Spaces:
Running
Running
import { useState, useCallback } from "react"; | |
interface LocationData { | |
latitude: number; | |
longitude: number; | |
accuracy?: number; | |
googleMapsUrl: string; | |
timestamp: Date; | |
} | |
interface LocationError { | |
code: number; | |
message: string; | |
} | |
export const useLocation = () => { | |
const [isLoading, setIsLoading] = useState(false); | |
const [location, setLocation] = useState<LocationData | null>(null); | |
const [error, setError] = useState<LocationError | null>(null); | |
const getLocation = useCallback(() => { | |
if (!navigator.geolocation) { | |
setError({ | |
code: 0, | |
message: "Geolocation is not supported by this browser." | |
}); | |
return; | |
} | |
setIsLoading(true); | |
setError(null); | |
navigator.geolocation.getCurrentPosition( | |
(position) => { | |
const lat = position.coords.latitude; | |
const lng = position.coords.longitude; | |
const accuracy = position.coords.accuracy; | |
const googleMapsUrl = `https://maps.google.com/?q=${lat},${lng}`; | |
const locationData: LocationData = { | |
latitude: lat, | |
longitude: lng, | |
accuracy, | |
googleMapsUrl, | |
timestamp: new Date(position.timestamp) | |
}; | |
setLocation(locationData); | |
setIsLoading(false); | |
}, | |
(err) => { | |
let errorMessage: string; | |
switch (err.code) { | |
case err.PERMISSION_DENIED: | |
errorMessage = "User denied the location request. Please enable location services and try again."; | |
break; | |
case err.POSITION_UNAVAILABLE: | |
errorMessage = "Location information is unavailable. Please check your GPS/network connection."; | |
break; | |
case err.TIMEOUT: | |
errorMessage = "Location request timed out. Please try again."; | |
break; | |
default: | |
errorMessage = "An unknown error occurred while retrieving location."; | |
break; | |
} | |
setError({ | |
code: err.code, | |
message: errorMessage | |
}); | |
setIsLoading(false); | |
}, | |
{ | |
enableHighAccuracy: true, | |
timeout: 10000, | |
maximumAge: 60000 | |
} | |
); | |
}, []); | |
const copyToClipboard = useCallback((url: string) => { | |
if (navigator.clipboard) { | |
return navigator.clipboard.writeText(url); | |
} | |
return Promise.reject("Clipboard not supported"); | |
}, []); | |
const shareLocation = useCallback((locationData: LocationData) => { | |
if (navigator.share) { | |
return navigator.share({ | |
title: "My Location", | |
url: locationData.googleMapsUrl | |
}); | |
} | |
return Promise.reject("Web Share API not supported"); | |
}, []); | |
const clearLocation = useCallback(() => { | |
setLocation(null); | |
setError(null); | |
}, []); | |
return { | |
location, | |
error, | |
isLoading, | |
getLocation, | |
copyToClipboard, | |
shareLocation, | |
clearLocation | |
}; | |
}; |