Skip to content

feat: day-tab filter for multi-day event schedules (#542 PR-3)#636

Merged
BreakableHoodie merged 1 commit into
mainfrom
feat/542-day-tabs
Jul 18, 2026
Merged

feat: day-tab filter for multi-day event schedules (#542 PR-3)#636
BreakableHoodie merged 1 commit into
mainfrom
feat/542-day-tabs

Conversation

@BreakableHoodie

Copy link
Copy Markdown
Owner

Summary

Multi-day events get a day-tab segmented control on both the full schedule (ScheduleView) and the fan's personal schedule (MySchedule). Selecting a day filters the list to that day's sets (Dre's confirmed choice over scroll-anchor), and ?day=N deep-links straight to a day's lineup — shareable, back-button-sane. Directly serves Buddies Fest 2 (Aug 7–9), the upcoming multi-day event.

Closes #542 (final sibling PR — PR-1 staleness #604, PR-2 day-aware ICS, PR-4 subEvent JSON-LD #634)

What changed

File Change
frontend/src/utils/festivalDays.js resolveActiveFestivalDay() — precedence ?day=N → today's festival day if in-progress → day 1, using the existing 6 AM after-midnight convention (untouched)
frontend/src/hooks/useFestivalDayFilter.js (new) Wraps useSearchParams + the resolver; syncs the active day to the URL
frontend/src/components/ui/DayTabs.jsx (new) Shared tablist: roving tabindex, arrow/Home/End keys, aria-selected, ≥44px targets, theme tokens only
frontend/src/components/{ScheduleView,MySchedule}.jsx Pre-filter bands to the active day before their existing pipelines (venue/genre/time filters, conflict detection, Copy all operate on the active day); render DayTabs only when festivalDays.length > 1
frontend/src/App.jsx Threads an authoritative festivalDays (from the full lineup) into MySchedule so a Day-2-only selection isn't mislabelled "Day 1"

Deliberate scope calls (flagged, not oversights): Share Schedule + Lock-In Lineup read the unfiltered band list so a shared route covers the whole festival regardless of active tab; the existing DayDivider (carries #569 doors time) is kept alongside the tabs; single-day events render no tabs (never-show-"Day 1" rule, byte-unchanged).

Security / correctness notes

None — client-side view filtering + a URL param. Schedule storage logic untouched; the filter is layered on top.

Verification

  • Tests: frontend 561 pass (53 files), incl. new coverage across festivalDays / ScheduleView / MySchedule
  • ESLint: 0 errors · Format check: clean · Build: green
  • Single-day regression: no tabs rendered (gated on festivalDays.length > 1 at both call sites — verified)
  • validate:openapi: n/a — frontend only
  • Manual smoke: recommend a click-through on Buddies Fest 2 post-deploy (tab filter, ?day=2 deep-link, keyboard nav)

Built by Sonny · Reviewed by Theo · 🤖 Claude Code

Multi-day events (Buddies Fest 2, Aug 7-9) get a day-tab segmented
control on the schedule (ScheduleView) and personal schedule
(MySchedule): selecting a day filters the list to that day's sets,
and ?day=N deep-links straight to it. Active day resolves ?day=N →
today's festival day if the event is in progress → day 1, using the
existing 6 AM after-midnight convention. Single-day events render no
tabs at all (never-show-"Day 1" rule).

Share Schedule and Lock-In Lineup deliberately read the unfiltered
band list so a shared route always covers the whole festival
regardless of the active tab. Shared DayTabs component is a proper
tablist (roving tabindex, arrow/Home/End keys, aria-selected, 44px
targets, theme tokens).

Closes #542

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BreakableHoodie BreakableHoodie added enhancement New feature or request priority:p3 Lower priority labels Jul 18, 2026
Copilot AI review requested due to automatic review settings July 18, 2026 18:03
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@BreakableHoodie
BreakableHoodie merged commit 86f3b46 into main Jul 18, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority:p3 Lower priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(multiday): Phase 2 polish — day tabs, per-day SEO/ICS/hours [tracking]

2 participants