'use client'; import { MapContainer, TileLayer, Marker, Popup, Tooltip, useMapEvents } from "react-leaflet"; import Link from "next/link"; import type { SensorResponse } from "@/lib/types"; import L from 'leaflet'; // Fix Leaflet default icon path broken by webpack if (typeof window !== 'undefined') { delete (L.Icon.Default.prototype as any)._getIconUrl; L.Icon.Default.mergeOptions({ iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-icon-2x.png', iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-icon.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/images/marker-shadow.png', }); } const createNeonIcon = () => { return new L.DivIcon({ className: "bg-transparent", html: `
`, iconSize: [24, 24], iconAnchor: [12, 12], popupAnchor: [0, -12], }); }; const createPendingIcon = () => { return new L.DivIcon({ className: "bg-transparent", html: `
`, iconSize: [32, 32], iconAnchor: [16, 16], popupAnchor: [0, -16], }); }; interface ClickHandlerProps { onMapClick?: (lat: number, lng: number) => void; } function MapClickHandler({ onMapClick }: ClickHandlerProps) { useMapEvents({ click(e) { if (onMapClick) { onMapClick(e.latlng.lat, e.latlng.lng); } }, }); return null; } interface GlobalMapProps { sensors: SensorResponse[]; onMapClick?: (lat: number, lng: number) => void; pendingLatLng?: { lat: number; lng: number } | null; } export function GlobalMap({ sensors, onMapClick, pendingLatLng }: GlobalMapProps) { const neonIcon = createNeonIcon(); const pendingIcon = createPendingIcon(); return ( {sensors?.map((sensor) => (
{sensor.locationName || sensor.sensorId}

{sensor.locationName || "Unknown Sector"}

NODE ID: {sensor.sensorId}
LAT: {sensor.latitude} | LNG: {sensor.longitude}

Access Telemetry
))} {/* Pending marker from map click */} {pendingLatLng && (
DEPLOY HERE
)}
); }