'use client' import { useCallback } from 'react'; import { useMapContext } from '../context'; import { useMapControl } from './useMapControl'; import type { MarkerActions, MarkerData } from '../types' let markerId = 0 const generateMarkerId = () => `marker-${++markerId}` /** * Hook for marker management * Provides methods to add, remove, update markers */ export function useMarkers(): MarkerActions { const { markers, setMarkers } = useMapContext() const { fitBounds } = useMapControl() const addMarker = useCallback( (marker: Omit): string => { const id = generateMarkerId() setMarkers((prev) => [...prev, { ...marker, id }]) return id }, [setMarkers] ) const removeMarker = useCallback( (id: string) => { setMarkers((prev) => prev.filter((m) => m.id !== id)) }, [setMarkers] ) const updateMarker = useCallback( (id: string, updates: Partial>) => { setMarkers((prev) => prev.map((m) => (m.id === id ? { ...m, ...updates } : m)) ) }, [setMarkers] ) const clearMarkers = useCallback(() => { setMarkers([]) }, [setMarkers]) const fitToMarkers = useCallback( // Accepts a plain `padding` number (back-compat) or an options object. // `maxZoom` (default 16) stops a single / tightly-clustered set from // zooming all the way in and losing surrounding context. (paddingOrOpts: number | { padding?: number; maxZoom?: number } = 50) => { if (markers.length === 0) return const { padding = 50, maxZoom = 16 } = typeof paddingOrOpts === 'number' ? { padding: paddingOrOpts } : paddingOrOpts if (markers.length === 1) { const marker = markers[0] fitBounds( [ [marker.longitude - 0.01, marker.latitude - 0.01], [marker.longitude + 0.01, marker.latitude + 0.01], ], { padding, maxZoom } ) return } const lngs = markers.map((m) => m.longitude) const lats = markers.map((m) => m.latitude) const bounds: [[number, number], [number, number]] = [ [Math.min(...lngs), Math.min(...lats)], [Math.max(...lngs), Math.max(...lats)], ] fitBounds(bounds, { padding, maxZoom }) }, [markers, fitBounds] ) return { markers, addMarker, removeMarker, updateMarker, clearMarkers, fitToMarkers, } }