'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 { getGetDriversLeaderboardUseCase, getGetTeamsLeaderboardUseCase } from '@/lib/di-container'; import { TeamsLeaderboardPresenter } from '@/lib/presenters/TeamsLeaderboardPresenter'; import type { DriverLeaderboardItemViewModel, SkillLevel } from '@gridpilot/racing/application/presenters/IDriversLeaderboardPresenter'; import type { TeamLeaderboardItemViewModel } from '@gridpilot/racing/application/presenters/ITeamsLeaderboardPresenter'; import Image from 'next/image'; // ============================================================================ // TYPES // ============================================================================ type DriverListItem = DriverLeaderboardItemViewModel; type TeamDisplayData = TeamLeaderboardItemViewModel; // ============================================================================ // 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 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 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 { const driversUseCase = getGetDriversLeaderboardUseCase(); const teamsUseCase = getGetTeamsLeaderboardUseCase(); const teamsPresenter = new TeamsLeaderboardPresenter(); await driversUseCase.execute(); await teamsUseCase.execute(undefined as void, teamsPresenter); const driversViewModel = driversUseCase.presenter.getViewModel(); const teamsViewModel = teamsPresenter.getViewModel(); setDrivers(driversViewModel.drivers); setTeams(teamsViewModel ? teamsViewModel.teams : []); } catch (error) { console.error('Failed to load leaderboard data:', error); setDrivers([]); setTeams([]); } finally { setLoading(false); } }; void load(); }, []); const handleDriverClick = (driverId: string) => { router.push(`/drivers/${driverId}`); }; const handleTeamClick = (teamId: string) => { 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 */}
); }