frontend: fix map stacking + honest infra error states
From a live review of drb.cusano.net. MapView.tsx / globals.css: - The Leaflet map painted above the sticky Nav (z-40) and modal overlays, so on Live the account dropdown opened *behind* the map. Pin .leaflet-container to its own stacking context (position:relative; z-index:0) — keeps Leaflet's internal pane order, drops the whole map below app chrome. The map's own overlay UI (legend, rail, clock, fit-all) is outside .leaflet-container and unaffected. Chosen over raising Nav's z-index, which would float the sticky header over modal backdrops on ~7 pages. - Basemap: the "Dark" tile URL is already CARTO's keyless dark raster (so a prod "API KEY REQUIRED" watermark is a stale build or CARTO rate-limiting the origin, not this code). Add NEXT_PUBLIC_MAP_TILE_URL as a build-time override so a keyed style drops in without a code change; add the OSM attribution the keyless CARTO tiles require. incidents/page.tsx, alerts/page.tsx: - Both dumped raw Firestore "requires an index / PERMISSION_DENIED" strings (with a console.firebase URL) straight into the UI when the composite indexes aren't deployed (server-26 #13/#51). Collapse those known infra failures to a plain sentence; any other error passes through verbatim so a real bug still shows. alerts also now surfaces the events-query error at all — it was swallowed, showing a false "No alerts triggered yet." on a public-safety screen. onboarding/page.tsx: stale comment (/dashboard -> "/"). Untypechecked (no node/npm locally); presentational only — one string helper, one added error branch, a CSS rule, two tile-URL constants, a comment. next build in deploy.yml gates it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b430cf32f2
commit
968134f8ee
@@ -28,6 +28,17 @@ const FILTER_THRESHOLD: Record<SeverityFilter, number> = { all: -1, minor: 1, mo
|
||||
|
||||
type SortMode = "recent" | "severity";
|
||||
|
||||
// The Firestore client surfaces a missing composite index or an undeployed
|
||||
// ruleset as a raw multi-line string with a console URL in it — not something
|
||||
// to put in front of an operator. Collapse the known infra failures to a plain
|
||||
// line; pass anything else straight through so a real bug still shows.
|
||||
function friendlyIncidentsError(raw: string): string {
|
||||
if (/requires an index|PERMISSION_DENIED|Missing or insufficient permissions|failed-precondition/i.test(raw)) {
|
||||
return "Couldn't load incidents — the incidents database index isn't deployed on the server yet. This is a one-time backend deploy step (server-26 #13 / #51), not a problem with your data.";
|
||||
}
|
||||
return `Couldn't load incidents: ${raw}`;
|
||||
}
|
||||
|
||||
function fmtTime(iso: string) {
|
||||
try { return new Date(iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }); } catch { return iso; }
|
||||
}
|
||||
@@ -286,7 +297,7 @@ export default function IncidentsPage() {
|
||||
recorded yet" over the top of it told the operator the radio was
|
||||
quiet when the page had simply failed to load — server-26#13. */}
|
||||
{filtered.length === 0 && error && (
|
||||
<ErrorBanner message={`Couldn't load incidents: ${error}`} />
|
||||
<ErrorBanner message={friendlyIncidentsError(error)} />
|
||||
)}
|
||||
|
||||
{filtered.length === 0 && !error && (
|
||||
|
||||
Reference in New Issue
Block a user