Files
gridpilot.gg/apps/website/templates/DriversTemplate.tsx
2026-01-15 19:55:46 +01:00

141 lines
4.6 KiB
TypeScript

'use client';
import React from 'react';
import {
Search,
Crown,
Users,
Trophy,
} from 'lucide-react';
import { Heading } from '@/ui/Heading';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Container } from '@/ui/Container';
import { Grid } from '@/ui/Grid';
import { GridItem } from '@/ui/GridItem';
import { Surface } from '@/ui/Surface';
import { Icon } from '@/ui/Icon';
import { FeaturedDriverCard } from '@/components/drivers/FeaturedDriverCard';
import { SkillDistribution } from '@/ui/SkillDistribution';
import { CategoryDistribution } from '@/ui/CategoryDistribution';
import { LeaderboardPreview } from '@/components/leaderboards/LeaderboardPreview';
import { RecentActivity } from '@/components/feed/RecentActivity';
import { PageHero } from '@/ui/PageHero';
import { DriversSearch } from '@/ui/DriversSearch';
import { EmptyState } from '@/components/shared/state/EmptyState';
import type { DriversViewData } from '@/lib/types/view-data/DriversViewData';
interface DriversTemplateProps {
viewData: DriversViewData | null;
searchQuery: string;
onSearchChange: (query: string) => void;
filteredDrivers: DriversViewData['drivers'];
onDriverClick: (id: string) => void;
onViewLeaderboard: () => void;
}
export function DriversTemplate({
viewData,
searchQuery,
onSearchChange,
filteredDrivers,
onDriverClick,
onViewLeaderboard
}: DriversTemplateProps) {
const drivers = viewData?.drivers || [];
const totalRaces = viewData?.totalRaces || 0;
const totalWins = viewData?.totalWins || 0;
const activeCount = viewData?.activeCount || 0;
// Featured drivers (top 4)
const featuredDrivers = filteredDrivers.slice(0, 4);
return (
<Container size="lg" py={8}>
<Stack gap={10}>
{/* Hero Section */}
<PageHero
title="Drivers"
description="Meet the racers who make every lap count. From rookies to champions, track their journey and see who's dominating the grid."
icon={Users}
stats={[
{ label: 'drivers', value: drivers.length, color: 'text-primary-blue' },
{ label: 'active', value: activeCount, color: 'text-performance-green', animate: true },
{ label: 'total wins', value: totalWins.toLocaleString(), color: 'text-warning-amber' },
{ label: 'races', value: totalRaces.toLocaleString(), color: 'text-neon-aqua' },
]}
actions={[
{
label: 'View Leaderboard',
onClick: onViewLeaderboard,
icon: Trophy,
description: 'See full driver rankings'
}
]}
/>
{/* Search */}
<DriversSearch query={searchQuery} onChange={onSearchChange} />
{/* Featured Drivers */}
{!searchQuery && (
<Box>
<Stack direction="row" align="center" gap={3} mb={4}>
<Surface variant="muted" rounded="xl" padding={2}>
<Icon icon={Crown} size={6} color="#f59e0b" />
</Surface>
<Box>
<Heading level={2}>Featured Drivers</Heading>
<Text size="xs" color="text-gray-500">Top performers on the grid</Text>
</Box>
</Stack>
<Grid cols={4} gap={4}>
{featuredDrivers.map((driver, index) => (
<GridItem key={driver.id} colSpan={12} mdSpan={6} lgSpan={3}>
<FeaturedDriverCard
driver={driver}
position={index + 1}
onClick={() => onDriverClick(driver.id)}
/>
</GridItem>
))}
</Grid>
</Box>
)}
{/* Active Drivers */}
{!searchQuery && <RecentActivity drivers={drivers} onDriverClick={onDriverClick} />}
{/* Skill Distribution */}
{!searchQuery && <SkillDistribution drivers={drivers} />}
{/* Category Distribution */}
{!searchQuery && <CategoryDistribution drivers={drivers} />}
{/* Leaderboard Preview */}
<LeaderboardPreview
drivers={filteredDrivers}
onDriverClick={onDriverClick}
onNavigate={() => onViewLeaderboard()}
/>
{/* Empty State */}
{filteredDrivers.length === 0 && (
<EmptyState
icon={Search}
title="No drivers found"
description={`No drivers found matching "${searchQuery}"`}
action={{
label: 'Clear search',
onClick: () => onSearchChange(''),
variant: 'secondary'
}}
/>
)}
</Stack>
</Container>
);
}