import React, { useState, useCallback, useRef, useEffect } from 'react'; import { GoogleMap, useJsApiLoader, Marker, Autocomplete, } from '@react-google-maps/api'; import { useMaps } from '../stores/useMaps'; import { LocateFixed, MapPinIcon } from 'lucide-react'; import { Button } from '@chakra-ui/react'; const containerStyle = { width: '100%', height: '400px', }; const PinpointLocation = ({ initialLatitude, initialLongitude, initialAddress, }) => { const { isLoaded } = useJsApiLoader({ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY, libraries: ['places'], }); const { setAddressMaps, selectedPosition, setSelectedPosition, setDetailAddress, setPinedMaps, getDefaultCenter, // ✅ ambil default center dari store } = useMaps(); const [tempAddress, setTempAddress] = useState(initialAddress || ''); const [tempPosition, setTempPosition] = useState( initialLatitude && initialLongitude ? { lat: parseFloat(initialLatitude), lng: parseFloat(initialLongitude) } : selectedPosition?.lat && selectedPosition?.lng ? selectedPosition : getDefaultCenter() // ✅ fallback aman untuk view ); useEffect(() => { if (initialLatitude && initialLongitude) { const lat = parseFloat(initialLatitude); const lng = parseFloat(initialLongitude); if (!isNaN(lat) && !isNaN(lng)) { setTempPosition({ lat, lng }); // kalau address belum ada, reverse geocode if (!initialAddress) { getAddress(lat, lng); } else { setTempAddress(initialAddress); } } } }, [initialLatitude, initialLongitude, initialAddress]); const [markerIcon, setMarkerIcon] = useState(null); const autocompleteRef = useRef(null); useEffect(() => { if (isLoaded && window.google) { setMarkerIcon({ url: 'https://cdn.pixabay.com/photo/2014/04/03/10/03/google-309740_1280.png', scaledSize: new window.google.maps.Size(25, 40), }); } // Jika ada koordinat awal tapi belum ada address → reverse geocode if (initialLatitude && initialLongitude && !initialAddress) { getAddress(parseFloat(initialLatitude), parseFloat(initialLongitude)); } }, [isLoaded, initialLatitude, initialLongitude, initialAddress]); const getAddressComponent = (components, type) => { const component = components.find((comp) => comp.types.includes(type)); return component ? component.long_name : ''; }; // fill from pin point const getAddress = async (lat, lng) => { try { const response = await fetch( `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${process.env.NEXT_PUBLIC_GOOGLE_API_KEY}&language=id` ); const data = await response.json(); if (data.results[0]) { const addressComponents = data.results[0].address_components; const formattedAddress = data.results[0].formatted_address; const details = { street: [ getAddressComponent(addressComponents, 'route'), getAddressComponent(addressComponents, 'street_number'), getAddressComponent(addressComponents, 'administrative_area_level_4'), getAddressComponent(addressComponents, 'administrative_area_level_3'), getAddressComponent(addressComponents, 'administrative_area_level_2'), getAddressComponent(addressComponents, 'administrative_area_level_1'), getAddressComponent(addressComponents, 'postal_code'), ].filter(Boolean).join(', '), province: getAddressComponent( addressComponents, 'administrative_area_level_1' ), district: getAddressComponent( addressComponents, 'administrative_area_level_2' ), subDistrict: getAddressComponent( addressComponents, 'administrative_area_level_3' ), village: getAddressComponent( addressComponents, 'administrative_area_level_4' ), postalCode: getAddressComponent(addressComponents, 'postal_code'), }; setDetailAddress(details); setTempAddress(formattedAddress); } } catch (error) { console.error('Error fetching address:', error); } }; const onMapClick = useCallback((event) => { const lat = event.latLng.lat(); const lng = event.latLng.lng(); const newPosition = { lat, lng }; setTempPosition(newPosition); getAddress(lat, lng); }, []); const handlePlaceSelect = () => { const place = autocompleteRef.current.getPlace(); if (place && place.geometry) { const lat = place.geometry.location.lat(); const lng = place.geometry.location.lng(); const newPosition = { lat, lng }; setTempPosition(newPosition); setTempAddress(place.formatted_address); getAddress(lat, lng); } }; const handleUseCurrentLocation = () => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( (position) => { const lat = position.coords.latitude; const lng = position.coords.longitude; const newPosition = { lat, lng }; setTempPosition(newPosition); getAddress(lat, lng); }, (error) => { console.error('Error getting current location:', error); } ); } }; const handleSavePinpoint = (event) => { event.preventDefault(); // ✅ cegah save jika masih di default center (user belum benar2 pilih lokasi) const dc = getDefaultCenter(); const isDefault = Math.abs(tempPosition.lat - dc.lat) < 1e-6 && Math.abs(tempPosition.lng - dc.lng) < 1e-6; if (!tempAddress || isDefault) { alert('Silahkan pilih lokasi di peta atau autocomplete terlebih dahulu'); return; } setSelectedPosition(tempPosition); setAddressMaps(tempAddress); setPinedMaps(false); }; return (
Loading autocomplete...
)}Loading map...
)}PinPoint :