import { useMap } from "@vis.gl/react-google-maps"; import { useEffect, useRef, useState } from "react"; import IGMapPoi from "../../types/IGMapPoi"; import MapMarker from "./MapMarker"; import { MarkerClusterer, DefaultRenderer, Cluster, Marker, } from "@googlemaps/markerclusterer"; class CustomMarkerRenderer extends DefaultRenderer { render({ count, position, }: Cluster): google.maps.marker.AdvancedMarkerElement { const svgElement = document.createElement("div"); svgElement.innerHTML = `
${count}
`; const marker = new google.maps.marker.AdvancedMarkerElement({ position, content: svgElement, zIndex: Math.max(1000, count), }); return marker; } } export default function GoogleMapMarkers({ data, filter, }: { data: IGMapPoi[]; filter: string; }) { const map = useMap(); const [markers, setMarkers] = useState<{ [key: string]: Marker }>({}); const [selectedMarker, setSelectedMarker] = useState(null); const clusterer = useRef(null); useEffect(() => { if (!map) return; if (!clusterer.current) { clusterer.current = new MarkerClusterer({ map: map, renderer: new CustomMarkerRenderer(), }); } }, [map]); useEffect(() => { clusterer.current?.clearMarkers(); clusterer.current?.addMarkers(Object.values(markers)); }, [markers]); const setMarkerRef = (marker: Marker | null, key: string) => { if (marker && markers[key]) return; if (!marker && !markers[key]) return; setMarkers((prev) => { if (prev[key] === marker) return prev; if (marker) { return { ...prev, [key]: marker }; } else { const newMarkers = { ...prev }; delete newMarkers[key]; return newMarkers; } }); }; return ( <> {data.map( (poi: IGMapPoi, index: number) => (filter === poi.type || filter === "All") && ( {poi.customMarker} ) )} ); }