wip
This commit is contained in:
103
apps/website/components/races/ResultsTable.tsx
Normal file
103
apps/website/components/races/ResultsTable.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
'use client';
|
||||
|
||||
import { Result } from '@gridpilot/racing/domain/entities/Result';
|
||||
import { Driver } from '@gridpilot/racing/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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user