Full Changelog: v1.2.0...v1.3.0
Added
-
PocketBase self-hosted backend support — opt-in via
NEXT_PUBLIC_BACKEND=pocketbase, giving LAN/local deployments a no-cloud-account option alongside Firebase. Implemented as a backend-agnostic service layer (src/lib/services—IAuthService/IDbService/IStorageServiceinterfaces withfirebase/andpocketbase/adapters selected byfactory.ts), plusdocker-compose.yml,Dockerfile.pocketbase, andscripts/setup-pocketbase.jsfor collection setup. -
Docker production and development environment (
Dockerfile,Dockerfile.pocketbase,docker-compose.yml). -
GitHub Actions CI/CD pipeline (build, lint, type-check, E2E against both backends) and automated release drafting (
.github/workflows/). -
BDD end-to-end test suite bootstrap (Playwright +
playwright-bdd, Firebase emulators) covering dispatch, event creation, venue management, auth, and profile flows, with a parallel PocketBase E2E configuration. -
Roles are now fetched from the persisted store instead of hardcoded values.
-
Dispatch tracking composition utilities added under
src/components/dispatch/:trackingtablebase.tsx— shared table shell and row rendering structure used by call and clinic tracking.trackingtextentry.tsx— shared inline text entry control used across team, call, and clinic flows.motioncell.tsx— shared animation-aware table cell wrapper for smoother row transitions.
-
Shared animation utilities now drive add/remove and collapse/expand transitions in dispatch cards and tracking rows with reduced-motion support.
-
Foundation refactor: extracted core utilities to
src/lib/for reuse across features:uploadUtils.ts— file upload with exponential backoff retry logic (transient error detection, original error preservation).zoomPanUtils.ts— viewport math utilities (clampScale,clampPanPosition) for consistent zoom/pan behavior.markerUtils.ts— marker detection and placement helpers.
-
Shared React hooks extracted to
src/hooks/for reuse:useZoomPan— manages zoom/pan state and mouse/wheel event handlers for map-based interfaces.useScheduleGeneration— generates shift schedules from event duration and team coverage.useTeamForm— team/supervisor form submission and validation.
-
Shared UI primitives added to
src/components/ui/:map-zoom-controls.tsx— zoom in/out/reset button cluster with accessibility labels (reused across event create and venue management).map-pan-surface.tsx— reusable pan/wheel interaction surface for canvas-based viewers.
-
Event creation flow decomposed into focused section components under
src/components/event-create/:MetadataSection.tsx— event name, date, and venue selection.TeamStaffingSection.tsx— team roster assignment.SupervisorStaffingSection.tsx— supervisor roster assignment.PostingScheduleSection.tsx— shift schedule generation and management.PostsEquipmentSection.tsx— posts and equipment selection with multi-select state.
-
Venue management flow decomposed into focused section components under
src/components/venue-management/:EquipmentManagementSection.tsx— add/edit/delete equipment with stable React keys.LayerControlBar.tsx— layer navigation (previous/next/add/delete) with accessibility labels.MarkerModeToggleButton.tsx— toggle marker placement mode.PendingMarkerDialog.tsx— marker naming dialog.MarkerPlacementInstruction.tsx— on-screen guidance during marker placement.
-
Lite event drafts now persist a
postingScheduleEnabledflag to keep posting schedule behavior consistent between setup and dispatch.
Changed
-
Navbar refresh: increased contrast in light mode, resized/recolored for greater contrast and more compact viewing, and realigned mobile navbar buttons for consistency.
-
Color and opacity constants centralized in config instead of scattered literals.
-
Dispatch right panel now uses browser-style secondary tabs with active counts and a compact header action bar (
Add Callwith keyboard shortcut hint). -
Call and clinic tracking now share aligned table and card visual language, including unified shells, spacing, and row structure.
-
Team cards received a UI refresh: transparent shell, square corners, divider structure, chevron expand indicator, refined map pin sizing, and clearer member/cert formatting.
-
Team card expand/collapse now uses smooth row height and opacity animation with reduced-motion fallbacks.
-
Status color logic is centralized in
src/lib/statusColors.tsand reused across team chips and dispatch status rendering. -
Tracking text fields for chief complaint and location were resized and standardized through shared
TrackingTextEntryusage. -
Status box text area was expanded for better readability of longer status updates.
-
Event creation page (
src/app/(main)/events/[eventId]/create/page.tsx) now uses decomposed section components instead of a monolithic page layout, improving maintainability and testability. -
Venue management page (
src/app/(main)/venues/management/page.client.tsx) now uses decomposed section components and shared map controls instead of page-local implementations. -
Dispatch call tracking page now threads styling through
rowClassNameprop to restore per-status visual differentiation. -
Pan math in
zoomPanUtils.clampPanPositioncorrected to properly clamp against scaled image overflow (fixes off-by-factor error at different zoom levels). -
Lite setup Locations/Equipment add row now uses an attached input + action button style with aligned corner radii and consistent spacing.
-
Teams and Supervisors panel actions in Lite setup now use explicit
Add TeamandAdd Supervisorbuttons. -
Lite dispatch navbar now hides
Posting Schedulewhen posting schedule is disabled in event setup. -
Lite navbar primary links were simplified to focus on Lite routes (
Lite Home,Create). -
Landing page copy and CTA text were refined (
CrowdCAD Litefooter label and Lite subtitle wording), and Lite CTA iconography was simplified. -
Updated
public/logo.svgartwork/viewBox for refined logo rendering.
Fixed
-
Calls tab now visually matches the Clinic tab: shares the
TrackingTableBasescaffold and header/button chrome, andAdd Call(a pill button matching Clinic'sAdd Patient) replaces the old icon-only+. This also fixed a header/body column-count mismatch that had misaligned every column from Status onward. -
Resolved calls (Delivered, NMM, Unable to Locate, Refusal, etc.) no longer show a stale "Pending" team marker just because their team was detached.
-
The call actions (3-dot) menu no longer force-closes on resolved calls when "Show Resolved Calls" is enabled.
-
Team-status dropdown no longer closes spuriously from a stray upstream self-close race in the popover library.
-
Fixed a dispatch dual-mount bug and E2E test-data collisions in seed data, and corrected a nested-dialog Playwright locator.
-
Backend-agnostic bypass logic (
src/app/firebase.ts) now checksNEXT_PUBLIC_BACKEND === 'pocketbase'explicitly rather than inferring it from other env vars, so the app never silently falls back to the wrong backend. -
Profile edit no longer passes
photoURLtoupdateProfile()in PocketBase mode, where the adapter doesn't support it. -
E2E seed-db
bulkCreate()document IDs no longer collide across chunks (ID now incorporates chunk index and item index). -
CI workflow
contents: writepermission scoped to the publish-report job instead of top-level. -
Repaired a broken PocketBase client initialization path and hardcoded CI E2E test credentials.
-
Resolved-row action menus now close correctly when rows are resolved and hidden, preventing orphaned dropdown menus.
-
Removed ghost/shadow rendering artifact in tracking text entry fields while scrolling.
-
Upload retry logic now only retries on transient Firebase Storage errors (
storage/retry-limit-exceeded,storage/unknown) to avoid masking real failures, and preserves original error for diagnostics. -
Removed initial navbar mount flicker/layout shift on page reload by rendering the main app navbar in the initial render path instead of client-only lazy loading.
-
Equipment list now uses stable React keys (
item.id) instead of array indices to prevent component state loss on edit/delete operations.