"use client"; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, ReferenceArea, } from "recharts"; import { computeOutages, outageLookup, formatOutageDuration } from "@/lib/outage"; export interface TodaySample { recordedAt: string; localTime: string; isOpen: boolean; waitMinutes: number | null; fastLaneMinutes: number | null; } interface Props { samples: TodaySample[]; hasFastLane: boolean; } const TIME_FMT = new Intl.DateTimeFormat([], { hour: "2-digit", minute: "2-digit", hour12: false, }); export default function WaitTimeTodayChart({ samples, hasFastLane }: Props) { const outages = computeOutages(samples); const outageByTime = outageLookup(samples, outages); // Show the Fast Lane line if either the ride metadata flags it as a Fast // Lane ride OR we have any actual Fast Lane data in today's samples. The // metadata flag can lag (or read false even when SF is reporting waits), // so the data-driven check rescues those rides. const showFastLane = hasFastLane || samples.some((s) => s.fastLaneMinutes !== null); // X-axis time is rendered in the viewer's local timezone (Intl with no // tz arg) so an Eastern-time user sees ET regardless of which park. // Each point also carries its outage (if any) so the custom tooltip can // render "Outage #N — Hh Mm" without re-scanning. const data = samples.map((s) => { const time = TIME_FMT.format(new Date(s.recordedAt)); const outage = !s.isOpen ? outageByTime.get(time) ?? null : null; return { time, wait: s.isOpen ? s.waitMinutes : null, fl: s.isOpen ? s.fastLaneMinutes : null, outageN: outage?.n ?? null, outageDurationMin: outage?.durationMin ?? null, }; }); const tickInterval = Math.max(1, Math.floor(data.length / 8)); return (