All checks were successful
Deploy to Cloudflare Pages / deploy (push) Successful in 4m3s
131 lines
4.4 KiB
TypeScript
131 lines
4.4 KiB
TypeScript
import { AppData } from "@/lib/types";
|
|
import { parsePoints, findStyleByPoints } from "@/lib/leaderboard";
|
|
|
|
interface RaceResultsTableProps {
|
|
appData: AppData;
|
|
}
|
|
|
|
export default function RaceResultsTable({ appData }: RaceResultsTableProps) {
|
|
return (
|
|
<div
|
|
id="table-container"
|
|
className="bg-gray-800/70 p-4 rounded-2xl shadow-2xl backdrop-blur-sm border border-gray-700/50 overflow-x-auto"
|
|
>
|
|
<table
|
|
id="race-results-table"
|
|
className="w-full min-w-[1200px] border-collapse text-center"
|
|
>
|
|
<thead id="race-table-head">
|
|
<tr>
|
|
<th scope="col" className="py-3 px-4 min-w-[200px]">
|
|
Track
|
|
</th>
|
|
<th scope="col" className="py-3 px-4 min-w-[100px]">
|
|
FL
|
|
</th>
|
|
{appData.drivers.map((driver) => (
|
|
<th
|
|
key={driver.initials}
|
|
scope="col"
|
|
className="py-3 px-4 min-w-[170px]"
|
|
style={{ textAlign: "center" }}
|
|
>
|
|
<span>{driver.name}</span>
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody id="race-table-body" className="divide-y divide-gray-700">
|
|
{appData.tracks.map((track, trackIndex) => (
|
|
<tr key={trackIndex}>
|
|
<td className="font-semibold py-3 px-4 whitespace-nowrap min-w-[200px]">
|
|
<span>{track.name}</span>
|
|
</td>
|
|
<td className="py-3 px-4 font-mono min-w-[100px]">
|
|
{track.fastestLapInitials || ""}
|
|
</td>
|
|
{appData.drivers.map((driver, driverIndex) => {
|
|
const driverInitials = driver.initials;
|
|
let result = track.results[driverIndex];
|
|
// DNS fallback
|
|
if (result === undefined || result === null || result === "") {
|
|
result = "DNS";
|
|
}
|
|
const pointsNum = parsePoints(result);
|
|
const style = findStyleByPoints(appData, pointsNum);
|
|
|
|
let cellStyles: React.CSSProperties = {
|
|
backgroundColor: style.color,
|
|
color: style.textColor,
|
|
};
|
|
|
|
let hasFL = false;
|
|
if (
|
|
track.fastestLapInitials &&
|
|
track.fastestLapInitials === driverInitials &&
|
|
appData.flPoints.points
|
|
) {
|
|
hasFL = true;
|
|
const flColor = appData.flPoints.color;
|
|
if (pointsNum === 0) {
|
|
cellStyles = {
|
|
backgroundColor: flColor,
|
|
color: appData.flPoints.textColor,
|
|
};
|
|
} else {
|
|
cellStyles = {
|
|
background: `linear-gradient(135deg, ${style.color} 50%, ${flColor} 50%)`,
|
|
color: style.textColor,
|
|
};
|
|
}
|
|
}
|
|
|
|
if (hasFL) {
|
|
cellStyles = {
|
|
...cellStyles,
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
flexDirection: "row",
|
|
paddingLeft: "0.75rem",
|
|
paddingRight: "0.75rem",
|
|
};
|
|
} else {
|
|
cellStyles = {
|
|
...cellStyles,
|
|
textAlign: "center",
|
|
};
|
|
}
|
|
|
|
return (
|
|
<td
|
|
key={driverIndex}
|
|
className="py-3 px-4 font-mono"
|
|
style={cellStyles}
|
|
>
|
|
{hasFL ? (
|
|
<>
|
|
<span style={{ flexGrow: 1, textAlign: "left" }}>
|
|
{result}
|
|
</span>
|
|
<span
|
|
className="fl-text-only"
|
|
style={{ color: appData.flPoints.textColor }}
|
|
>
|
|
(+{appData.flPoints.points})
|
|
</span>
|
|
</>
|
|
) : (
|
|
<span>{result}</span>
|
|
)}
|
|
</td>
|
|
);
|
|
})}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|