'use client'; import { Badge } from '@/ui/Badge'; import { Icon } from '@/ui/Icon'; import { Link } from '@/ui/Link'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/ui/Table'; import { Text } from '@/ui/Text'; import { Box } from '@/ui/Box'; import { Group } from '@/ui/Group'; import { Stack } from '@/ui/Stack'; import { Surface } from '@/ui/Surface'; import { PositionBadge } from '@/ui/ResultRow'; import { AlertTriangle, ExternalLink } from 'lucide-react'; import React, { ReactNode } from 'react'; type PenaltyTypeDTO = | 'time_penalty' | 'grid_penalty' | 'points_deduction' | 'disqualification' | 'warning' | 'license_points' | string; interface ResultDTO { id: string; raceId: string; driverId: string; position: number; fastestLap: number; incidents: number; startPosition: number; getPositionChange(): number; } interface DriverDTO { id: string; name: string; } interface PenaltyData { driverId: string; type: PenaltyTypeDTO; value?: number; } interface RaceResultsTableProps { results: ResultDTO[]; drivers: DriverDTO[]; pointsSystem: Record; fastestLapTime?: number | undefined; penalties?: PenaltyData[]; currentDriverId?: string | undefined; isAdmin?: boolean; onPenaltyClick?: (driver: DriverDTO) => void; penaltyButtonRenderer?: (driver: DriverDTO) => ReactNode; } export function RaceResultsTable({ results, drivers, pointsSystem, fastestLapTime, penalties = [], currentDriverId, isAdmin = false, penaltyButtonRenderer, }: RaceResultsTableProps) { const getDriver = (driverId: string): DriverDTO | undefined => { return drivers.find((d) => d.id === driverId); }; const getDriverName = (driverId: string): string => { const driver = getDriver(driverId); return driver?.name || 'Unknown Driver'; }; const getDriverPenalties = (driverId: string): PenaltyData[] => { return penalties.filter((p) => p.driverId === driverId); }; const getPenaltyDescription = (penalty: PenaltyData): string => { const descriptions: Record = { time_penalty: `+${penalty.value}s time penalty`, grid_penalty: `${penalty.value} place grid penalty`, points_deduction: `-${penalty.value} points`, disqualification: 'Disqualified', warning: 'Warning', license_points: `${penalty.value} license points`, }; return descriptions[penalty.type] || penalty.type; }; const formatLapTime = (seconds: number): string => { const minutes = Math.floor(seconds / 60); const secs = (seconds % 60).toFixed(3); return `${minutes}:${secs.padStart(6, '0')}`; }; const getPoints = (position: number): number => { return pointsSystem[position] || 0; }; const getPositionChangeVariant = (change: number): 'success' | 'warning' | 'low' => { if (change > 0) return 'success'; if (change < 0) return 'warning'; return 'low'; }; const getPositionChangeText = (change: number): string => { if (change > 0) return `+${change}`; if (change < 0) return `${change}`; return '0'; }; if (results.length === 0) { return ( No results available ); } return ( Pos Driver Fastest Lap Incidents Points +/- Penalties {isAdmin && Actions} {results.map((result) => { const positionChange = result.getPositionChange(); const isFastestLap = typeof fastestLapTime === 'number' && result.fastestLap === fastestLapTime; const driverPenalties = getDriverPenalties(result.driverId); const driver = getDriver(result.driverId); const isCurrentUser = currentDriverId === result.driverId; return ( {driver ? ( {driver.name.charAt(0)} {driver.name} {isCurrentUser && ( You )} ) : ( {getDriverName(result.driverId)} )} {formatLapTime(result.fastestLap)} 0 ? 'warning' : 'high'}> {result.incidents}× {getPoints(result.position)} {getPositionChangeText(positionChange)} {driverPenalties.length > 0 ? ( {driverPenalties.map((penalty, idx) => ( {getPenaltyDescription(penalty)} ))} ) : ( )} {isAdmin && ( {driver && penaltyButtonRenderer && penaltyButtonRenderer(driver)} )} ); })}
); }