'use client';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
Trophy,
Medal,
Crown,
Star,
TrendingUp,
Shield,
Search,
Plus,
Sparkles,
Users,
Target,
Zap,
Award,
ChevronRight,
Flame,
Flag,
Activity,
BarChart3,
UserPlus,
} from 'lucide-react';
import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input';
import Card from '@/components/ui/Card';
import Heading from '@/components/ui/Heading';
import { getDriverRepository, getDriverStats, getAllDriverRankings, getImageService } from '@/lib/di-container';
import Image from 'next/image';
// ============================================================================
// TYPES
// ============================================================================
type SkillLevel = 'beginner' | 'intermediate' | 'advanced' | 'pro';
interface DriverListItem {
id: string;
name: string;
rating: number;
skillLevel: SkillLevel;
nationality: string;
racesCompleted: number;
wins: number;
podiums: number;
isActive: boolean;
rank: number;
}
// ============================================================================
// DEMO DATA
// ============================================================================
//
// In alpha, all driver listings come from the in-memory repositories wired
// through the DI container. We intentionally avoid hardcoded fallback driver
// lists here so that the demo data stays consistent across pages.
// ============================================================================
// SKILL LEVEL CONFIG
// ============================================================================
const SKILL_LEVELS: {
id: SkillLevel;
label: string;
icon: React.ElementType;
color: string;
bgColor: string;
borderColor: string;
description: string;
}[] = [
{ 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' },
{ 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' },
];
// ============================================================================
// FEATURED DRIVER CARD COMPONENT
// ============================================================================
interface FeaturedDriverCardProps {
driver: DriverListItem;
position: number;
onClick: () => void;
}
function FeaturedDriverCard({ driver, position, onClick }: FeaturedDriverCardProps) {
const imageService = getImageService();
const levelConfig = SKILL_LEVELS.find((l) => l.id === driver.skillLevel);
const getBorderColor = (pos: number) => {
switch (pos) {
case 1: return 'border-yellow-400/50 hover:border-yellow-400';
case 2: return 'border-gray-300/50 hover:border-gray-300';
case 3: return 'border-amber-600/50 hover:border-amber-600';
default: return 'border-charcoal-outline hover:border-primary-blue';
}
};
const getMedalColor = (pos: number) => {
switch (pos) {
case 1: return 'text-yellow-400';
case 2: return 'text-gray-300';
case 3: return 'text-amber-600';
default: return 'text-gray-500';
}
};
return (
);
}
// ============================================================================
// SKILL DISTRIBUTION COMPONENT
// ============================================================================
interface SkillDistributionProps {
drivers: DriverListItem[];
}
function SkillDistribution({ drivers }: SkillDistributionProps) {
const distribution = SKILL_LEVELS.map((level) => ({
...level,
count: drivers.filter((d) => d.skillLevel === level.id).length,
percentage: drivers.length > 0
? Math.round((drivers.filter((d) => d.skillLevel === level.id).length / drivers.length) * 100)
: 0,
}));
return (
Skill Distribution
Driver population by skill level
{distribution.map((level) => {
const Icon = level.icon;
return (
{level.count}
{level.label}
{level.percentage}% of drivers
);
})}
);
}
// ============================================================================
// LEADERBOARD PREVIEW COMPONENT
// ============================================================================
interface LeaderboardPreviewProps {
drivers: DriverListItem[];
onDriverClick: (id: string) => void;
}
function LeaderboardPreview({ drivers, onDriverClick }: LeaderboardPreviewProps) {
const router = useRouter();
const imageService = getImageService();
const top5 = drivers.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 (
Top Drivers
Highest rated competitors
{top5.map((driver, index) => {
const levelConfig = SKILL_LEVELS.find((l) => l.id === driver.skillLevel);
const position = index + 1;
return (
);
})}
);
}
// ============================================================================
// RECENT ACTIVITY COMPONENT
// ============================================================================
interface RecentActivityProps {
drivers: DriverListItem[];
onDriverClick: (id: string) => void;
}
function RecentActivity({ drivers, onDriverClick }: RecentActivityProps) {
const imageService = getImageService();
const activeDrivers = drivers.filter((d) => d.isActive).slice(0, 6);
return (
Active Drivers
Currently competing in leagues
{activeDrivers.map((driver) => {
const levelConfig = SKILL_LEVELS.find((l) => l.id === driver.skillLevel);
return (
);
})}
);
}
// ============================================================================
// MAIN PAGE COMPONENT
// ============================================================================
export default function DriversPage() {
const router = useRouter();
const [drivers, setDrivers] = useState([]);
const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState('');
useEffect(() => {
const load = async () => {
const driverRepo = getDriverRepository();
const allDrivers = await driverRepo.findAll();
const rankings = getAllDriverRankings();
const items: DriverListItem[] = allDrivers.map((driver) => {
const stats = getDriverStats(driver.id);
const rating = stats?.rating ?? 0;
const wins = stats?.wins ?? 0;
const podiums = stats?.podiums ?? 0;
const totalRaces = stats?.totalRaces ?? 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';
const isActive = rankings.some((r) => r.driverId === driver.id);
return {
id: driver.id,
name: driver.name,
rating,
skillLevel,
nationality: driver.country,
racesCompleted: totalRaces,
wins,
podiums,
isActive,
rank: effectiveRank,
};
});
// Sort by rank
items.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;
});
setDrivers(items);
setLoading(false);
};
void load();
}, []);
const handleDriverClick = (driverId: string) => {
router.push(`/drivers/${driverId}`);
};
// Filter by search
const filteredDrivers = drivers.filter((driver) => {
if (!searchQuery) return true;
return (
driver.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
driver.nationality.toLowerCase().includes(searchQuery.toLowerCase())
);
});
// Stats
const totalRaces = drivers.reduce((sum, d) => sum + d.racesCompleted, 0);
const totalWins = drivers.reduce((sum, d) => sum + d.wins, 0);
const activeCount = drivers.filter((d) => d.isActive).length;
// Featured drivers (top 4)
const featuredDrivers = filteredDrivers.slice(0, 4);
if (loading) {
return (
);
}
return (
{/* Hero Section */}
{/* Background decoration */}
Meet the racers who make every lap count. From rookies to champions, track their journey and see who's dominating the grid.
{/* Quick Stats */}
{totalWins.toLocaleString()} total wins
{totalRaces.toLocaleString()} races
{/* CTA */}
See full driver rankings
{/* Search */}
{/* Featured Drivers */}
{!searchQuery && (
Featured Drivers
Top performers on the grid
{featuredDrivers.map((driver, index) => (
handleDriverClick(driver.id)}
/>
))}
)}
{/* Active Drivers */}
{!searchQuery &&
}
{/* Skill Distribution */}
{!searchQuery &&
}
{/* Leaderboard Preview */}
{/* Empty State */}
{filteredDrivers.length === 0 && (
No drivers found matching "{searchQuery}"
)}
);
}