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 (
| Driver |
Best Lap |
Best Time |
Laps |
Pit Outs |
{rows.map((row) => {
const isFastest =
fastest &&
row.best?.driver_number === fastest.driver_number &&
row.best?.lap_number === fastest.lap_number
return (
|
#{row.driver_number}
|
{row.best ? (
<>
{row.best.lap_number}
{isFastest && (
FASTEST
)}
>
) : (
'—'
)}
|
{formatLapTime(row.best?.lap_duration)} |
{row.lastLap || row.total} |
{row.pitOuts || '—'}
|
)
})}
)
}