website refactor
This commit is contained in:
118
apps/website/components/leagues/ScheduleTable.tsx
Normal file
118
apps/website/components/leagues/ScheduleTable.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Icon } from '@/ui/Icon';
|
||||
import { Calendar, MapPin, ChevronRight } from 'lucide-react';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
import { Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from '@/ui/Table';
|
||||
import { Link } from '@/ui/Link';
|
||||
import { routes } from '@/lib/routing/RouteConfig';
|
||||
|
||||
interface RaceEntry {
|
||||
id: string;
|
||||
name: string;
|
||||
track: string;
|
||||
scheduledAt: string;
|
||||
status: 'upcoming' | 'live' | 'completed';
|
||||
}
|
||||
|
||||
interface ScheduleTableProps {
|
||||
races: RaceEntry[];
|
||||
}
|
||||
|
||||
export function ScheduleTable({ races }: ScheduleTableProps) {
|
||||
return (
|
||||
<Surface variant="dark" border rounded="lg" overflow="hidden">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeader>Race</TableHeader>
|
||||
<TableHeader>Track</TableHeader>
|
||||
<TableHeader>Date</TableHeader>
|
||||
<TableHeader>Status</TableHeader>
|
||||
<TableHeader textAlign="right">Actions</TableHeader>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{races.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={5} textAlign="center" py={12}>
|
||||
<Text color="text-gray-500">No races scheduled yet.</Text>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
races.map((race) => (
|
||||
<TableRow key={race.id}>
|
||||
<TableCell>
|
||||
<Text weight="medium" color="text-white">{race.name}</Text>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Icon icon={MapPin} size={3.5} color="text-gray-500" />
|
||||
<Text size="sm" color="text-gray-400">{race.track}</Text>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Stack direction="row" align="center" gap={2}>
|
||||
<Icon icon={Calendar} size={3.5} color="text-gray-500" />
|
||||
<Text size="sm" color="text-gray-400">
|
||||
{new Date(race.scheduledAt).toLocaleDateString()}
|
||||
</Text>
|
||||
</Stack>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<StatusBadge status={race.status} />
|
||||
</TableCell>
|
||||
<TableCell textAlign="right">
|
||||
<Link
|
||||
href={routes.race.detail(race.id)}
|
||||
variant="primary"
|
||||
size="xs"
|
||||
weight="bold"
|
||||
letterSpacing="wider"
|
||||
>
|
||||
<Stack direction="row" align="center" gap={1}>
|
||||
<Text>DETAILS</Text>
|
||||
<Icon icon={ChevronRight} size={3} />
|
||||
</Stack>
|
||||
</Link>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Surface>
|
||||
);
|
||||
}
|
||||
|
||||
function StatusBadge({ status }: { status: RaceEntry['status'] }) {
|
||||
const styles = {
|
||||
upcoming: 'bg-gray-500/10 text-gray-500 border-gray-500/20',
|
||||
live: 'bg-performance-green/10 text-performance-green border-performance-green/20 animate-pulse',
|
||||
completed: 'bg-primary-blue/10 text-primary-blue border-primary-blue/20',
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
as="span"
|
||||
px={2}
|
||||
py={0.5}
|
||||
rounded="full"
|
||||
fontSize="10px"
|
||||
border
|
||||
bg={styles[status].split(' ')[0]}
|
||||
color={styles[status].split(' ')[1]}
|
||||
borderColor={styles[status].split(' ')[2]}
|
||||
animate={status === 'live' ? 'pulse' : 'none'}
|
||||
letterSpacing="widest"
|
||||
weight="bold"
|
||||
display="inline-block"
|
||||
>
|
||||
{status.toUpperCase()}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user