Files
gridpilot.gg/apps/website/templates/TeamLeaderboardTemplate.tsx
2026-01-19 18:01:30 +01:00

120 lines
4.7 KiB
TypeScript

'use client';
import { LeaderboardFiltersBar } from '@/components/leaderboards/LeaderboardFiltersBar';
import type { SkillLevel, SortBy, TeamLeaderboardViewData } from '@/lib/view-data/TeamLeaderboardViewData';
import { Button } from '@/ui/Button';
import { Container } from '@/ui/Container';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Group } from '@/ui/Group';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/ui/Table';
import { Text } from '@/ui/Text';
import { Panel } from '@/ui/Panel';
import { Section } from '@/ui/Section';
import { Award, ChevronLeft } from 'lucide-react';
import React from 'react';
interface TeamLeaderboardTemplateProps {
viewData: TeamLeaderboardViewData;
onSearchChange: (query: string) => void;
filterLevelChange: (level: SkillLevel | 'all') => void;
onSortChange: (sort: SortBy) => void;
onTeamClick: (id: string) => void;
onBackToTeams: () => void;
}
export function TeamLeaderboardTemplate({
viewData,
onSearchChange,
onTeamClick,
onBackToTeams,
}: TeamLeaderboardTemplateProps) {
const { searchQuery, filteredAndSortedTeams } = viewData;
return (
<Container size="lg" py={12}>
<Group direction="column" gap={8} fullWidth>
{/* Header */}
<Group direction="row" align="center" justify="between" fullWidth>
<Group direction="row" align="center" gap={4}>
<Button variant="secondary" size="sm" onClick={onBackToTeams} icon={<Icon icon={ChevronLeft} size={4} />}>
Back
</Button>
<Group direction="column">
<Heading level={1} weight="bold">Global Standings</Heading>
<Text variant="low" size="sm" font="mono" uppercase letterSpacing="widest">Team Performance Index</Text>
</Group>
</Group>
<Icon icon={Award} size={8} color="var(--ui-color-intent-warning)" />
</Group>
<LeaderboardFiltersBar
searchQuery={searchQuery}
onSearchChange={onSearchChange}
placeholder="Search teams..."
/>
<Panel variant="dark" padding={0}>
<Table>
<TableHead>
<TableRow>
<TableHeader w="20">Rank</TableHeader>
<TableHeader>Team</TableHeader>
<TableHeader textAlign="center">Personnel</TableHeader>
<TableHeader textAlign="center">Races</TableHeader>
<TableHeader textAlign="right">Rating</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{filteredAndSortedTeams.length > 0 ? (
filteredAndSortedTeams.map((team, index) => (
<TableRow
key={team.id}
onClick={() => onTeamClick(team.id)}
clickable
>
<TableCell>
<Text font="mono" weight="bold" variant={index < 3 ? 'warning' : 'low'}>
#{index + 1}
</Text>
</TableCell>
<TableCell>
<Group direction="row" align="center" gap={3}>
<Panel variant="muted" padding={2}>
<Text size="xs" weight="bold" color="text-primary-accent">{team.name.substring(0, 2).toUpperCase()}</Text>
</Panel>
<Text weight="bold" size="sm">{team.name}</Text>
</Group>
</TableCell>
<TableCell textAlign="center">
<Text size="xs" variant="low" font="mono">{team.memberCount}</Text>
</TableCell>
<TableCell textAlign="center">
<Text size="xs" variant="low" font="mono">{team.totalRaces}</Text>
</TableCell>
<TableCell textAlign="right">
<Text font="mono" weight="bold" color="text-primary-accent">1450</Text>
</TableCell>
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={5} textAlign="center">
<Section variant="dark" padding="lg">
<Group align="center" justify="center" fullWidth>
<Text variant="low" font="mono" size="xs" uppercase letterSpacing="widest">
No teams found matching criteria
</Text>
</Group>
</Section>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</Panel>
</Group>
</Container>
);
}