feat: tournament events, shifts, and season events - #61
Merged
Conversation
…nk to canonical Event catalog, add start/end times
…active event list
…inks, add TournamentShift and SeasonEvent schemas
…log links and start/end times
…etach with bounds and overlap validation
…under /admin/, keep GET routes public
… catalog links, shifts, season events
…and season-catalog empty state
…or members and invites
…or missing tournaments
…RL-driven tournament fetch
…onfirm-preview modal, rename from 'catalog' to 'default events'
…ad of one top-level banner
…pport filtering by multiple divisions
…ct filter modal, add category filter
… section, switch division and type filters to ButtonGroup, bump filter icon sizes
…ed-change closes, close panel on cancel
…ink save bar in narrow panels
…x select/edit/create-event interactions
…ared usePanelSelection hook
…t filters per user/tournament
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🚅 Deployed to the nexus-pr-61 environment in nexus
|
This was
linked to
issues
Aug 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the old JSON-blob
TournamentEvent.blocks/.categorymodel with real scheduling data — start/end datetimes, a reusable per-tournamentTournamentShiftcatalog, and a link to the canonicalEvent/EventCategorycatalog via a newSeasonEventbulk-load table. Ships the first UI for any of this: an Events tab (read-only table + edit panel) and a Shifts tab (inline-editable table + attach/detach panel) on the tournament events page, which previously had no frontend at all.Also folded in, along the way: a rebuild of the members roster's panel/filter infrastructure (reused directly by the events UI), and tournament-timezone-aware datetime validation.
What changed
Backend — events, shifts, season catalog
TournamentEventrewritten: droppedblocks(JSON) andcategory(string);divisionnow nullable; addedevent_idFK to the canonicalEventcatalog (null = custom event) and required-by-conventionstart_time/end_time— left nullable on the column itself since TDs often create an event before its time is scheduled, but the frontend warns before allowing shift-attach without them.TournamentShift— new per-tournament shift catalog (label,start,end), attached to events viatournament_event_shifts. NamedTournamentShiftrather thanEventShiftto match the existingTournamentEvent/TournamentMembershipnaming convention.end == start, is fine). Delete has no server-side guard — cascades silently, confirmation is frontend-only.(tournament_id, event_id, division)— a canonical event can only be added once per division per tournament; custom events (event_id IS NULL) are unconstrained.SeasonEvent— admin-curated(event_id, year, division, is_active)suggestion list. NewPOST /admin/season-events/CRUD and a bulk-load action that creates oneTournamentEventper activeSeasonEventmatching the tournament's own division list, withnamesnapshotted (not live-linked).seed_season_events_2027.py).manage_eventsgates every events/shifts/bulk-load route, read and write alike — no separate read-only permission.TournamentMembership.assigned_event_id/.scheduledropped outright — dead weight from the old single-assignment model, no migration path kept.timezonecolumn, captured silently from the browser on create; event/shift bounds validation compares against tournament-local time instead of raw UTC, and per-field 409s (start/end outside tournament bounds) surface on the offending input instead of a generic save-bar error.Backend — TournamentSummary
TournamentSummaryschema onGET /tournaments/me/— dropsvolunteer_schema,time_blocks,categories; addsevent_count/volunteer_countcomputed from.events/.memberships. (There's no separateGET /tournaments/list route in this codebase — only/me/and/{id}/— so only/me/needed the change.)GET /tournaments/{id}/unchanged, still returns fullTournamentRead.TournamentPublicas a shared base between the summary and the join-code preview schema.Frontend — events & shifts page
TabStrip(pulled out of the roles-settings tab UI).FilterModal, division/type/category filters); row click docks an edit panel (EventPanel) instead of opening a modal.EventPanel: name/division/type/building/room/floor/volunteers all editable; category shown as fixed text only whenevent_idis set (no category at all for custom events);Comboboxfor canonical-vs-custom event selection; shift picker filtered to shifts that fit inside the event's start/end, selected shifts render as chips.LoadDefaultEventsModal).FloatingSaveBarbatching changes (per-row edit toggle, not per-field autosave); expand panel (ShiftEventsCard) shows/edits which events a shift is attached to — the reverse of the event panel's shift picker.lockedconvention as the rest of settings. Users withoutmanage_eventsdon't see the page at all — no read-only mode.Frontend — also included
DockedPanel,useLayoutPanel) replacing the old modalSidePanel,usePanelSelectionunifying select/edit flow,SelectionBarfor multi-row select,usePersistedFilterfor per-user/per-tournament filter persistence.MassRoleEditor(add/remove roles with diff preview),MembersFilterModal, locked-role display instead of hiding, checklist column animation.FilterModal,FormPopover,Badgedivision/warning variants,Buttonxssize,Popoverflip-above-trigger fix, datetime-local input year clamp.Out of scope
SeasonEventcuration admin UI — bulk-load consumes it, managing the season list itself is not built.