The edit form now fetches approved time-off requests and excludes
volunteers whose time off overlaps the shift date from the
selectable list. Unavailable volunteers are shown below the picker
in a "On approved time off" note.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The edit form now loads the volunteer list and groups them by
operational role. Template role requirements are shown with a
count indicator (selected/required) that turns green when filled.
Volunteers are selected via checkboxes instead of typing IDs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- /schedules?year=2026&month=4 for the shifts view
- /schedules/templates for the templates view
- Month navigation updates search params via useNavigate
- Reloading or sharing a URL restores the exact view
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace bare http.FileServer with an SPA-aware handler that tries to
serve the requested static file and falls back to index.html when
the path doesn't match a real file. This lets React Router handle
client-side routes like /schedules on page reload.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Initialize slice helpers with make() instead of var declaration so
empty results serialize as [] instead of null in JSON, fixing the
frontend TypeError on the schedules page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the database has no users, the UI redirects to /setup and prompts
for creation of the first admin account. The setup endpoints are
self-disabling — once any user exists, POST /setup/admin returns 403
and the frontend redirects /setup back to /login. The backend uses an
atomic transaction to prevent race conditions on concurrent requests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace removed Schedule type and api.listSchedules() with
ShiftInstance and api.listShifts() after the schedule rewrite.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>