"use client"; import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet"; import L from "leaflet"; import type { NodeRecord, CallRecord, IncidentRecord } from "@/lib/types"; // Fix Leaflet default icon paths broken by webpack delete (L.Icon.Default.prototype as unknown as Record)._getIconUrl; L.Icon.Default.mergeOptions({ iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png", iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png", shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png", }); const nodeIcon = (status: string) => L.divIcon({ className: "", html: `
`, iconSize: [14, 14], iconAnchor: [7, 7], }); const INCIDENT_COLORS: Record = { fire: "#ef4444", police: "#3b82f6", ems: "#eab308", accident: "#f97316", other: "#6b7280", }; const incidentIcon = (type: string | null) => { const color = INCIDENT_COLORS[type ?? "other"] ?? INCIDENT_COLORS.other; return L.divIcon({ className: "", html: `
!
`, iconSize: [16, 16], iconAnchor: [8, 8], }); }; interface Props { nodes: NodeRecord[]; activeCalls: CallRecord[]; incidents?: IncidentRecord[]; } export default function MapView({ nodes, activeCalls, incidents = [] }: Props) { const activeByNode = Object.fromEntries( activeCalls.map((c) => [c.node_id, c]) ); // Only show incidents that have coordinates const mappableIncidents = incidents.filter( (i) => i.location && i.location.lat != null && i.location.lng != null ); const center: [number, number] = nodes.length > 0 ? [nodes[0].lat, nodes[0].lon] : [39.5, -98.35]; return ( 0 ? 10 : 4} className="w-full h-full rounded-lg" style={{ background: "#111827" }} > {/* Node markers */} {nodes.map((node) => (

{node.name}

{node.node_id}

{node.status}

{activeByNode[node.node_id] && (

● TG {activeByNode[node.node_id].talkgroup_id ?? "—"}{" "} {activeByNode[node.node_id].talkgroup_name}

)}
))} {/* Incident markers */} {mappableIncidents.map((inc) => (

{inc.title ?? "Incident"}

{inc.type ?? "other"}

{inc.status}

{inc.call_ids.length} call{inc.call_ids.length !== 1 ? "s" : ""}

{inc.summary &&

{inc.summary}

}
))}
); }