'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { Trophy, Users, Crown, Star, TrendingUp, Shield, Medal, ChevronRight, Award, Flag, Target, Zap, Hash, Percent, } from 'lucide-react'; import Button from '@/components/ui/Button'; import Heading from '@/components/ui/Heading'; import { getDriverRepository, getDriverStats, getAllDriverRankings, getImageService, getGetAllTeamsQuery, getGetTeamMembersQuery } from '@/lib/di-container'; import Image from 'next/image'; import type { Team } from '@gridpilot/racing'; // ============================================================================ // TYPES // ============================================================================ type SkillLevel = 'beginner' | 'intermediate' | 'advanced' | 'pro'; interface DriverListItem { id: string; name: string; rating: number; skillLevel: SkillLevel; nationality: string; wins: number; podiums: number; rank: number; } interface TeamDisplayData { id: string; name: string; memberCount: number; rating: number | null; totalWins: number; totalRaces: number; performanceLevel: SkillLevel; } // ============================================================================ // DEMO DATA // ============================================================================ const DEMO_DRIVERS: DriverListItem[] = [ { id: 'demo-1', name: 'Max Verstappen', rating: 4250, skillLevel: 'pro', nationality: 'NL', wins: 47, podiums: 89, rank: 1 }, { id: 'demo-2', name: 'Lewis Hamilton', rating: 4180, skillLevel: 'pro', nationality: 'GB', wins: 52, podiums: 112, rank: 2 }, { id: 'demo-3', name: 'Charles Leclerc', rating: 3950, skillLevel: 'pro', nationality: 'MC', wins: 28, podiums: 67, rank: 3 }, { id: 'demo-4', name: 'Lando Norris', rating: 3820, skillLevel: 'advanced', nationality: 'GB', wins: 18, podiums: 45, rank: 4 }, { id: 'demo-5', name: 'Carlos Sainz', rating: 3750, skillLevel: 'advanced', nationality: 'ES', wins: 15, podiums: 52, rank: 5 }, { id: 'demo-6', name: 'Oscar Piastri', rating: 3680, skillLevel: 'advanced', nationality: 'AU', wins: 8, podiums: 24, rank: 6 }, { id: 'demo-7', name: 'George Russell', rating: 3620, skillLevel: 'advanced', nationality: 'GB', wins: 6, podiums: 31, rank: 7 }, { id: 'demo-8', name: 'Fernando Alonso', rating: 3580, skillLevel: 'advanced', nationality: 'ES', wins: 32, podiums: 98, rank: 8 }, { id: 'demo-9', name: 'Nico Hülkenberg', rating: 3420, skillLevel: 'advanced', nationality: 'DE', wins: 2, podiums: 18, rank: 9 }, { id: 'demo-10', name: 'Yuki Tsunoda', rating: 3250, skillLevel: 'intermediate', nationality: 'JP', wins: 1, podiums: 8, rank: 10 }, ]; const DEMO_TEAMS: TeamDisplayData[] = [ { id: 'demo-team-1', name: 'Apex Predators Racing', memberCount: 8, rating: 4850, totalWins: 47, totalRaces: 156, performanceLevel: 'pro' }, { id: 'demo-team-2', name: 'Velocity Esports', memberCount: 12, rating: 5200, totalWins: 63, totalRaces: 198, performanceLevel: 'pro' }, { id: 'demo-team-3', name: 'Nitro Motorsport', memberCount: 6, rating: 4720, totalWins: 38, totalRaces: 112, performanceLevel: 'pro' }, { id: 'demo-team-4', name: 'Horizon Racing Collective', memberCount: 10, rating: 3800, totalWins: 24, totalRaces: 89, performanceLevel: 'advanced' }, { id: 'demo-team-5', name: 'Phoenix Rising eSports', memberCount: 7, rating: 3650, totalWins: 19, totalRaces: 76, performanceLevel: 'advanced' }, ]; // ============================================================================ // SKILL LEVEL CONFIG // ============================================================================ const SKILL_LEVELS: { id: SkillLevel; label: string; icon: React.ElementType; color: string; bgColor: string; borderColor: string; }[] = [ { id: 'pro', label: 'Pro', icon: Crown, color: 'text-yellow-400', bgColor: 'bg-yellow-400/10', borderColor: 'border-yellow-400/30' }, { id: 'advanced', label: 'Advanced', icon: Star, color: 'text-purple-400', bgColor: 'bg-purple-400/10', borderColor: 'border-purple-400/30' }, { id: 'intermediate', label: 'Intermediate', icon: TrendingUp, color: 'text-primary-blue', bgColor: 'bg-primary-blue/10', borderColor: 'border-primary-blue/30' }, { id: 'beginner', label: 'Beginner', icon: Shield, color: 'text-green-400', bgColor: 'bg-green-400/10', borderColor: 'border-green-400/30' }, ]; // ============================================================================ // DRIVER LEADERBOARD PREVIEW // ============================================================================ interface DriverLeaderboardPreviewProps { drivers: DriverListItem[]; onDriverClick: (id: string) => void; } function DriverLeaderboardPreview({ drivers, onDriverClick }: DriverLeaderboardPreviewProps) { const router = useRouter(); const imageService = getImageService(); const top10 = drivers.slice(0, 10); const getMedalColor = (position: number) => { switch (position) { case 1: return 'text-yellow-400'; case 2: return 'text-gray-300'; case 3: return 'text-amber-600'; default: return 'text-gray-500'; } }; const getMedalBg = (position: number) => { switch (position) { case 1: return 'bg-yellow-400/10 border-yellow-400/30'; case 2: return 'bg-gray-300/10 border-gray-300/30'; case 3: return 'bg-amber-600/10 border-amber-600/30'; default: return 'bg-iron-gray/50 border-charcoal-outline'; } }; return (
{/* Header */}

Driver Rankings

Top performers across all leagues

{/* Leaderboard Rows */}
{top10.map((driver, index) => { const levelConfig = SKILL_LEVELS.find((l) => l.id === driver.skillLevel); const position = index + 1; return ( ); })}
); } // ============================================================================ // TEAM LEADERBOARD PREVIEW // ============================================================================ interface TeamLeaderboardPreviewProps { teams: TeamDisplayData[]; onTeamClick: (id: string) => void; } function TeamLeaderboardPreview({ teams, onTeamClick }: TeamLeaderboardPreviewProps) { const router = useRouter(); const imageService = getImageService(); const top5 = [...teams] .filter((t) => t.rating !== null) .sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0)) .slice(0, 5); const getMedalColor = (position: number) => { switch (position) { case 1: return 'text-yellow-400'; case 2: return 'text-gray-300'; case 3: return 'text-amber-600'; default: return 'text-gray-500'; } }; const getMedalBg = (position: number) => { switch (position) { case 1: return 'bg-yellow-400/10 border-yellow-400/30'; case 2: return 'bg-gray-300/10 border-gray-300/30'; case 3: return 'bg-amber-600/10 border-amber-600/30'; default: return 'bg-iron-gray/50 border-charcoal-outline'; } }; return (
{/* Header */}

Team Rankings

Top performing racing teams

{/* Leaderboard Rows */}
{top5.map((team, index) => { const levelConfig = SKILL_LEVELS.find((l) => l.id === team.performanceLevel); const LevelIcon = levelConfig?.icon || Shield; const position = index + 1; return ( ); })}
); } // ============================================================================ // MAIN PAGE COMPONENT // ============================================================================ export default function LeaderboardsPage() { const router = useRouter(); const [drivers, setDrivers] = useState([]); const [teams, setTeams] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const load = async () => { try { // Load drivers const driverRepo = getDriverRepository(); const allDrivers = await driverRepo.findAll(); const rankings = getAllDriverRankings(); const driverItems: DriverListItem[] = allDrivers.map((driver) => { const stats = getDriverStats(driver.id); const rating = stats?.rating ?? 0; const wins = stats?.wins ?? 0; const podiums = stats?.podiums ?? 0; let effectiveRank = Number.POSITIVE_INFINITY; if (typeof stats?.overallRank === 'number' && stats.overallRank > 0) { effectiveRank = stats.overallRank; } else { const indexInGlobal = rankings.findIndex((entry) => entry.driverId === driver.id); if (indexInGlobal !== -1) { effectiveRank = indexInGlobal + 1; } } const skillLevel: SkillLevel = rating >= 3000 ? 'pro' : rating >= 2500 ? 'advanced' : rating >= 1800 ? 'intermediate' : 'beginner'; return { id: driver.id, name: driver.name, rating, skillLevel, nationality: driver.country, wins, podiums, rank: effectiveRank, }; }); // Sort by rank driverItems.sort((a, b) => { const rankA = Number.isFinite(a.rank) && a.rank > 0 ? a.rank : Number.POSITIVE_INFINITY; const rankB = Number.isFinite(b.rank) && b.rank > 0 ? b.rank : Number.POSITIVE_INFINITY; return rankA - rankB || b.rating - a.rating; }); // Load teams const allTeamsQuery = getGetAllTeamsQuery(); const teamMembersQuery = getGetTeamMembersQuery(); const allTeams = await allTeamsQuery.execute(); const teamData: TeamDisplayData[] = []; await Promise.all( allTeams.map(async (team: Team) => { const memberships = await teamMembersQuery.execute({ teamId: team.id }); const memberCount = memberships.length; let ratingSum = 0; let ratingCount = 0; let totalWins = 0; let totalRaces = 0; for (const membership of memberships) { const stats = getDriverStats(membership.driverId); if (!stats) continue; if (typeof stats.rating === 'number') { ratingSum += stats.rating; ratingCount += 1; } totalWins += stats.wins ?? 0; totalRaces += stats.totalRaces ?? 0; } const averageRating = ratingCount > 0 ? ratingSum / ratingCount : null; let performanceLevel: SkillLevel = 'beginner'; if (averageRating !== null) { if (averageRating >= 4500) performanceLevel = 'pro'; else if (averageRating >= 3000) performanceLevel = 'advanced'; else if (averageRating >= 2000) performanceLevel = 'intermediate'; } teamData.push({ id: team.id, name: team.name, memberCount, rating: averageRating, totalWins, totalRaces, performanceLevel, }); }), ); setDrivers(driverItems.length > 0 ? driverItems : DEMO_DRIVERS); setTeams(teamData.length > 0 ? teamData : DEMO_TEAMS); } catch (error) { console.error('Failed to load leaderboard data:', error); setDrivers(DEMO_DRIVERS); setTeams(DEMO_TEAMS); } finally { setLoading(false); } }; void load(); }, []); const handleDriverClick = (driverId: string) => { if (driverId.startsWith('demo-')) return; router.push(`/drivers/${driverId}`); }; const handleTeamClick = (teamId: string) => { if (teamId.startsWith('demo-team-')) return; router.push(`/teams/${teamId}`); }; if (loading) { return (

Loading leaderboards...

); } return (
{/* Hero Section */}
{/* Background decoration */}
Leaderboards

Where champions rise and legends are made

Track the best drivers and teams across all competitions. Every race counts. Every position matters. Who will claim the throne?

{/* Quick Nav */}
{/* Leaderboard Grids */}
); }