162 lines
5.5 KiB
TypeScript
162 lines
5.5 KiB
TypeScript
|
|
|
|
import { mediaConfig } from '@/lib/config/mediaConfig';
|
|
import { Badge } from '@/ui/Badge';
|
|
import { Box } from '@/ui/Box';
|
|
import { Heading } from '@/ui/Heading';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { Image } from '@/ui/Image';
|
|
import { MedalBadge } from '@/components/leaderboards/MedalBadge';
|
|
import { MiniStat } from '@/ui/MiniStat';
|
|
import { Text } from '@/ui/Text';
|
|
import { Flag, Shield, Star, TrendingUp } from 'lucide-react';
|
|
|
|
const SKILL_LEVELS = [
|
|
{ id: 'pro', label: 'Pro', icon: Star, color: 'text-yellow-400', bgColor: 'bg-yellow-400/10', borderColor: 'border-yellow-400/30', description: 'Elite competition level' },
|
|
{ id: 'advanced', label: 'Advanced', icon: Star, color: 'text-purple-400', bgColor: 'bg-purple-400/10', borderColor: 'border-purple-400/30', description: 'Highly competitive' },
|
|
{ id: 'intermediate', label: 'Intermediate', icon: TrendingUp, color: 'text-primary-blue', bgColor: 'bg-primary-blue/10', borderColor: 'border-primary-blue/30', description: 'Developing skills' },
|
|
{ id: 'beginner', label: 'Beginner', icon: Shield, color: 'text-green-400', bgColor: 'bg-green-400/10', borderColor: 'border-green-400/30', description: 'Learning the ropes' },
|
|
];
|
|
|
|
const CATEGORIES = [
|
|
{ id: 'beginner', label: 'Beginner', color: 'text-green-400', bgColor: 'bg-green-400/10', borderColor: 'border-green-400/30' },
|
|
{ id: 'intermediate', label: 'Intermediate', color: 'text-primary-blue', bgColor: 'bg-primary-blue/10', borderColor: 'border-primary-blue/30' },
|
|
{ id: 'advanced', label: 'Advanced', color: 'text-purple-400', bgColor: 'bg-purple-400/10', borderColor: 'border-purple-400/30' },
|
|
{ id: 'pro', label: 'Pro', color: 'text-yellow-400', bgColor: 'bg-yellow-400/10', borderColor: 'border-yellow-400/30' },
|
|
{ id: 'endurance', label: 'Endurance', color: 'text-orange-400', bgColor: 'bg-orange-400/10', borderColor: 'border-orange-400/30' },
|
|
{ id: 'sprint', label: 'Sprint', color: 'text-red-400', bgColor: 'bg-red-400/10', borderColor: 'border-red-400/30' },
|
|
];
|
|
|
|
interface FeaturedDriverCardProps {
|
|
driver: {
|
|
id: string;
|
|
name: string;
|
|
nationality: string;
|
|
avatarUrl?: string;
|
|
rating: number;
|
|
wins: number;
|
|
podiums: number;
|
|
skillLevel?: string;
|
|
category?: string;
|
|
};
|
|
position: number;
|
|
onClick: () => void;
|
|
}
|
|
|
|
export function FeaturedDriverCard({ driver, position, onClick }: FeaturedDriverCardProps) {
|
|
const levelConfig = SKILL_LEVELS.find((l) => l.id === driver.skillLevel);
|
|
const categoryConfig = CATEGORIES.find((c) => c.id === driver.category);
|
|
|
|
const getBorderColor = (pos: number) => {
|
|
switch (pos) {
|
|
case 1: return 'border-yellow-400/50';
|
|
case 2: return 'border-gray-300/50';
|
|
case 3: return 'border-amber-600/50';
|
|
default: return 'border-charcoal-outline';
|
|
}
|
|
};
|
|
|
|
const getHoverBorderColor = (pos: number) => {
|
|
switch (pos) {
|
|
case 1: return 'yellow-400';
|
|
case 2: return 'gray-300';
|
|
case 3: return 'amber-600';
|
|
default: return 'primary-blue';
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box
|
|
as="button"
|
|
type="button"
|
|
onClick={onClick}
|
|
p={5}
|
|
rounded="xl"
|
|
bg="bg-iron-gray/60"
|
|
border
|
|
borderColor={getBorderColor(position)}
|
|
hoverBorderColor={getHoverBorderColor(position)}
|
|
transition
|
|
textAlign="left"
|
|
cursor="pointer"
|
|
hoverScale
|
|
group
|
|
>
|
|
{/* Header with Position */}
|
|
<Box display="flex" alignItems="start" justifyContent="between" mb={4}>
|
|
<MedalBadge position={position} />
|
|
<Box display="flex" gap={2}>
|
|
{categoryConfig && (
|
|
<Badge
|
|
bg={categoryConfig.bgColor}
|
|
color={categoryConfig.color}
|
|
borderColor={categoryConfig.borderColor}
|
|
>
|
|
{categoryConfig.label}
|
|
</Badge>
|
|
)}
|
|
{levelConfig && (
|
|
<Badge
|
|
bg={levelConfig.bgColor}
|
|
color={levelConfig.color}
|
|
borderColor={levelConfig.borderColor}
|
|
>
|
|
{levelConfig.label}
|
|
</Badge>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
|
|
{/* Avatar & Name */}
|
|
<Box display="flex" alignItems="center" gap={4} mb={4}>
|
|
<Box
|
|
position="relative"
|
|
w="16"
|
|
h="16"
|
|
rounded="full"
|
|
overflow="hidden"
|
|
border
|
|
borderColor="border-charcoal-outline"
|
|
groupHoverBorderColor="primary-blue"
|
|
transition
|
|
>
|
|
<Image
|
|
src={driver.avatarUrl || mediaConfig.avatars.defaultFallback}
|
|
alt={driver.name}
|
|
objectFit="cover"
|
|
fill
|
|
/>
|
|
</Box>
|
|
<Box>
|
|
<Heading level={3} groupHoverColor="primary-blue" transition>
|
|
{driver.name}
|
|
</Heading>
|
|
<Box display="flex" alignItems="center" gap={2}>
|
|
<Icon icon={Flag} size={3.5} color="rgb(107, 114, 128)" />
|
|
<Text size="sm" color="text-gray-500">{driver.nationality}</Text>
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
|
|
{/* Stats */}
|
|
<Box display="grid" gridCols={3} gap={3}>
|
|
<MiniStat
|
|
label="Rating"
|
|
value={driver.rating.toLocaleString()}
|
|
color="text-primary-blue"
|
|
/>
|
|
<MiniStat
|
|
label="Wins"
|
|
value={driver.wins}
|
|
color="text-performance-green"
|
|
/>
|
|
<MiniStat
|
|
label="Podiums"
|
|
value={driver.podiums}
|
|
color="text-warning-amber"
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
}
|