diff --git a/src/components/forms/fields/GeolocationInput.tsx b/src/components/forms/fields/GeolocationInput.tsx index ed24299..4fbb92f 100644 --- a/src/components/forms/fields/GeolocationInput.tsx +++ b/src/components/forms/fields/GeolocationInput.tsx @@ -1,9 +1,12 @@ import { useState, useEffect, useCallback } from 'react'; import { Modal } from '../../reusable/Modal'; import { Button } from '../../buttons/Button'; -import { useJsApiLoader, GoogleMap, Marker } from '@react-google-maps/api'; +import { useJsApiLoader, GoogleMap } from '@react-google-maps/api'; +import { CustomAdvancedMarker } from '../../maps/CustomAdvancedMarker'; import { MapPin, Crosshair, Map as MapIcon, Loader2, X } from 'lucide-react'; +const libraries: ("marker")[] = ["marker"]; + const mapContainerStyle = { width: '100%', height: '400px', @@ -27,9 +30,12 @@ export function GeolocationInput({ const [isMapModalOpen, setIsMapModalOpen] = useState(false); const [mapMarkerPos, setMapMarkerPos] = useState<{ lat: number; lng: number } | null>(null); + const isLocalhost = typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'); + const { isLoaded } = useJsApiLoader({ id: 'google-map-script', - googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY || '' + googleMapsApiKey: isLocalhost ? '' : (import.meta.env.VITE_GOOGLE_MAPS_API_KEY || ''), + libraries }); // Extract lat, lng & accuracy from value (supporting both latitude/longitude and lat/lng) @@ -179,11 +185,12 @@ export function GeolocationInput({ options={{ streetViewControl: false, mapTypeControl: false, - fullscreenControl: false + fullscreenControl: false, + mapId: "DEMO_MAP_ID" }} > {mapMarkerPos && ( - + )} )} diff --git a/src/components/maps/CustomAdvancedMarker.tsx b/src/components/maps/CustomAdvancedMarker.tsx new file mode 100644 index 0000000..3bd4753 --- /dev/null +++ b/src/components/maps/CustomAdvancedMarker.tsx @@ -0,0 +1,53 @@ +import { useEffect, useRef } from 'react'; +import { useGoogleMap } from '@react-google-maps/api'; + +export function CustomAdvancedMarker({ + position, + title, + iconUrl, + onClick +}: { + position: google.maps.LatLngLiteral; + title?: string; + iconUrl?: string; + onClick?: () => void; +}) { + const map = useGoogleMap(); + const markerRef = useRef(null); + + useEffect(() => { + if (!map || !window.google?.maps?.marker?.AdvancedMarkerElement) return; + + let content: HTMLElement | undefined; + if (iconUrl) { + const img = document.createElement('img'); + img.src = iconUrl; + img.style.width = '32px'; + img.style.height = '32px'; + content = img; + } + + const options: google.maps.marker.AdvancedMarkerElementOptions = { + map, + position, + }; + + if (title) options.title = title; + if (content) options.content = content; + + markerRef.current = new window.google.maps.marker.AdvancedMarkerElement(options); + + if (onClick && markerRef.current) { + markerRef.current.addListener('gmp-click', onClick); + } + + return () => { + if (markerRef.current) { + google.maps.event.clearInstanceListeners(markerRef.current); + markerRef.current.map = null; + } + }; + }, [map, position.lat, position.lng, title, iconUrl, onClick]); + + return null; +} diff --git a/src/components/maps/DailyLogMap.tsx b/src/components/maps/DailyLogMap.tsx index 9323836..eff87ee 100644 --- a/src/components/maps/DailyLogMap.tsx +++ b/src/components/maps/DailyLogMap.tsx @@ -1,8 +1,11 @@ import { useState, useEffect, useCallback, useRef } from 'react'; -import { useJsApiLoader, GoogleMap, Marker, InfoWindow } from '@react-google-maps/api'; +import { useJsApiLoader, GoogleMap, InfoWindow } from '@react-google-maps/api'; import { Loader2, MapPin } from 'lucide-react'; import { PIPELINE } from '../../api/config'; import { dailyReportsClient } from '../../api/clients'; +import { CustomAdvancedMarker } from './CustomAdvancedMarker'; + +const libraries: ("marker")[] = ["marker"]; interface StoreLocation { latitude: number; @@ -50,9 +53,12 @@ export function DailyLogMap({ const [error, setError] = useState(null); const mapRef = useRef(null); + const isLocalhost = typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'); + const { isLoaded } = useJsApiLoader({ id: 'google-map-script', - googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY || '' + googleMapsApiKey: isLocalhost ? '' : (import.meta.env.VITE_GOOGLE_MAPS_API_KEY || ''), + libraries }); const fetchNearestStores = async (lat: number, lng: number) => { @@ -171,30 +177,29 @@ export function DailyLogMap({ options={{ streetViewControl: false, mapTypeControl: false, - fullscreenControl: false + fullscreenControl: false, + mapId: "DEMO_MAP_ID" }} > {/* User's Current Location Marker */} {userLocation && ( - )} {/* Stores Markers */} - {stores.map((store) => { + {stores.map((store, index) => { if (!store.location) return null; const lat = Number(store.location.latitude); const lng = Number(store.location.longitude); if (isNaN(lat) || isNaN(lng)) return null; return ( - setSelectedStore(store)} title={store.business_name}