Files
gridpilot.gg/apps/website/templates/DriversTemplate.tsx
2026-01-14 23:31:57 +01:00

123 lines
4.0 KiB
TypeScript

'use client';
import React from 'react';
import {
Search,
Crown,
} 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 '@/components/drivers/SkillDistribution';
import { CategoryDistribution } from '@/components/drivers/CategoryDistribution';
import { LeaderboardPreview } from '@/components/drivers/LeaderboardPreview';
import { RecentActivity } from '@/components/drivers/RecentActivity';
import { DriversHero } from '@/components/drivers/DriversHero';
import { DriversSearch } from '@/components/drivers/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 */}
<DriversHero
driverCount={drivers.length}
activeCount={activeCount}
totalWins={totalWins}
totalRaces={totalRaces}
onViewLeaderboard={onViewLeaderboard}
/>
{/* 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} />
{/* 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>
);
}