import { useEffect, useRef } from 'react'; import L from 'leaflet'; export default function MapView({ members, groups, sos }) { const elRef = useRef(null); const mapRef = useRef(null); const markersRef = useRef(new Map()); const didFit = useRef(false); useEffect(() => { const map = L.map(elRef.current, { center: [48.8566, 2.3522], zoom: 12 }); L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19, }).addTo(map); mapRef.current = map; return () => map.remove(); }, []); useEffect(() => { const map = mapRef.current; if (!map) return; const sosMembers = new Set(sos.filter((a) => a.state !== 'resolved').map((a) => a.member_id)); const colorOf = (gid) => groups.find((g) => g.id === gid)?.color || '#64748b'; const positioned = members.filter((m) => m.lat != null && m.lng != null); const seen = new Set(); for (const m of positioned) { seen.add(m.id); const isSos = sosMembers.has(m.id); const icon = L.divIcon({ className: 'marker-wrap', html: `
`, iconSize: [16, 16], iconAnchor: [8, 8], }); let mk = markersRef.current.get(m.id); if (!mk) { mk = L.marker([m.lat, m.lng], { icon }).addTo(map); markersRef.current.set(m.id, mk); } else { mk.setLatLng([m.lat, m.lng]); mk.setIcon(icon); } mk.bindPopup( `${m.name}${m.callsign ? ` · ${m.callsign}` : ''}