import { useCallback, useEffect, useRef, useState } from 'react' import type { LatLng } from '@/types/api' function geolocationErrorMessage(error: GeolocationPositionError): string { switch (error.code) { case error.PERMISSION_DENIED: return 'Location access denied. Enable it to view nearby pings.' case error.POSITION_UNAVAILABLE: return 'Unable to determine your position. Try again.' case error.TIMEOUT: return 'Timed out while fetching your location.' default: return 'Failed to retrieve your location.' } } export function useUserLocation() { const [location, setLocation] = useState(null) const [error, setError] = useState(null) const [isRequesting, setIsRequesting] = useState(false) const watchIdRef = useRef(null) const clearWatch = useCallback(() => { if (typeof navigator === 'undefined' || !navigator.geolocation) { return } if (watchIdRef.current !== null) { navigator.geolocation.clearWatch(watchIdRef.current) watchIdRef.current = null } }, []) const start = useCallback(() => { if (typeof navigator === 'undefined' || !navigator.geolocation) { setError('Geolocation is not supported in this browser.') setIsRequesting(false) return } clearWatch() setIsRequesting(true) setError(null) navigator.geolocation.getCurrentPosition( (position) => { setLocation({ lat: position.coords.latitude, lng: position.coords.longitude }) setIsRequesting(false) setError(null) }, (geoError) => { setError(geolocationErrorMessage(geoError)) setIsRequesting(false) }, { enableHighAccuracy: true, timeout: 10000 }, ) const watchId = navigator.geolocation.watchPosition( (position) => { setLocation({ lat: position.coords.latitude, lng: position.coords.longitude }) setError(null) setIsRequesting(false) }, (geoError) => { setError(geolocationErrorMessage(geoError)) setIsRequesting(false) }, { enableHighAccuracy: true, maximumAge: 15000, timeout: 10000 }, ) watchIdRef.current = watchId }, [clearWatch]) useEffect(() => { start() return () => { clearWatch() } }, [clearWatch, start]) return { location, error, isRequesting, refresh: start, } }