'use client'; import Link from 'next/link'; import { AlertTriangle, ExternalLink } from 'lucide-react'; import InlinePenaltyButton from './InlinePenaltyButton'; 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 ResultsTableProps { results: ResultDTO[]; drivers: DriverDTO[]; pointsSystem: Record; fastestLapTime?: number | undefined; penalties?: PenaltyData[]; currentDriverId?: string | undefined; isAdmin?: boolean; onPenaltyClick?: (driver: DriverDTO) => void; } export default function ResultsTable({ results, drivers, pointsSystem, fastestLapTime, penalties = [], currentDriverId, isAdmin = false, onPenaltyClick, }: ResultsTableProps) { 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 getPositionChangeColor = (change: number): string => { if (change > 0) return 'text-performance-green'; if (change < 0) return 'text-warning-amber'; return 'text-gray-500'; }; 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 (
{isAdmin && } {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 ( {isAdmin && ( )} ); })}
Pos Driver Fastest Lap Incidents Points +/- PenaltiesActions
{result.position}
{driver ? ( <>
{driver.name.charAt(0)}
{driver.name} {isCurrentUser && ( You )} ) : ( {getDriverName(result.driverId)} )}
{formatLapTime(result.fastestLap)} 0 ? 'text-warning-amber' : 'text-white'} > {result.incidents}× {getPoints(result.position)} {getPositionChangeText(positionChange)} {driverPenalties.length > 0 ? (
{driverPenalties.map((penalty, idx) => (
{getPenaltyDescription(penalty)}
))}
) : ( )}
{driver && onPenaltyClick && ( )}
); }