import { useEffect, useRef } from 'react'; import { useMap } from 'react-leaflet'; import { useMapInteraction, useMapViewport } from '@/contexts/MapContexts.tsx'; import { useOrganizationSites } from '@/hooks/map/useOrganizationSites.ts'; /** * Component to handle centering map on selected organization * This runs inside MapContainer to access the Leaflet map instance * Optimized to prevent unnecessary updates and infinite loops */ const OrganizationCenterHandler = () => { const map = useMap(); const { selectedOrg } = useMapInteraction(); const { setMapCenter, setZoom } = useMapViewport(); const { orgSitesMap } = useOrganizationSites(selectedOrg ? [selectedOrg] : []); const lastCenteredOrgIdRef = useRef(null); const isCenteringRef = useRef(false); useEffect(() => { if (!selectedOrg) { lastCenteredOrgIdRef.current = null; return; } // Prevent re-centering if we already centered on this org if (lastCenteredOrgIdRef.current === selectedOrg.ID) { return; } // Prevent updates during centering animation if (isCenteringRef.current) { return; } const site = orgSitesMap.get(selectedOrg.ID); if (site) { const position: [number, number] = [site.Latitude, site.Longitude]; const currentCenter = map.getCenter(); const currentZoom = map.getZoom(); // Only center if we're not already close to this position const centerDiff = Math.abs(currentCenter.lat - position[0]) + Math.abs(currentCenter.lng - position[1]); const zoomDiff = Math.abs(currentZoom - 14); if (centerDiff > 0.001 || zoomDiff > 0.5) { isCenteringRef.current = true; lastCenteredOrgIdRef.current = selectedOrg.ID; map.setView(position, 14, { animate: true }); setMapCenter(position); setZoom(14); // Reset flag after animation completes const timeoutId = setTimeout(() => { isCenteringRef.current = false; }, 500); return () => { clearTimeout(timeoutId); }; } } }, [selectedOrg, orgSitesMap, map, setMapCenter, setZoom]); return null; }; export default OrganizationCenterHandler;