feat: detect passholder preview days and filter plain buyouts
All checks were successful
Build and Deploy / Build & Push (push) Successful in 3m9s

- Buyout days are now treated as closed unless they carry a Passholder
  Preview event, in which case they surface as a distinct purple cell
  in the UI showing "Passholder" + hours
- DB gains a special_type column (auto-migrated on next startup)
- scrape.ts threads specialType through to upsertDay
- debug.ts now shows events, isBuyout, isPassholderPreview, and
  specialType in the parsed result section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-04 10:53:05 -04:00
parent 7c28d8f89f
commit 91e09b0548
6 changed files with 114 additions and 26 deletions

View File

@@ -177,6 +177,52 @@ export function WeekCalendar({ parks, weekDates, data }: WeekCalendarProps) {
);
}
// Passholder preview day
if (dayData.specialType === "passholder_preview") {
return (
<td key={date} style={{
...tdBase,
padding: 4,
borderLeft: isToday ? "1px solid var(--color-today-border)" : undefined,
borderRight: isToday ? "1px solid var(--color-today-border)" : undefined,
}}>
<div style={{
background: "var(--color-ph-bg)",
border: "1px solid var(--color-ph-border)",
borderRadius: 6,
padding: "4px 4px",
textAlign: "center",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
gap: 2,
}}>
<span style={{
color: "var(--color-ph-label)",
fontSize: "0.6rem",
fontWeight: 600,
letterSpacing: "0.04em",
textTransform: "uppercase",
whiteSpace: "nowrap",
}}>
Passholder
</span>
<span style={{
color: "var(--color-ph-hours)",
fontSize: "0.72rem",
fontWeight: 500,
letterSpacing: "-0.01em",
whiteSpace: "nowrap",
}}>
{dayData.hoursLabel}
</span>
</div>
</td>
);
}
// Open with confirmed hours
return (
<td key={date} style={{