feat: UI redesign with park detail pages and ride status
Some checks failed
Build and Deploy / Build & Push (push) Failing after 22s
Some checks failed
Build and Deploy / Build & Push (push) Failing after 22s
Visual overhaul: - Warmer color system with amber accent for Today, better text hierarchy - Row hover highlighting, sticky column shadow on horizontal scroll - Closed cells replaced with dot (·) instead of "Closed" text - Regional grouping (Northeast/Southeast/Midwest/Texas & South/West) - Two-row header with park count badge and WeekNav on separate lines - Amber "Today" button in WeekNav when off current week - Mobile card layout (< 1024px) with 7-day grid per park; table on desktop - Skeleton loading state via app/loading.tsx Park detail pages (/park/[id]): - Month calendar view with ← → navigation via ?month= param - Live ride status fetched from Six Flags API (cached 1h) - Ride hours only shown when they differ from park operating hours - Fallback to nearest upcoming open day when today is dropped by API, including cross-month fallback for end-of-month edge case Data layer: - Park type gains region field; parks.ts exports groupByRegion() - db.ts gains getParkMonthData() for single-park month queries - sixflags.ts gains scrapeRidesForDay() returning RidesFetchResult with rides, dataDate, isExact, and parkHoursLabel Removed: CalendarGrid.tsx, MonthNav.tsx (dead code) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
36
lib/db.ts
36
lib/db.ts
@@ -99,6 +99,42 @@ export function getDateRange(
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scraped DayData for a single park for an entire month.
|
||||
* Shape: { 'YYYY-MM-DD': DayData }
|
||||
*/
|
||||
export function getParkMonthData(
|
||||
db: Database.Database,
|
||||
parkId: string,
|
||||
year: number,
|
||||
month: number,
|
||||
): Record<string, DayData> {
|
||||
const prefix = `${year}-${String(month).padStart(2, "0")}`;
|
||||
const rows = db
|
||||
.prepare(
|
||||
`SELECT date, is_open, hours_label, special_type
|
||||
FROM park_days
|
||||
WHERE park_id = ? AND date LIKE ? || '-%'
|
||||
ORDER BY date`
|
||||
)
|
||||
.all(parkId, prefix) as {
|
||||
date: string;
|
||||
is_open: number;
|
||||
hours_label: string | null;
|
||||
special_type: string | null;
|
||||
}[];
|
||||
|
||||
const result: Record<string, DayData> = {};
|
||||
for (const row of rows) {
|
||||
result[row.date] = {
|
||||
isOpen: row.is_open === 1,
|
||||
hoursLabel: row.hours_label,
|
||||
specialType: row.special_type,
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Returns a map of parkId → boolean[] (index 0 = day 1) for a given month. */
|
||||
export function getMonthCalendar(
|
||||
db: Database.Database,
|
||||
|
||||
Reference in New Issue
Block a user