website refactor
This commit is contained in:
161
apps/website/components/drivers/FeaturedDriverCard.tsx
Normal file
161
apps/website/components/drivers/FeaturedDriverCard.tsx
Normal file
@@ -0,0 +1,161 @@
|
||||
|
||||
|
||||
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 '@/ui/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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user