118 lines
3.2 KiB
TypeScript
118 lines
3.2 KiB
TypeScript
'use client';
|
|
|
|
import { routes } from '@/lib/routing/RouteConfig';
|
|
import { Card } from '@/ui/Card';
|
|
import { Heading } from '@/ui/Heading';
|
|
import { Icon } from '@/ui/Icon';
|
|
import { Link } from '@/ui/Link';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Text } from '@/ui/Text';
|
|
import { Badge } from '@/ui/Badge';
|
|
import { ArrowRight, Car, ChevronRight, LucideIcon, Trophy, Zap } from 'lucide-react';
|
|
|
|
interface RaceCardProps {
|
|
track: string;
|
|
car: string;
|
|
scheduledAt: string;
|
|
scheduledAtLabel: string;
|
|
timeLabel: string;
|
|
status: string;
|
|
statusLabel: string;
|
|
statusVariant: 'primary' | 'success' | 'warning' | 'critical' | 'default' | 'secondary' | 'info' | 'danger';
|
|
leagueName: string;
|
|
leagueId?: string;
|
|
strengthOfField?: number | null;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
export function RaceCard({
|
|
track,
|
|
car,
|
|
scheduledAt,
|
|
scheduledAtLabel,
|
|
timeLabel,
|
|
status,
|
|
statusLabel,
|
|
statusVariant,
|
|
leagueName,
|
|
leagueId,
|
|
strengthOfField,
|
|
onClick,
|
|
}: RaceCardProps) {
|
|
return (
|
|
<Card
|
|
variant="dark"
|
|
onClick={onClick}
|
|
>
|
|
<Stack direction="row" align="start" gap={4}>
|
|
{/* Time Column */}
|
|
<Stack align="center" gap={1}>
|
|
<Text size="lg" weight="bold" variant="high">
|
|
{timeLabel}
|
|
</Text>
|
|
<Text size="xs" variant={statusVariant === 'default' ? 'low' : (statusVariant as any)}>
|
|
{status === 'running' ? 'LIVE' : scheduledAtLabel}
|
|
</Text>
|
|
</Stack>
|
|
|
|
{/* Main Content */}
|
|
<Stack gap={4} fullWidth>
|
|
<Stack direction="row" align="start" justify="between" gap={4}>
|
|
<Stack>
|
|
<Heading
|
|
level={3}
|
|
>
|
|
{track}
|
|
</Heading>
|
|
<Stack direction="row" align="center" gap={3}>
|
|
<Stack direction="row" align="center" gap={1}>
|
|
<Icon icon={Car} size={3.5} intent="low" />
|
|
<Text size="sm" variant="low">
|
|
{car}
|
|
</Text>
|
|
</Stack>
|
|
{strengthOfField && (
|
|
<Stack direction="row" align="center" gap={1}>
|
|
<Icon icon={Zap} size={3.5} intent="warning" />
|
|
<Text size="sm" variant="low">
|
|
SOF {strengthOfField}
|
|
</Text>
|
|
</Stack>
|
|
)}
|
|
</Stack>
|
|
</Stack>
|
|
|
|
{/* Status Badge */}
|
|
<Badge variant={statusVariant}>
|
|
{statusLabel}
|
|
</Badge>
|
|
</Stack>
|
|
|
|
{/* League Link */}
|
|
<Stack>
|
|
<Link
|
|
href={routes.league.detail(leagueId ?? '')}
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<Stack direction="row" align="center" gap={2}>
|
|
<Icon icon={Trophy} size={3.5} intent="primary" />
|
|
<Text size="sm" variant="primary">
|
|
{leagueName}
|
|
</Text>
|
|
<Icon icon={ArrowRight} size={3} intent="primary" />
|
|
</Stack>
|
|
</Link>
|
|
</Stack>
|
|
</Stack>
|
|
|
|
{/* Arrow */}
|
|
<Icon
|
|
icon={ChevronRight}
|
|
size={5}
|
|
intent="low"
|
|
/>
|
|
</Stack>
|
|
</Card>
|
|
);
|
|
}
|