import { Button, Input } from "@usememos/mui"; import { LatLng } from "leaflet"; import { MapPinIcon, XIcon } from "lucide-react"; import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import LeafletMap from "@/components/LeafletMap"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/Popover"; import { Location } from "@/types/proto/api/v1/memo_service"; import { useTranslate } from "@/utils/i18n"; interface Props { location?: Location; onChange: (location?: Location) => void; } interface State { initilized: boolean; placeholder: string; position?: LatLng; } const LocationSelector = (props: Props) => { const t = useTranslate(); const [state, setState] = useState({ initilized: false, placeholder: props.location?.placeholder || "", position: props.location ? new LatLng(props.location.latitude, props.location.longitude) : undefined, }); const [popoverOpen, setPopoverOpen] = useState(false); useEffect(() => { setState((state) => ({ ...state, placeholder: props.location?.placeholder || "", position: new LatLng(props.location?.latitude || 0, props.location?.longitude || 0), })); }, [props.location]); useEffect(() => { if (popoverOpen && !props.location) { const handleError = (error: any, errorMessage: string) => { setState({ ...state, initilized: true }); toast.error(errorMessage); console.error(error); }; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( (position) => { const lat = position.coords.latitude; const lng = position.coords.longitude; setState({ ...state, position: new LatLng(lat, lng), initilized: true }); }, (error) => { handleError(error, "Failed to get current position"); }, ); } else { handleError("Geolocation is not supported by this browser.", "Geolocation is not supported by this browser."); } } }, [popoverOpen]); useEffect(() => { if (!state.position) { setState({ ...state, placeholder: "" }); return; } // Fetch reverse geocoding data. fetch(`https://nominatim.openstreetmap.org/reverse?lat=${state.position.lat}&lon=${state.position.lng}&format=json`) .then((response) => response.json()) .then((data) => { if (data && data.display_name) { setState({ ...state, placeholder: data.display_name }); } }) .catch((error) => { toast.error("Failed to fetch reverse geocoding data"); console.error("Failed to fetch reverse geocoding data:", error); }); }, [state.position]); const onPositionChanged = (position: LatLng) => { setState({ ...state, position }); }; const removeLocation = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); props.onChange(undefined); }; return (
{state.position && ( [{state.position.lat.toFixed(2)}, {state.position.lng.toFixed(2)}] )} setState((state) => ({ ...state, placeholder: e.target.value }))} />
); }; export default LocationSelector;