mediahub-fe/components/maps/Maps.tsx

160 lines
4.1 KiB
TypeScript

import { GoogleMap, Marker, useLoadScript } from "@react-google-maps/api";
import Cookies from "js-cookie";
import { useEffect, useState } from "react";
import usePlacesAutocomplete, {
getGeocode,
getLatLng,
} from "use-places-autocomplete";
import { GoogleMapsAPI } from "./client-config";
import Geocode from "react-geocode";
import { PlacesCombobox } from "@/components/ui/combobox";
Geocode.setApiKey(GoogleMapsAPI);
export default function Places(props: {
center: { lat: number; lng: number };
draggable?: boolean;
onLocationChange?: (location: string) => void; // Tambahkan onLocationChange
}) {
const { isLoaded } = useLoadScript({
googleMapsApiKey: GoogleMapsAPI,
libraries: ["places"],
language: "id",
});
const { center, draggable, onLocationChange } = props;
if (!isLoaded) return <div>Loading...</div>;
return (
<Map
lat={center.lat}
lng={center.lng}
draggable={draggable}
onLocationChange={onLocationChange} // Kirimkan properti onLocationChange
/>
);
}
interface MapProps {
lat: number;
lng: number;
draggable?: boolean;
onLocationChange?: (location: string) => void; // Tambahkan properti ini
}
function Map(props: MapProps) {
const containerStyle = {
width: "100%",
height: "400px",
};
const center = {
lat: -6.1754,
lng: 106.8272,
};
const [selected, setSelected] = useState<{ lat: number; lng: number } | null>(
null
);
const { lat, lng, draggable, onLocationChange } = props;
useEffect(() => {
if (lat !== undefined && lng !== undefined) {
setSelected({ lat, lng });
getAddressFromLatLong(lat, lng);
}
}, [lat, lng]);
const onMarkerDragEnd = (e: google.maps.MapMouseEvent) => {
const lat = e.latLng?.lat() ?? 0;
const lng = e.latLng?.lng() ?? 0;
console.log(lat, lng);
getAddressFromLatLong(lat, lng);
if (onLocationChange) {
onLocationChange(`Latitude: ${lat}, Longitude: ${lng}`); // Kirimkan lokasi ke parent melalui onLocationChange
}
};
async function getAddressFromLatLong(lat: number, lng: number) {
try {
const response = await Geocode.fromLatLng(lat.toString(), lng.toString());
const address = response.results[0].formatted_address;
Cookies.set("map_lat", `${lat}`, { expires: 1 });
Cookies.set("map_long", `${lng}`, { expires: 1 });
console.log("Address:", address);
if (onLocationChange) {
onLocationChange(address); // Kirimkan alamat jika berhasil
}
} catch (error) {
console.error(error);
}
}
return (
<>
<div>
<PlacesAutocomplete setSelected={setSelected} />
</div>
<GoogleMap
zoom={selected == null ? 10 : 15}
center={selected == null ? center : selected}
mapContainerStyle={containerStyle}
>
{selected && (
<Marker
draggable={draggable}
position={selected}
onDragEnd={onMarkerDragEnd}
/>
)}
</GoogleMap>
</>
);
}
interface PlacesAutocompleteProps {
setSelected: (coords: { lat: number; lng: number }) => void;
}
function PlacesAutocomplete({ setSelected }: PlacesAutocompleteProps) {
const {
ready,
value,
setValue,
suggestions: { status, data },
clearSuggestions,
} = usePlacesAutocomplete();
const handleSelect = async (address: string) => {
setValue(address, false);
clearSuggestions();
try {
const results = await getGeocode({ address });
const { lat, lng } = await getLatLng(results[0]);
setSelected({ lat, lng });
console.log("Selected Lat/Lng:", { lat, lng });
Cookies.set("map_lat", `${lat}`, { expires: 1 });
Cookies.set("map_long", `${lng}`, { expires: 1 });
} catch (error) {
console.error("Error fetching coordinates:", error);
}
};
return (
<PlacesCombobox
value={value}
onValueChange={(newValue) => setValue(newValue)}
onSelect={handleSelect}
suggestions={data}
status={status}
disabled={!ready}
placeholder="Cari Alamat"
className="border"
/>
);
}