feat: show live open ride count in park name cell

- Fetch Queue-Times ride counts for parks open today (5min cache)
- Only shown within 1h before open to 1h after scheduled close
- Count displayed on the right of the park name/location cell (desktop)
  and below the open badge (mobile)
- Whole park cell is now a clickable link
- Hover warms the park cell background; no row-wide highlight

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-04 20:38:12 -04:00
parent 43feb4cef0
commit 8e969165b4
5 changed files with 100 additions and 23 deletions

View File

@@ -10,6 +10,7 @@ interface WeekCalendarProps {
weekDates: string[]; // 7 dates, YYYY-MM-DD, SunSat
data: Record<string, Record<string, DayData>>; // parkId → date → DayData
grouped?: Map<Region, Park[]>; // pre-grouped parks (if provided, renders region headers)
rideCounts?: Record<string, number>; // parkId → open ride count for today
}
const DOW = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
@@ -163,12 +164,14 @@ function ParkRow({
weekDates,
parsedDates,
parkData,
rideCounts,
}: {
park: Park;
parkIdx: number;
weekDates: string[];
parsedDates: ReturnType<typeof parseDate>[];
parkData: Record<string, DayData>;
rideCounts?: Record<string, number>;
}) {
const rowBg = parkIdx % 2 === 0 ? "var(--color-bg)" : "var(--color-surface)";
return (
@@ -181,7 +184,7 @@ function ParkRow({
position: "sticky",
left: 0,
zIndex: 5,
padding: "10px 14px",
padding: 0,
borderBottom: "1px solid var(--color-border)",
borderRight: "1px solid var(--color-border)",
whiteSpace: "nowrap",
@@ -189,14 +192,27 @@ function ParkRow({
background: rowBg,
transition: "background 120ms ease",
}}>
<Link href={`/park/${park.id}`} className="park-name-link">
<span style={{ fontWeight: 500, fontSize: "0.85rem", lineHeight: 1.2 }}>
{park.name}
</span>
<Link href={`/park/${park.id}`} className="park-name-link" style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
padding: "10px 14px",
gap: 10,
}}>
<div>
<span style={{ fontWeight: 500, fontSize: "0.85rem", lineHeight: 1.2, color: "var(--color-text)" }}>
{park.name}
</span>
<div style={{ fontSize: "0.7rem", color: "var(--color-text-muted)", marginTop: 2 }}>
{park.location.city}, {park.location.state}
</div>
</div>
{rideCounts?.[park.id] !== undefined && (
<div style={{ fontSize: "0.65rem", color: "var(--color-open-hours)", fontWeight: 500, whiteSpace: "nowrap", flexShrink: 0 }}>
{rideCounts[park.id]} open
</div>
)}
</Link>
<div style={{ fontSize: "0.7rem", color: "var(--color-text-muted)", marginTop: 2 }}>
{park.location.city}, {park.location.state}
</div>
</td>
{weekDates.map((date, i) => (
@@ -210,7 +226,7 @@ function ParkRow({
);
}
export function WeekCalendar({ parks, weekDates, data, grouped }: WeekCalendarProps) {
export function WeekCalendar({ parks, weekDates, data, grouped, rideCounts }: WeekCalendarProps) {
const today = getTodayLocal();
const parsedDates = weekDates.map(parseDate);
@@ -324,6 +340,7 @@ export function WeekCalendar({ parks, weekDates, data, grouped }: WeekCalendarPr
weekDates={weekDates}
parsedDates={parsedDates}
parkData={data[park.id] ?? {}}
rideCounts={rideCounts}
/>
))}
</Fragment>