111 lines
3.4 KiB
TypeScript
111 lines
3.4 KiB
TypeScript
import { DriverLeaderboardPreview } from '@/components/leaderboards/DriverLeaderboardPreview';
|
|
import { TeamLeaderboardPreview } from '@/components/leaderboards/TeamLeaderboardPreview';
|
|
import type { LeaderboardsViewData } from '@/lib/view-data/LeaderboardsViewData';
|
|
import { Section } from '@/ui/Section';
|
|
import { PageHeader } from '@/ui/PageHeader';
|
|
import { FeatureGrid } from '@/ui/FeatureGrid';
|
|
import { Container } from '@/ui/Container';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Group } from '@/ui/Group';
|
|
import { Button } from '@/ui/Button';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { Trophy, Users, Activity } from 'lucide-react';
|
|
import React from 'react';
|
|
|
|
interface LeaderboardsTemplateProps {
|
|
viewData: LeaderboardsViewData;
|
|
onDriverClick: (id: string) => void;
|
|
onTeamClick: (id: string) => void;
|
|
onNavigateToDrivers: () => void;
|
|
onNavigateToTeams: () => void;
|
|
}
|
|
|
|
export function LeaderboardsTemplate({
|
|
viewData,
|
|
onDriverClick,
|
|
onTeamClick,
|
|
onNavigateToDrivers,
|
|
onNavigateToTeams
|
|
}: LeaderboardsTemplateProps) {
|
|
const top10Drivers = viewData.drivers.slice(0, 10);
|
|
const top5Teams = viewData.teams.slice(0, 5);
|
|
|
|
// Newcomers: less than 10 races, sorted by rating
|
|
const topNewcomers = [...viewData.drivers]
|
|
.filter(d => d.racesCompleted < 10)
|
|
.sort((a, b) => b.rating - a.rating)
|
|
.slice(0, 5);
|
|
|
|
// All time: sorted by wins
|
|
const topAllTime = [...viewData.drivers]
|
|
.sort((a, b) => b.wins - a.wins)
|
|
.slice(0, 5);
|
|
|
|
return (
|
|
<Section variant="default" padding="md">
|
|
<Stack gap={16}>
|
|
<PageHeader
|
|
title="Leaderboards"
|
|
description="Global Performance Standings"
|
|
icon={Activity}
|
|
action={
|
|
<Group gap={4}>
|
|
<Button
|
|
variant="secondary"
|
|
onClick={onNavigateToDrivers}
|
|
icon={<Icon icon={Trophy} size={4} />}
|
|
>
|
|
Drivers
|
|
</Button>
|
|
<Button
|
|
variant="secondary"
|
|
onClick={onNavigateToTeams}
|
|
icon={<Icon icon={Users} size={4} />}
|
|
>
|
|
Teams
|
|
</Button>
|
|
</Group>
|
|
}
|
|
/>
|
|
|
|
{/* Top 10 2026 up top */}
|
|
<DriverLeaderboardPreview
|
|
title="Top 10 Drivers 2026"
|
|
subtitle="Current Season Standings"
|
|
drivers={top10Drivers}
|
|
onDriverClick={onDriverClick}
|
|
onNavigateToDrivers={onNavigateToDrivers}
|
|
/>
|
|
|
|
<FeatureGrid columns={{ base: 1, lg: 2 }} gap={12}>
|
|
<TeamLeaderboardPreview
|
|
teams={top5Teams.map(t => ({
|
|
...t,
|
|
logoUrl: t.logoUrl || ''
|
|
}))}
|
|
onTeamClick={onTeamClick}
|
|
onNavigateToTeams={onNavigateToTeams}
|
|
/>
|
|
|
|
<Stack gap={12}>
|
|
<DriverLeaderboardPreview
|
|
title="Top Newcomers"
|
|
subtitle="Rising Stars (< 10 Races)"
|
|
drivers={topNewcomers}
|
|
onDriverClick={onDriverClick}
|
|
onNavigateToDrivers={onNavigateToDrivers}
|
|
/>
|
|
<DriverLeaderboardPreview
|
|
title="Top All Time"
|
|
subtitle="Most Wins"
|
|
drivers={topAllTime}
|
|
onDriverClick={onDriverClick}
|
|
onNavigateToDrivers={onNavigateToDrivers}
|
|
/>
|
|
</Stack>
|
|
</FeatureGrid>
|
|
</Stack>
|
|
</Section>
|
|
);
|
|
}
|