Files
gridpilot.gg/apps/website/ui/RaceResultRow.tsx
2026-01-15 17:12:24 +01:00

108 lines
4.0 KiB
TypeScript

import { CountryFlagDisplay } from '@/lib/display-objects/CountryFlagDisplay';
import { Box } from './Box';
import { Image } from './Image';
import { Stack } from './Stack';
import { Surface } from './Surface';
import { Text } from './Text';
interface ResultEntry {
position: number;
driverId: string;
driverName: string;
driverAvatar: string;
country: string;
car: string;
laps: number;
time: string;
fastestLap: string;
points: number;
incidents: number;
isCurrentUser: boolean;
}
interface RaceResultRowProps {
result: ResultEntry;
points: number;
}
export function RaceResultRow({ result, points }: RaceResultRowProps) {
const { isCurrentUser, position, driverAvatar, driverName, country, car, laps, incidents, time, fastestLap } = result;
const getPositionColor = (pos: number) => {
if (pos === 1) return { bg: 'bg-yellow-500/20', color: 'text-yellow-400' };
if (pos === 2) return { bg: 'bg-gray-400/20', color: 'text-gray-300' };
if (pos === 3) return { bg: 'bg-amber-600/20', color: 'text-amber-600' };
return { bg: 'bg-iron-gray/50', color: 'text-gray-500' };
};
const posConfig = getPositionColor(position);
return (
<Surface
variant={isCurrentUser ? 'muted' : 'dark'}
rounded="xl"
border={isCurrentUser}
padding={3}
className={isCurrentUser ? 'border-primary-blue/40' : ''}
style={isCurrentUser ? { background: 'linear-gradient(to right, rgba(59, 130, 246, 0.2), rgba(59, 130, 246, 0.1), transparent)' } : {}}
>
<Stack direction="row" align="center" gap={3}>
{/* Position */}
<Box
width="10"
height="10"
rounded="lg"
display="flex"
center
className={`${posConfig.bg} ${posConfig.color}`}
>
<Text weight="bold">{position}</Text>
</Box>
{/* Avatar */}
<Box position="relative" flexShrink={0}>
<Box width="10" height="10" rounded="full" overflow="hidden" border={isCurrentUser} borderColor="border-primary-blue/50" className={isCurrentUser ? 'border-2' : ''}>
<Image src={driverAvatar} alt={driverName} width={40} height={40} objectFit="cover" />
</Box>
<Box position="absolute" bottom="-0.5" right="-0.5" width="5" height="5" rounded="full" bg="bg-deep-graphite" display="flex" center style={{ fontSize: '0.625rem' }}>
{CountryFlagDisplay.fromCountryCode(country).toString()}
</Box>
</Box>
{/* Driver Info */}
<Box flexGrow={1} minWidth="0">
<Stack direction="row" align="center" gap={2}>
<Text weight="semibold" size="sm" color={isCurrentUser ? 'text-primary-blue' : 'text-white'} truncate>{driverName}</Text>
{isCurrentUser && (
<Box px={2} py={0.5} rounded="full" bg="bg-primary-blue">
<Text size="xs" weight="bold" color="text-white">YOU</Text>
</Box>
)}
</Stack>
<Stack direction="row" align="center" gap={2} mt={1}>
<Text size="xs" color="text-gray-500">{car}</Text>
<Text size="xs" color="text-gray-500"></Text>
<Text size="xs" color="text-gray-500">Laps: {laps}</Text>
<Text size="xs" color="text-gray-500"></Text>
<Text size="xs" color="text-gray-500">Incidents: {incidents}</Text>
</Stack>
</Box>
{/* Times */}
<Box textAlign="right" style={{ minWidth: '100px' }}>
<Text size="sm" font="mono" color="text-white" block>{time}</Text>
<Text size="xs" color="text-performance-green" block mt={1}>FL: {fastestLap}</Text>
</Box>
{/* Points */}
<Box p={2} rounded="lg" border={true} borderColor="border-warning-amber/20" bg="bg-warning-amber/10" textAlign="center" style={{ minWidth: '3.5rem' }}>
<Text size="xs" color="text-gray-500" block>PTS</Text>
<Text size="sm" weight="bold" color="text-warning-amber">{points}</Text>
</Box>
</Stack>
</Surface>
);
}