108 lines
4.0 KiB
TypeScript
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>
|
|
);
|
|
}
|