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;
}
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;