'use client'; import dynamic from 'next/dynamic'; import { useMemo, useState } from 'react'; import { LevelLegend } from '@/components/ui/primitives'; import { useLive } from '@/lib/live'; import type { Country, Front, Incident, LatencyPair, Probe, Region } from '@/lib/types'; import { ModeSelector } from './ModeSelector'; import { type MapMode } from './modes'; const WorldMap = dynamic(() => import('./WorldMap').then((m) => m.WorldMap), { ssr: false, loading: () =>
Loading map…
, }); export interface MapData { regions: Region[] | null; countries: Country[] | null; probes: Probe[] | null; fronts: Front[] | null; incidents: Incident[] | null; matrix: LatencyPair[] | null; } /** Client island: the map itself is lazy-loaded (no SSR); live slices override the SSR data. */ export function MapIsland({ initial, height = 'h-[300px] sm:h-[420px] lg:h-[520px]', initialMode = 'pressure' }: { initial: MapData; height?: string; initialMode?: MapMode }) { const [mode, setMode] = useState(initialMode); const liveRegions = useLive((s) => s.regions); const liveFronts = useLive((s) => s.fronts); const liveIncidents = useLive((s) => s.incidents); const liveCountries = useLive((s) => s.countries); // Memoised so the map's data effect only re-runs when a real regional update arrived. const countries = useMemo(() => { if (!initial.countries) return null; if (!liveCountries) return initial.countries; const byCc = new Map(liveCountries.map((x) => [x.cc, x])); return initial.countries.map((c) => { const u = byCc.get(c.cc); return u ? { ...c, pressure: u.pressure, level: u.level, delta_1h: u.delta_1h } : c; }); }, [initial.countries, liveCountries]); return (
{mode === 'probes' ? 'Arc thickness = |z| of the inter-region latency matrix' : mode === 'incidents' ? 'Markers = incidents with a geographic scope' : 'Countries coloured only where we hold measurements'}
); }