import { useState, useEffect, useCallback } from 'react'; import { useJsApiLoader, GoogleMap, InfoWindow } from '@react-google-maps/api'; const libraries: ("marker")[] = ["marker"]; import { CustomAdvancedMarker } from './CustomAdvancedMarker'; import { PIPELINE, BASE_URL } from '../../api/config'; import { Loader2, MapPin, ChevronDown, ChevronUp } from 'lucide-react'; // Interfaces for the API response interface StoreLocation { latitude: number; longitude: number; } interface Store { area: string; business_name: string; distance_km: number; location: StoreLocation; route_name: string; store_code: string; } interface NearestStoresResponse { message: string; response: { count: number; stores: Store[]; success: boolean; }; } const mapContainerStyle = { width: '100%', height: '100%', minHeight: '400px', borderRadius: '16px' }; const defaultCenter = { lat: 12.9716, lng: 77.5946 }; export function NearestStoresMap() { const [userLocation, setUserLocation] = useState<{ lat: number, lng: number } | null>(null); const [stores, setStores] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [selectedStore, setSelectedStore] = useState(null); const [isListExpanded, setIsListExpanded] = useState(false); const isLocalhost = typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'); const { isLoaded } = useJsApiLoader({ id: 'google-map-script', googleMapsApiKey: isLocalhost ? '' : (import.meta.env.VITE_GOOGLE_MAPS_API_KEY || ''), libraries }); const fetchNearestStores = async (lat: number, lng: number) => { setLoading(true); setError(null); try { const response = await fetch(`${BASE_URL}${PIPELINE.endpoints.nearestStores}`, { method: 'POST', headers: { 'accept': 'application/json, text/plain, */*', 'content-type': 'application/json', 'groupid': '25', 'orgid': '57', 'templateid': '189', 'x-pipeline-version': 'latest' }, body: JSON.stringify({ latitude: lat, longitude: lng }) }); if (!response.ok) { throw new Error(`Failed to fetch stores: ${response.statusText}`); } const data = await response.json() as NearestStoresResponse; if (data.response && data.response.stores) { setStores(data.response.stores); } } catch (err: any) { setError(err.message || 'An error occurred while fetching stores.'); } finally { setLoading(false); } }; useEffect(() => { if (!navigator.geolocation) { setError('Geolocation is not supported by your browser.'); return; } setLoading(true); navigator.geolocation.getCurrentPosition( (position) => { const lat = position.coords.latitude; const lng = position.coords.longitude; setUserLocation({ lat, lng }); fetchNearestStores(lat, lng); }, (err) => { setError(err.message || 'Failed to get location'); setLoading(false); }, { enableHighAccuracy: true } ); }, []); const onLoad = useCallback(function callback(map: google.maps.Map) { if (userLocation) { const bounds = new window.google.maps.LatLngBounds(); bounds.extend(userLocation); stores.forEach(store => { if (store.location) { bounds.extend({ lat: store.location.latitude, lng: store.location.longitude }); } }); if (stores.length > 0) { map.fitBounds(bounds); } } }, [userLocation, stores]); if (!isLoaded) { return (
); } return (
{error && (
{error}
)} {loading && !userLocation && (
Locating you...
)}
{/* User's Current Location Marker */} {userLocation && ( )} {/* Stores Markers */} {stores.map((store) => ( store.location && ( setSelectedStore(store)} title={store.business_name} /> ) ))} {/* Info Window for Selected Store */} {selectedStore && selectedStore.location && ( setSelectedStore(null)} >

{selectedStore.business_name}

{selectedStore.area}

{selectedStore.route_name} {selectedStore.distance_km} km
)}
setIsListExpanded(!isListExpanded)}>

Nearest Stores ({stores.length})

{isListExpanded && ( <> {loading && stores.length === 0 && (
Fetching nearby stores...
)} {!loading && stores.length === 0 && userLocation && (
No stores found nearby.
)}
{stores.map(store => (
setSelectedStore(store)}>
{store.business_name}

{store.area}

{store.route_name} {store.distance_km} km
))}
)}
); }