website refactor

This commit is contained in:
2026-01-15 19:55:46 +01:00
parent 5ef149b782
commit ce7be39155
154 changed files with 436 additions and 356 deletions

View 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>
);
}