103 lines
3.7 KiB
TypeScript
103 lines
3.7 KiB
TypeScript
'use client';
|
||
|
||
import { Result } from '../../domain/entities/Result';
|
||
import { Driver } from '../../domain/entities/Driver';
|
||
|
||
interface ResultsTableProps {
|
||
results: Result[];
|
||
drivers: Driver[];
|
||
pointsSystem: Record<number, number>;
|
||
fastestLapTime?: number;
|
||
}
|
||
|
||
export default function ResultsTable({ results, drivers, pointsSystem, fastestLapTime }: ResultsTableProps) {
|
||
const getDriverName = (driverId: string): string => {
|
||
const driver = drivers.find(d => d.id === driverId);
|
||
return driver?.name || 'Unknown Driver';
|
||
};
|
||
|
||
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 (
|
||
<div className="text-center py-8 text-gray-400">
|
||
No results available
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<div className="overflow-x-auto">
|
||
<table className="w-full">
|
||
<thead>
|
||
<tr className="border-b border-charcoal-outline">
|
||
<th className="text-left py-3 px-4 text-sm font-semibold text-gray-400">Pos</th>
|
||
<th className="text-left py-3 px-4 text-sm font-semibold text-gray-400">Driver</th>
|
||
<th className="text-left py-3 px-4 text-sm font-semibold text-gray-400">Fastest Lap</th>
|
||
<th className="text-left py-3 px-4 text-sm font-semibold text-gray-400">Incidents</th>
|
||
<th className="text-left py-3 px-4 text-sm font-semibold text-gray-400">Points</th>
|
||
<th className="text-left py-3 px-4 text-sm font-semibold text-gray-400">+/-</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{results.map((result) => {
|
||
const positionChange = result.getPositionChange();
|
||
const isFastestLap = fastestLapTime && result.fastestLap === fastestLapTime;
|
||
|
||
return (
|
||
<tr
|
||
key={result.id}
|
||
className="border-b border-charcoal-outline/50 hover:bg-iron-gray/20 transition-colors"
|
||
>
|
||
<td className="py-3 px-4">
|
||
<span className="text-white font-semibold">{result.position}</span>
|
||
</td>
|
||
<td className="py-3 px-4">
|
||
<span className="text-white">{getDriverName(result.driverId)}</span>
|
||
</td>
|
||
<td className="py-3 px-4">
|
||
<span className={isFastestLap ? 'text-performance-green font-medium' : 'text-white'}>
|
||
{formatLapTime(result.fastestLap)}
|
||
</span>
|
||
</td>
|
||
<td className="py-3 px-4">
|
||
<span className={result.incidents > 0 ? 'text-warning-amber' : 'text-white'}>
|
||
{result.incidents}×
|
||
</span>
|
||
</td>
|
||
<td className="py-3 px-4">
|
||
<span className="text-white font-medium">{getPoints(result.position)}</span>
|
||
</td>
|
||
<td className="py-3 px-4">
|
||
<span className={`font-medium ${getPositionChangeColor(positionChange)}`}>
|
||
{getPositionChangeText(positionChange)}
|
||
</span>
|
||
</td>
|
||
</tr>
|
||
);
|
||
})}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
);
|
||
} |