import type { Lap } from '../types' import { formatLapTime } from '../utils' interface Props { laps: Lap[] } interface DriverLapSummary { driver_number: number total: number best: Lap | null lastLap: number pitOuts: number } export function LapsView({ laps }: Props) { if (laps.length === 0) { return (
Laps not ingested. Run box-box --ingest-session <key> to load this dataset.
) } const byDriver = new Map() for (const lap of laps) { const summary = byDriver.get(lap.driver_number) ?? { driver_number: lap.driver_number, total: 0, best: null, lastLap: 0, pitOuts: 0, } summary.total += 1 summary.lastLap = Math.max(summary.lastLap, lap.lap_number) if (lap.is_pit_out_lap) summary.pitOuts += 1 if ( lap.lap_duration != null && lap.lap_duration > 0 && (!summary.best || summary.best.lap_duration == null || lap.lap_duration < summary.best.lap_duration) ) { summary.best = lap } byDriver.set(lap.driver_number, summary) } const rows = [...byDriver.values()].sort((a, b) => { const aBest = a.best?.lap_duration ?? Number.POSITIVE_INFINITY const bBest = b.best?.lap_duration ?? Number.POSITIVE_INFINITY if (aBest !== bBest) return aBest - bBest return a.driver_number - b.driver_number }) const fastest = rows.find((row) => row.best?.lap_duration != null)?.best return (
{rows.map((row) => { const isFastest = fastest && row.best?.driver_number === fastest.driver_number && row.best?.lap_number === fastest.lap_number return ( ) })}
Driver Best Lap Best Time Laps Pit Outs
#{row.driver_number} {row.best ? ( <> {row.best.lap_number} {isFastest && ( FASTEST )} ) : ( '—' )} {formatLapTime(row.best?.lap_duration)} {row.lastLap || row.total} {row.pitOuts || '—'}
) }