Profile refactor, dispatch vocabulary presets, and UI cleanup - #19
Merged
Conversation
Strips the profile page down to essentials (info, security, preferences) and adds an admin section for managing event certifications and other admins, backed by a new isAdmin flag on the user doc. Adds a proper reduced-motion preference (previously only OS-driven), a collapsible password-change form, a redesigned edit-profile page, and a self-service "forgot password" flow using each backend's built-in email reset link so locked-out users don't need admin intervention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ion Venues Admins can now delete a user's venues, events, dispatch logs, and profile doc from Profile > Admin > Manage Administrator Access (fully removes the account on PocketBase; on Firebase the Auth record itself has to be removed separately via the console, since the client SDK can't delete another user's auth account without a privileged server credential). Also adds Organization Venues: an admin can mark venues they own as visible to every user on the instance, instead of sharing them with people one at a time. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ation context Lays the groundwork for customizable dispatch terminology: a canonical term registry keyed by the exact English strings already used internally (so the default preset is an identity mapping with zero data migration), CrowdCAD Default and CrowdCAD French built-in presets, and a DispatchVocabularyProvider context exposing t(key) for render-site translation. No wiring into the dispatch UI yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ed forks Adds UserDoc.dispatchVocabularyPresetId, a dispatchVocabularyPresets collection service (list/create, following the same flat/unfiltered query pattern as org venues so custom presets are visible to every signed-in user), and useDispatchVocabulary to tie it together with a localStorage fallback for lite/unauthenticated mode. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New card in Preferences lets a user pick a dispatch vocabulary preset (built-in or a shared custom one) and browse/edit every term grouped by category. Editing always forks a newly-named, org-shared preset rather than mutating the one currently selected — verified end-to-end in the browser (preset switch, term editor, fork-and-save all round-trip correctly). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wraps the dispatch route in DispatchVocabularyProvider and switches its own render-site labels (tab titles, section headers, add/empty-state copy) to t() lookups, leaving every status comparison and stored value untouched. Verified in-browser with a live lite event: switching to CrowdCAD French correctly renders "Équipes", "Appels totaux", "Ajouter un appel", etc. Also adds a few chrome terms (No teams available, Show/Hide Resolved Calls) discovered while wiring. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…details
Table headers (trackingtablebase.tsx), status chips/dropdowns, add-team/
supervisor/equipment submenus, log/duplicate/priority/delete actions, and
the expanded call details panel now render through t() at each display
site. Status dropdown keys stay on the canonical English value (key={status})
so handleTeamStatusChange and all resolved-status comparisons are untouched
— only the rendered label translates. Adds a handful of terms discovered
while wiring (No available teams/supervisors/equipment, Notes, Add notes,
No log entries, Log for Call, the priority-call banner).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Status selects, location autocomplete, Refresh Post/Edit/Delete menu items, member list header, activity log placeholder, and the (Lead) display suffix in both teamcard.tsx and its condensed variant now render through t(). The (Lead) storage marker used by member-string parsing is left untouched; only the formatted display label is translated. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Clinic status dropdown (In Clinic/Transported/AMA/Discharged), Walkup fallback, primary team, notes/log panels, and the No clinic calls empty state now render through t(). Also catches No clinic calls in page.tsx, missed during the earlier page-shell pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Equipment status/location controls, Mark Ready/Delete menu, staging/
delivery/notes labels, the clinic walkup modal, add/edit team and
supervisor modals, and the quick-call modal now render through t().
Team-location fallbacks ('Unknown', 'Clinic') translate via the same
identity-fallback t() call used elsewhere, so custom venue post names
pass through untouched.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The desktop Show Resolved Calls / Show Resolved Clinic Calls toggle buttons live inside calltracking.tsx/clinictracking.tsx themselves (not page.tsx, where only the mobile variants were wired) and stayed in English under the French preset — fixed in all three locations. Also wires the dispatch-only navbar items: Venue Map, Posting Schedule, End Event, and Venues in appnavbar.tsx, plus the lite dispatch navbar's Posting Schedule/End Event/Clear Event/Export Summary. Both navbars render outside DispatchPage's provider tree (they're siblings in AppShell/LiteLayout, not descendants), so each calls useDispatchVocabulary() directly rather than relying on context. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a "New preset" flow (pick a base preset + name, forks and switches to it immediately so the term editor can be opened to customize) and a "Your presets" list that surfaces only presets the current user created, each with a delete action. Built-in presets and presets created by other org members are never deletable — deletePreset() in useDispatchVocabulary enforces createdBy ownership before touching Firestore/localStorage, and resets the caller back to CrowdCAD Default if they delete their own currently-active preset. Also adds the disclaimer that the preference is per-user (not shared across dispatchers) and that logs always stay English. Verified live: creating "My French Variant" from the CrowdCAD French template correctly forked and activated it, and it appeared in Your presets with a delete control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Root-caused the "navbar still shows English" report: AppNavbar/LiteNavbar live in the persistent root layout and never remount on client-side navigation, so their one-time mount fetch never re-ran after the user changed their preset elsewhere in the same session — they stayed frozen at whatever was active on first load. Adds a small pub/sub bus (changeBus.ts) that every useDispatchVocabulary() instance broadcasts to and listens on, so all mounted consumers (navbar included) update immediately on select/create/update/delete, no refetch required. Verified live end-to-end on a real cloud event: switching to CrowdCAD French now updates the navbar (Plan du site / Horaire des postes / Terminer l'événement / Sites) instantly on client-side navigation. Also, per feedback: - Editing a preset you created now saves in place (updatePreset); editing any other preset (built-in or another org member's) still forks a new one — verified live, including a reload to confirm the in-place write persisted server-side. - "New preset" now offers a Blank template (empty terms map) alongside existing presets to start from — verified live. - Replaced the Select dropdown + separate "Your presets" list with a single row-based table: each row has an active indicator/selector, an Edit button (opens the term editor scoped to that preset), and a Trash button restricted to presets the user owns. The term editor's scroll container now uses the app's existing minimal-scrollbar utility instead of the default browser scrollbar. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t select - Add max-height + minimal-scrollbar to org venues, users, and venue selection lists so they scroll instead of growing unbounded - Remove the selected-item background behind the "Based on" preset checkmark and move its label outside the input box
…delete-account input ring - Apply minimal-scrollbar + max-height to the per-venue events list (mobile card list and desktop table) on the venue selection page - Remove the focus ring/outline on the Delete Account password input
- Shrink call-row team chips from h-9 to h-8 so the row height settles on the same min-height floor as clinic rows instead of exceeding it - Drop redundant width/alignment classes on the call row's action-menu cell and button so it matches the clinic row's simpler structure
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
Test plan
tsc --noEmitpasses