website refactor
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { BarChart3 } from 'lucide-react';
|
||||
import type { DriverLeaderboardItemViewModel } from '@/lib/view-models/DriverLeaderboardItemViewModel';
|
||||
|
||||
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' },
|
||||
@@ -13,7 +11,9 @@ const CATEGORIES = [
|
||||
];
|
||||
|
||||
interface CategoryDistributionProps {
|
||||
drivers: DriverLeaderboardItemViewModel[];
|
||||
drivers: {
|
||||
category?: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function CategoryDistribution({ drivers }: CategoryDistributionProps) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Card from '@/components/ui/Card';
|
||||
import Card from '@/ui/Card';
|
||||
import RankBadge from '@/components/drivers/RankBadge';
|
||||
import { DriverIdentity } from '@/components/drivers/DriverIdentity';
|
||||
import { DriverViewModel } from '@/lib/view-models/DriverViewModel';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import PlaceholderImage from '@/components/ui/PlaceholderImage';
|
||||
import PlaceholderImage from '@/ui/PlaceholderImage';
|
||||
|
||||
export interface DriverIdentityProps {
|
||||
driver: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Card from '@/components/ui/Card';
|
||||
import Card from '@/ui/Card';
|
||||
|
||||
export interface DriverRanking {
|
||||
type: 'overall' | 'league';
|
||||
|
||||
87
apps/website/components/drivers/DriversHero.tsx
Normal file
87
apps/website/components/drivers/DriversHero.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Users, Trophy, LucideIcon } from 'lucide-react';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Heading } from '@/ui/Heading';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Button } from '@/ui/Button';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
import { DecorativeBlur } from '@/ui/DecorativeBlur';
|
||||
|
||||
interface StatItemProps {
|
||||
label: string;
|
||||
value: string | number;
|
||||
color: string;
|
||||
animate?: boolean;
|
||||
}
|
||||
|
||||
function StatItem({ label, value, color, animate }: StatItemProps) {
|
||||
return (
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Box style={{ width: '0.5rem', height: '0.5rem', borderRadius: '9999px', backgroundColor: color }} className={animate ? 'animate-pulse' : ''} />
|
||||
<Text size="sm" color="text-gray-400">
|
||||
<Text weight="semibold" color="text-white">{value}</Text> {label}
|
||||
</Text>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
interface DriversHeroProps {
|
||||
driverCount: number;
|
||||
activeCount: number;
|
||||
totalWins: number;
|
||||
totalRaces: number;
|
||||
onViewLeaderboard: () => void;
|
||||
}
|
||||
|
||||
export function DriversHero({
|
||||
driverCount,
|
||||
activeCount,
|
||||
totalWins,
|
||||
totalRaces,
|
||||
onViewLeaderboard,
|
||||
}: DriversHeroProps) {
|
||||
return (
|
||||
<Surface variant="muted" rounded="2xl" border padding={8} style={{ position: 'relative', overflow: 'hidden', background: 'linear-gradient(to bottom right, rgba(59, 130, 246, 0.2), rgba(38, 38, 38, 0.8), #0f1115)', borderColor: 'rgba(59, 130, 246, 0.3)' }}>
|
||||
<DecorativeBlur color="blue" size="lg" position="top-right" opacity={10} />
|
||||
<DecorativeBlur color="yellow" size="md" position="bottom-left" opacity={5} />
|
||||
|
||||
<Stack direction="row" align="center" justify="between" wrap gap={8} style={{ position: 'relative', zIndex: 10 }}>
|
||||
<Box style={{ maxWidth: '42rem' }}>
|
||||
<Stack direction="row" align="center" gap={3} mb={4}>
|
||||
<Surface variant="muted" rounded="xl" padding={3} style={{ background: 'linear-gradient(to bottom right, rgba(59, 130, 246, 0.2), rgba(59, 130, 246, 0.05))', border: '1px solid rgba(59, 130, 246, 0.2)' }}>
|
||||
<Icon icon={Users} size={6} color="#3b82f6" />
|
||||
</Surface>
|
||||
<Heading level={1}>Drivers</Heading>
|
||||
</Stack>
|
||||
<Text size="lg" color="text-gray-400" block mb={6} style={{ lineHeight: 1.625 }}>
|
||||
Meet the racers who make every lap count. From rookies to champions, track their journey and see who's dominating the grid.
|
||||
</Text>
|
||||
|
||||
{/* Quick Stats */}
|
||||
<Stack direction="row" gap={6} wrap>
|
||||
<StatItem label="drivers" value={driverCount} color="#3b82f6" />
|
||||
<StatItem label="active" value={activeCount} color="#10b981" animate />
|
||||
<StatItem label="total wins" value={totalWins.toLocaleString()} color="#f59e0b" />
|
||||
<StatItem label="races" value={totalRaces.toLocaleString()} color="#00f2ff" />
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
{/* CTA */}
|
||||
<Stack align="center" gap={4}>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={onViewLeaderboard}
|
||||
icon={<Icon icon={Trophy} size={5} />}
|
||||
>
|
||||
View Leaderboard
|
||||
</Button>
|
||||
<Text size="xs" color="text-gray-500">See full driver rankings</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
30
apps/website/components/drivers/DriversSearch.tsx
Normal file
30
apps/website/components/drivers/DriversSearch.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Search } from 'lucide-react';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Input } from '@/ui/Input';
|
||||
|
||||
interface DriversSearchProps {
|
||||
query: string;
|
||||
onChange: (query: string) => void;
|
||||
}
|
||||
|
||||
export function DriversSearch({ query, onChange }: DriversSearchProps) {
|
||||
return (
|
||||
<Box mb={8}>
|
||||
<Box style={{ position: 'relative', maxWidth: '28rem' }}>
|
||||
<Box style={{ position: 'absolute', left: '0.75rem', top: '50%', transform: 'translateY(-50%)', zIndex: 10 }}>
|
||||
<Search style={{ width: '1.25rem', height: '1.25rem', color: '#6b7280' }} />
|
||||
</Box>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Search drivers by name or nationality..."
|
||||
value={query}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
style={{ paddingLeft: '2.75rem' }}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
import { Trophy, Crown, Star, TrendingUp, Shield, Flag } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import { mediaConfig } from '@/lib/config/mediaConfig';
|
||||
import type { DriverLeaderboardItemViewModel } from '@/lib/view-models/DriverLeaderboardItemViewModel';
|
||||
|
||||
const SKILL_LEVELS = [
|
||||
{ id: 'pro', label: 'Pro', icon: Crown, 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' },
|
||||
@@ -22,7 +20,17 @@ const CATEGORIES = [
|
||||
];
|
||||
|
||||
interface FeaturedDriverCardProps {
|
||||
driver: DriverLeaderboardItemViewModel;
|
||||
driver: {
|
||||
id: string;
|
||||
name: string;
|
||||
nationality: string;
|
||||
avatarUrl?: string;
|
||||
rating: number;
|
||||
wins: number;
|
||||
podiums: number;
|
||||
skillLevel?: string;
|
||||
category?: string;
|
||||
};
|
||||
position: number;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Heading from '@/components/ui/Heading';
|
||||
import Heading from '@/ui/Heading';
|
||||
import { Trophy, Users } from 'lucide-react';
|
||||
import Button from '../ui/Button';
|
||||
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Award, Crown, Flag, ChevronRight } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import Button from '@/components/ui/Button';
|
||||
import Button from '@/ui/Button';
|
||||
import { mediaConfig } from '@/lib/config/mediaConfig';
|
||||
import type { DriverLeaderboardItemViewModel } from '@/lib/view-models/DriverLeaderboardItemViewModel';
|
||||
|
||||
const SKILL_LEVELS = [
|
||||
{ id: 'pro', label: 'Pro', color: 'text-yellow-400' },
|
||||
{ id: 'advanced', label: 'Advanced', color: 'text-purple-400' },
|
||||
@@ -24,7 +22,16 @@ const CATEGORIES = [
|
||||
];
|
||||
|
||||
interface LeaderboardPreviewProps {
|
||||
drivers: DriverLeaderboardItemViewModel[];
|
||||
drivers: {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl?: string;
|
||||
nationality: string;
|
||||
rating: number;
|
||||
wins: number;
|
||||
skillLevel?: string;
|
||||
category?: string;
|
||||
}[];
|
||||
onDriverClick: (id: string) => void;
|
||||
}
|
||||
|
||||
|
||||
94
apps/website/components/drivers/RankingsPodium.tsx
Normal file
94
apps/website/components/drivers/RankingsPodium.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Crown } from 'lucide-react';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Image } from '@/ui/Image';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
|
||||
interface PodiumDriver {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
rating: number;
|
||||
wins: number;
|
||||
podiums: number;
|
||||
}
|
||||
|
||||
interface RankingsPodiumProps {
|
||||
podium: PodiumDriver[];
|
||||
onDriverClick?: (id: string) => void;
|
||||
}
|
||||
|
||||
export function RankingsPodium({ podium, onDriverClick }: RankingsPodiumProps) {
|
||||
return (
|
||||
<Box mb={10}>
|
||||
<Box style={{ display: 'flex', alignItems: 'end', justifyContent: 'center', gap: '1rem' }}>
|
||||
{[1, 0, 2].map((index) => {
|
||||
const driver = podium[index];
|
||||
if (!driver) return null;
|
||||
|
||||
const position = index === 1 ? 1 : index === 0 ? 2 : 3;
|
||||
const config = {
|
||||
1: { height: '10rem', color: 'rgba(250, 204, 21, 0.2)', borderColor: 'rgba(250, 204, 21, 0.4)', crown: '#facc15' },
|
||||
2: { height: '8rem', color: 'rgba(209, 213, 219, 0.2)', borderColor: 'rgba(209, 213, 219, 0.4)', crown: '#d1d5db' },
|
||||
3: { height: '6rem', color: 'rgba(217, 119, 6, 0.2)', borderColor: 'rgba(217, 119, 6, 0.4)', crown: '#d97706' },
|
||||
}[position] || { height: '6rem', color: 'rgba(217, 119, 6, 0.2)', borderColor: 'rgba(217, 119, 6, 0.4)', crown: '#d97706' };
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={driver.id}
|
||||
as="button"
|
||||
type="button"
|
||||
onClick={() => onDriverClick?.(driver.id)}
|
||||
style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', backgroundColor: 'transparent', border: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
<Box style={{ position: 'relative', marginBottom: '1rem' }}>
|
||||
<Box style={{ position: 'relative', width: position === 1 ? '6rem' : '5rem', height: position === 1 ? '6rem' : '5rem', borderRadius: '9999px', overflow: 'hidden', border: `4px solid ${config.crown}`, boxShadow: position === 1 ? '0 0 30px rgba(250, 204, 21, 0.3)' : 'none' }}>
|
||||
<Image
|
||||
src={driver.avatarUrl}
|
||||
alt={driver.name}
|
||||
width={112}
|
||||
height={112}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
</Box>
|
||||
<Box style={{ position: 'absolute', bottom: '-0.5rem', left: '50%', transform: 'translateX(-50%)', width: '2rem', height: '2rem', borderRadius: '9999px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '0.875rem', fontWeight: 'bold', background: `linear-gradient(to bottom right, ${config.color}, transparent)`, border: `2px solid ${config.crown}`, color: config.crown }}>
|
||||
{position}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Text weight="semibold" color="text-white" style={{ fontSize: position === 1 ? '1.125rem' : '1rem', marginBottom: '0.25rem' }}>
|
||||
{driver.name}
|
||||
</Text>
|
||||
|
||||
<Text font="mono" weight="bold" style={{ fontSize: position === 1 ? '1.25rem' : '1.125rem', color: position === 1 ? '#facc15' : '#3b82f6' }}>
|
||||
{driver.rating.toString()}
|
||||
</Text>
|
||||
|
||||
<Stack direction="row" align="center" gap={2} style={{ fontSize: '0.75rem', color: '#6b7280', marginTop: '0.25rem' }}>
|
||||
<Stack direction="row" align="center" gap={1}>
|
||||
<Text color="text-performance-green">🏆</Text>
|
||||
{driver.wins}
|
||||
</Stack>
|
||||
<Text>•</Text>
|
||||
<Stack direction="row" align="center" gap={1}>
|
||||
<Text color="text-warning-amber">🏅</Text>
|
||||
{driver.podiums}
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Box style={{ marginTop: '1rem', width: position === 1 ? '7rem' : '6rem', height: config.height, borderRadius: '0.5rem 0.5rem 0 0', background: `linear-gradient(to top, ${config.color}, transparent)`, borderTop: `1px solid ${config.borderColor}`, borderLeft: `1px solid ${config.borderColor}`, borderRight: `1px solid ${config.borderColor}`, display: 'flex', alignItems: 'end', justifyContent: 'center', paddingBottom: '1rem' }}>
|
||||
<Text weight="bold" style={{ fontSize: position === 1 ? '3rem' : '2.25rem', color: config.crown }}>
|
||||
{position}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
122
apps/website/components/drivers/RankingsTable.tsx
Normal file
122
apps/website/components/drivers/RankingsTable.tsx
Normal file
@@ -0,0 +1,122 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Medal } from 'lucide-react';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Image } from '@/ui/Image';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
|
||||
interface Driver {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
rank: number;
|
||||
nationality: string;
|
||||
skillLevel: string;
|
||||
racesCompleted: number;
|
||||
rating: number;
|
||||
wins: number;
|
||||
medalBg?: string;
|
||||
medalColor?: string;
|
||||
}
|
||||
|
||||
interface RankingsTableProps {
|
||||
drivers: Driver[];
|
||||
onDriverClick?: (id: string) => void;
|
||||
}
|
||||
|
||||
export function RankingsTable({ drivers, onDriverClick }: RankingsTableProps) {
|
||||
return (
|
||||
<Box style={{ borderRadius: '0.75rem', backgroundColor: 'rgba(38, 38, 38, 0.3)', border: '1px solid #262626', overflow: 'hidden' }}>
|
||||
{/* Table Header */}
|
||||
<Box style={{ display: 'grid', gridTemplateColumns: 'repeat(12, minmax(0, 1fr))', gap: '1rem', padding: '0.75rem 1rem', backgroundColor: 'rgba(38, 38, 38, 0.5)', borderBottom: '1px solid #262626', fontSize: '0.75rem', fontWeight: 500, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
|
||||
<Box style={{ gridColumn: 'span 1', textAlign: 'center' }}>Rank</Box>
|
||||
<Box style={{ gridColumn: 'span 5' }}>Driver</Box>
|
||||
<Box style={{ gridColumn: 'span 2', textAlign: 'center' }}>Races</Box>
|
||||
<Box style={{ gridColumn: 'span 2', textAlign: 'center' }}>Rating</Box>
|
||||
<Box style={{ gridColumn: 'span 2', textAlign: 'center' }}>Wins</Box>
|
||||
</Box>
|
||||
|
||||
{/* Table Body */}
|
||||
<Stack gap={0}>
|
||||
{drivers.map((driver, index) => {
|
||||
const position = driver.rank;
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={driver.id}
|
||||
as="button"
|
||||
type="button"
|
||||
onClick={() => onDriverClick?.(driver.id)}
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(12, minmax(0, 1fr))',
|
||||
gap: '1rem',
|
||||
padding: '1rem',
|
||||
width: '100%',
|
||||
textAlign: 'left',
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
borderBottom: index < drivers.length - 1 ? '1px solid rgba(38, 38, 38, 0.5)' : 'none'
|
||||
}}
|
||||
>
|
||||
{/* Position */}
|
||||
<Box style={{ gridColumn: 'span 1', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Box style={{ display: 'flex', height: '2.25rem', width: '2.25rem', alignItems: 'center', justifyContent: 'center', borderRadius: '9999px', fontSize: '0.875rem', fontWeight: 'bold', border: '1px solid #262626', backgroundColor: driver.medalBg, color: driver.medalColor }}>
|
||||
{position <= 3 ? <Icon icon={Medal} size={4} /> : position}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Driver Info */}
|
||||
<Box style={{ gridColumn: 'span 5', display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
|
||||
<Box style={{ position: 'relative', width: '2.5rem', height: '2.5rem', borderRadius: '9999px', overflow: 'hidden', border: '2px solid #262626' }}>
|
||||
<Image src={driver.avatarUrl} alt={driver.name} width={40} height={40} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
|
||||
</Box>
|
||||
<Box style={{ minWidth: 0 }}>
|
||||
<Text weight="semibold" color="text-white" block truncate>
|
||||
{driver.name}
|
||||
</Text>
|
||||
<Stack direction="row" align="center" gap={2} mt={1}>
|
||||
<Text size="xs" color="text-gray-500">{driver.nationality}</Text>
|
||||
<Text size="xs" color="text-gray-500">{driver.skillLevel}</Text>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* Races */}
|
||||
<Box style={{ gridColumn: 'span 2', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Text color="text-gray-400">{driver.racesCompleted}</Text>
|
||||
</Box>
|
||||
|
||||
{/* Rating */}
|
||||
<Box style={{ gridColumn: 'span 2', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Text font="mono" weight="semibold" color="text-white">
|
||||
{driver.rating.toString()}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
{/* Wins */}
|
||||
<Box style={{ gridColumn: 'span 2', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Text font="mono" weight="semibold" color="text-performance-green">
|
||||
{driver.wins}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
|
||||
{/* Empty State */}
|
||||
{drivers.length === 0 && (
|
||||
<Box style={{ padding: '4rem 0', textAlign: 'center' }}>
|
||||
<Text size="4xl" block mb={4}>🔍</Text>
|
||||
<Text color="text-gray-400" block mb={2}>No drivers found</Text>
|
||||
<Text size="sm" color="text-gray-500">There are no drivers in the system yet</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
import { Activity } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import { mediaConfig } from '@/lib/config/mediaConfig';
|
||||
import type { DriverLeaderboardItemViewModel } from '@/lib/view-models/DriverLeaderboardItemViewModel';
|
||||
|
||||
const SKILL_LEVELS = [
|
||||
{ id: 'pro', label: 'Pro', color: 'text-yellow-400' },
|
||||
{ id: 'advanced', label: 'Advanced', color: 'text-purple-400' },
|
||||
@@ -22,7 +20,14 @@ const CATEGORIES = [
|
||||
];
|
||||
|
||||
interface RecentActivityProps {
|
||||
drivers: DriverLeaderboardItemViewModel[];
|
||||
drivers: {
|
||||
id: string;
|
||||
name: string;
|
||||
avatarUrl?: string;
|
||||
isActive: boolean;
|
||||
skillLevel?: string;
|
||||
category?: string;
|
||||
}[];
|
||||
onDriverClick: (id: string) => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { BarChart3 } from 'lucide-react';
|
||||
import type { DriverLeaderboardItemViewModel } from '@/lib/view-models/DriverLeaderboardItemViewModel';
|
||||
|
||||
const SKILL_LEVELS = [
|
||||
{ id: 'pro', label: 'Pro', icon: BarChart3, color: 'text-yellow-400', bgColor: 'bg-yellow-400/10', borderColor: 'border-yellow-400/30' },
|
||||
{ id: 'advanced', label: 'Advanced', icon: BarChart3, color: 'text-purple-400', bgColor: 'bg-purple-400/10', borderColor: 'border-purple-400/30' },
|
||||
@@ -11,7 +9,9 @@ const SKILL_LEVELS = [
|
||||
];
|
||||
|
||||
interface SkillDistributionProps {
|
||||
drivers: DriverLeaderboardItemViewModel[];
|
||||
drivers: {
|
||||
skillLevel?: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function SkillDistribution({ drivers }: SkillDistributionProps) {
|
||||
|
||||
Reference in New Issue
Block a user