import Link from "next/link"; import type { DayData } from "@/lib/db"; interface ParkMonthCalendarProps { parkId: string; year: number; month: number; // 1-indexed monthData: Record; // 'YYYY-MM-DD' → DayData today: string; // YYYY-MM-DD } const DOW_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const MONTH_NAMES = [ "January","February","March","April","May","June", "July","August","September","October","November","December", ]; function prevMonth(year: number, month: number) { if (month === 1) return { year: year - 1, month: 12 }; return { year, month: month - 1 }; } function nextMonth(year: number, month: number) { if (month === 12) return { year: year + 1, month: 1 }; return { year, month: month + 1 }; } function daysInMonth(year: number, month: number): number { return new Date(year, month, 0).getDate(); } export function ParkMonthCalendar({ parkId, year, month, monthData, today }: ParkMonthCalendarProps) { const firstDow = new Date(year, month - 1, 1).getDay(); // 0=Sun const totalDays = daysInMonth(year, month); const prev = prevMonth(year, month); const next = nextMonth(year, month); const prevParam = `${prev.year}-${String(prev.month).padStart(2, "0")}`; const nextParam = `${next.year}-${String(next.month).padStart(2, "0")}`; // Build cells: leading empty + actual days const cells: Array<{ day: number | null; iso: string | null }> = []; for (let i = 0; i < firstDow; i++) cells.push({ day: null, iso: null }); for (let d = 1; d <= totalDays; d++) { const iso = `${year}-${String(month).padStart(2, "0")}-${String(d).padStart(2, "0")}`; cells.push({ day: d, iso }); } // Pad to complete last row while (cells.length % 7 !== 0) cells.push({ day: null, iso: null }); const weeks: typeof cells[] = []; for (let i = 0; i < cells.length; i += 7) { weeks.push(cells.slice(i, i + 7)); } return (
{/* Month nav */}
{MONTH_NAMES[month - 1]} {year}
{/* Calendar grid */}
{/* DOW header */}
{DOW_LABELS.map((d, i) => (
{d}
))}
{/* Weeks */} {weeks.map((week, wi) => (
{week.map((cell, ci) => { if (!cell.day || !cell.iso) { return (
); } const dayData = monthData[cell.iso]; const isToday = cell.iso === today; const isWeekend = ci === 0 || ci === 6; const isOpen = dayData?.isOpen && dayData?.hoursLabel; const isPH = dayData?.specialType === "passholder_preview"; const bg = isToday ? "var(--color-today-bg)" : isWeekend ? "var(--color-weekend-header)" : "transparent"; return (
{/* Date number */} {cell.day} {/* Status */} {!dayData ? ( ) : isPH && isOpen ? (
Passholder
{dayData.hoursLabel}
) : isOpen ? (
{dayData.hoursLabel}
) : ( · )}
); })}
))}
); } const navLinkStyle: React.CSSProperties = { display: "inline-flex", alignItems: "center", justifyContent: "center", padding: "6px 14px", borderRadius: 6, border: "1px solid var(--color-border)", background: "var(--color-surface)", color: "var(--color-text-muted)", fontSize: "1rem", lineHeight: 1, textDecoration: "none", };