feat(schedule): group list view by festival day with sticky header#250
feat(schedule): group list view by festival day with sticky header#250chiptus wants to merge 7 commits into
Conversation
Sets are now grouped into per-day sections (day boundary computed in the festival timezone) instead of a flat per-time-slot list, so each day's sticky header docks below the fixed top bar and stays stuck for the whole day instead of unsticking after one screen. The standalone filters row is removed; the Filters trigger and vote chips now live in the sticky day header. Closes #235 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Updates the Schedule “List” tab to render sets grouped by festival day (using the festival timezone) so each day is a continuous section with a sticky day header that also hosts the Filters trigger.
Changes:
- Group list schedule rendering into per-day sections and introduce a dedicated sticky day header component per festival day.
- Move the Filters trigger into the sticky day header (removing the standalone List-view filters row) and improve the trigger’s accessible label.
- Add/adjust Playwright e2e coverage for sticky day header behavior and opening the filter sheet from the day header.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/e2e/schedule-list-day-header.spec.ts | Adds new e2e coverage for sticky day header behavior and opening filters from the header. |
| tests/e2e/schedule-filter-sheet.spec.ts | Updates filter-sheet e2e to use the first matching trigger and reflects the new List header location. |
| src/pages/EditionView/tabs/ScheduleTab/ScheduleFilterSheet.tsx | Adds an aria-label to the filter trigger so it has an accessible name (including active count). |
| src/pages/EditionView/tabs/ScheduleTab/list/TimeSlotGroup.tsx | Removes the per-slot sticky date header so slots can live under a single per-day sticky header. |
| src/pages/EditionView/tabs/ScheduleTab/list/ListTab.tsx | Removes the standalone List filters row and renders only the List schedule content. |
| src/pages/EditionView/tabs/ScheduleTab/list/ListSchedule.tsx | Computes day-grouped time slots (by festival day key) and renders per-day groups. |
| src/pages/EditionView/tabs/ScheduleTab/list/ListDayGroup.tsx | New component: renders a per-day sticky header (with Filters trigger) and that day’s time slots. |
Comments suppressed due to low confidence (1)
tests/e2e/schedule-list-day-header.spec.ts:56
- Same potential flake here: strict equality on
getBoundingClientRect().topcan fail due to subpixel rounding differences between elements/scroll positions.
const topAfter = await secondHeader.evaluate(
(el) => el.getBoundingClientRect().top,
);
expect(topAfter).toBe(topBefore);
});
…y test Address Copilot review on PR #250: show the Filters trigger in the List view's empty state so a filter combination that yields zero sets doesn't strand the user without a way to clear/adjust it, and use a tolerance instead of strict pixel equality for the sticky-header e2e assertions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
Address review feedback on PR #250: the per-day section now exposes an accessible name via aria-label (queryable as a region) and the sticky header uses a semantic <header> element instead of a bare div, so tests and assistive tech no longer depend on data-testid to find them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
Address review feedback on PR #250. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
…stSchedule Address review feedback on PR #250: ScheduleTabList had become a pure Middle Man once the standalone filters row moved into the day header, so the list route now points at ListSchedule directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
Address review feedback on PR #250: the mobile and desktop blocks in TimeSlotGroup were near-identical, explained only by comments. A single responsive grid removes the duplication and the need for either comment. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
…ests Address review feedback on PR #250: the seeded "test" edition always has schedule_reveal_level=full and three festival days of sets, so the "not revealed" / "not enough days" skip guards were dead weight — replaced with a direct assertion that fails loudly instead. Filter-trigger lookups now go through the accessible role/name instead of data-testid. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4xgXYPJMoUYDAb6UUn4wj
Groups the List view's sets into per-day sections (day boundary computed in the festival timezone) so the day header sticks for the whole day instead of unsticking after one screen; the standalone filters row is removed and the Filters trigger now lives in the sticky day header.
Closes #235
Verification
pnpm run typecheck,pnpm run lint, andpnpm testall pass.Generated by Claude Code