import { useEffect, useRef } from 'react'; import { MapContainer, TileLayer, Marker, Popup, CircleMarker, useMap } from 'react-leaflet'; import L, { type LatLngTuple } from 'leaflet'; import 'leaflet/dist/leaflet.css'; export interface NearbyMapPin { id: string; name: string; cityLabel: string | null; latitude: number; longitude: number; } interface NearbyBreweryMapProps { pins: NearbyMapPin[]; selectedId: string | null; onSelect: (id: string) => void; userLocation: LatLngTuple | null; userLocationLabel: string; } // Leaflet paints markers as SVG attributes, which can't reference CSS custom // properties the way class names can - resolve the current theme's colors instead. const resolveThemeColor = (variable: string, fallback: string) => { if (typeof document === 'undefined') return fallback; const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim(); return value || fallback; }; const pinIcon = (active: boolean) => L.divIcon({ className: '', html: ``, iconSize: [18, 18], iconAnchor: [9, 9], }); const FitAndFocus = ({ pins, userLocation, selectedId, }: { pins: NearbyMapPin[]; userLocation: LatLngTuple | null; selectedId: string | null; }) => { const map = useMap(); const didInitialFit = useRef(false); useEffect(() => { if (didInitialFit.current) return; const points: LatLngTuple[] = pins.map((pin) => [pin.latitude, pin.longitude]); if (userLocation) points.push(userLocation); if (points.length > 0) { map.fitBounds(points, { padding: [40, 40], animate: false }); didInitialFit.current = true; } const timeout = setTimeout(() => map.invalidateSize(), 200); return () => clearTimeout(timeout); }, [map, pins, userLocation]); useEffect(() => { if (!didInitialFit.current || !selectedId) return; const pin = pins.find((p) => p.id === selectedId); if (!pin) return; map.flyTo([pin.latitude, pin.longitude], Math.max(map.getZoom(), 11), { duration: 0.8 }); }, [map, pins, selectedId]); return null; }; const NearbyBreweryMap = ({ pins, selectedId, onSelect, userLocation, userLocationLabel, }: NearbyBreweryMapProps) => ( {userLocation && ( You are here — {userLocationLabel} )} {pins.map((pin) => ( onSelect(pin.id) }} >

{pin.name}

{pin.cityLabel && (

{pin.cityLabel}

)} View brewery →
))}
); export default NearbyBreweryMap;