import React, {FC, ReactElement, useState, useEffect, useRef} from 'react'; export const determineAddressFromLocation = async (location: google.maps.LatLng | google.maps.LatLngLiteral): Promise => { const geocoder = new google.maps.Geocoder(); return new Promise(resolve => { geocoder.geocode({location}, results => resolve(results?.[0]?.formatted_address || "")); }); }; export const Marker: FC = (options: google.maps.MarkerOptions) : ReactElement | null => { const [marker, setMarker] = useState(); useEffect(() => { if (!marker) setMarker(new google.maps.Marker()); // remove marker from map on unmount return () => { if (!!marker) marker.setMap(null); }; }, [marker]); useEffect(() => { if (!!marker) marker.setOptions(options); }, [marker, options]); return null; }; export const MapComponent = ({mapOptions, handleMapClick} : {mapOptions: google.maps.MapOptions, handleMapClick: any}) : ReactElement => { const ref = useRef(null); const [map, setMap] = useState(undefined); const [markerPos, setMarkerPos] = useState(mapOptions?.center); const handleClick = (e: google.maps.MapMouseEvent | google.maps.IconMouseEvent) => { setMarkerPos(e.latLng); handleMapClick(e.latLng) } useEffect(() => { if (ref.current && !map) { const newmap = new window.google.maps.Map(ref.current, {...mapOptions}); newmap.addListener("click", handleClick); setMap(newmap); } }, [ref, map]); // re-render map if options change useEffect(() => { if (ref.current && map && !!mapOptions) { map.setOptions({...mapOptions, zoom: map.getZoom()}); } }, [mapOptions]); return (
); }