From bf7fdbd621a168981680a14b9609f641b832c4d6 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Sat, 26 Sep 2026 19:09:21 +0700 Subject: [PATCH] fix(ux): calendar 'Past' opens on the newest month with events The calendar always initialised to the current month, so the Past tab (all events in the past) opened on an empty month. It now anchors to the newest past event, and re-anchors when the tab changes. --- src/components/EventsCalendar.tsx | 21 ++++++++++++++++++--- src/pages/EventsPage.tsx | 5 +++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/components/EventsCalendar.tsx b/src/components/EventsCalendar.tsx index 6f78b98..8b1033c 100644 --- a/src/components/EventsCalendar.tsx +++ b/src/components/EventsCalendar.tsx @@ -29,6 +29,8 @@ interface EventsCalendarProps { goingCounts?: Map; /** Which kinds to display. */ show: 'events' | 'tours'; + /** Unix seconds to open the calendar on (e.g. the newest past event). */ + anchorUnix?: number; } // ─── Date helpers (local time) ──────────────────────────────────────────────── @@ -119,10 +121,23 @@ function formatDayLong(d: Date): string { // ─── Component ──────────────────────────────────────────────────────────────── -export function EventsCalendar({ events, tours, goingCounts, show }: EventsCalendarProps) { +export function EventsCalendar({ events, tours, goingCounts, show, anchorUnix }: EventsCalendarProps) { const today = useMemo(() => startOfDay(new Date()), []); - const [view, setView] = useState(() => new Date(today.getFullYear(), today.getMonth(), 1)); - const [selected, setSelected] = useState(today); + const [view, setView] = useState(() => { + const base = anchorUnix ? new Date(anchorUnix * 1000) : today; + return new Date(base.getFullYear(), base.getMonth(), 1); + }); + const [selected, setSelected] = useState(() => startOfDay(anchorUnix ? new Date(anchorUnix * 1000) : today)); + + // Follow the anchor when the caller changes tabs (React state is only the + // initial value otherwise). Without this, "Past" opened on the CURRENT month + // — which has no past events — so the calendar looked empty. + useEffect(() => { + if (!anchorUnix) return; + const d = new Date(anchorUnix * 1000); + setView(new Date(d.getFullYear(), d.getMonth(), 1)); + setSelected(startOfDay(d)); + }, [anchorUnix]); const accent = show === 'events' ? { dot: 'bg-[#ccff00]', ring: 'ring-[#ccff00]', text: 'text-[#ccff00]', soft: 'bg-[#ccff00]/15', border: 'border-[#ccff00]/40', solid: 'bg-[#ccff00] text-black' } diff --git a/src/pages/EventsPage.tsx b/src/pages/EventsPage.tsx index 1969db5..6ae78b8 100644 --- a/src/pages/EventsPage.tsx +++ b/src/pages/EventsPage.tsx @@ -1195,6 +1195,11 @@ export default function EventsPage() { events={activeTab === 'upcoming' ? filteredEvents.upcoming : filteredEvents.past} tours={[]} goingCounts={goingById} + anchorUnix={ + activeTab === 'past' && filteredEvents.past.length > 0 + ? filteredEvents.past.reduce((m, e) => Math.max(m, e.start), 0) + : undefined + } /> ) )}