diff --git a/src/components/leaderboard/LeaderboardManager.tsx b/src/components/leaderboard/LeaderboardManager.tsx index f60cab6..068ec7c 100644 --- a/src/components/leaderboard/LeaderboardManager.tsx +++ b/src/components/leaderboard/LeaderboardManager.tsx @@ -38,19 +38,20 @@ export function LeaderboardManager({ serverId, initialData }: LeaderboardManager const dirty = isDirty(draft, saved); const handleDriversChange = (newDrivers: LeaderboardDriver[]) => { - const oldDrivers = draft.drivers; + const oldDriverIds = new Set(draft.drivers.map((d) => d.id)); - // Build index map by matching drivers by initials (their stable identifier) - // For each position in newDrivers, find where that driver was in oldDrivers - const indexMap = newDrivers.map((d) => { - const oldIndex = oldDrivers.findIndex((old) => old.initials === d.initials); - return oldIndex; // -1 if new driver, otherwise the old index - }); - - // If a driver was added (findIndex returns -1), it's new, start with DNS + // Remap tracks: keep results for drivers that still exist, remove results for deleted drivers const newTracks = draft.tracks.map((t) => ({ ...t, - results: indexMap.map((i) => (i === -1 ? 'DNS' : (t.results[i] ?? 'DNS'))) + // Filter existing results to only include drivers still in newDrivers, add DNS for new drivers + results: [ + // Keep existing results for drivers still in the list + ...t.results.filter((r) => newDrivers.some((d) => d.id === r.driverId)), + // Add DNS for new drivers + ...newDrivers + .filter((d) => !oldDriverIds.has(d.id)) + .map((d) => ({ driverId: d.id, score: 'DNS' as const })) + ] })); setDraft({ ...draft, drivers: newDrivers, tracks: newTracks }); diff --git a/src/components/leaderboard/LeaderboardStandings.tsx b/src/components/leaderboard/LeaderboardStandings.tsx index cb96422..db8f865 100644 --- a/src/components/leaderboard/LeaderboardStandings.tsx +++ b/src/components/leaderboard/LeaderboardStandings.tsx @@ -10,15 +10,17 @@ interface LeaderboardStandingsProps { export function LeaderboardStandings({ leaderboard }: LeaderboardStandingsProps) { const standings = useMemo(() => { return leaderboard.drivers - .map((driver, idx) => { - const trackResults = leaderboard.tracks.map((t) => t.results[idx] ?? 0); + .map((driver) => { + const trackResults = leaderboard.tracks.map( + (t) => t.results.find((r) => r.driverId === driver.id)?.score ?? 'DNS' + ); const fastestLapCount = leaderboard.tracks.filter( - (t) => t.fastestLapInitials === driver.initials + (t) => t.fastestLapDriverId === driver.id ).length; const totalPoints = trackResults.reduce((sum: number, r) => sum + (typeof r === 'number' ? r : 0), 0) + fastestLapCount * leaderboard.flPoints.points; - return { driver, driverIndex: idx, totalPoints, trackResults, fastestLapCount }; + return { driver, driverId: driver.id, totalPoints, trackResults, fastestLapCount }; }) .sort((a, b) => b.totalPoints - a.totalPoints); }, [leaderboard]); @@ -54,7 +56,7 @@ export function LeaderboardStandings({ leaderboard }: LeaderboardStandingsProps) {standings.map((row, pos) => ( - + {pos + 1}
@@ -68,7 +70,7 @@ export function LeaderboardStandings({ leaderboard }: LeaderboardStandingsProps) {row.trackResults.map((result, ti) => { const track = leaderboard.tracks[ti]; - const isFl = track.fastestLapInitials === row.driver.initials; + const isFl = track.fastestLapDriverId === row.driver.id; return ( { - onChange([...drivers, { name: 'New Driver', initials: 'ND', color: randomColor() }]); + onChange([...drivers, { id: crypto.randomUUID(), name: 'New Driver', initials: 'ND', color: randomColor() }]); }; return (
{drivers.map((driver, i) => ( -
+