diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-06-11 13:40:45 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-06-11 13:40:45 +0700 |
| commit | 2e507ccbc92f18a0d7f8ebc59112a0337a0bd678 (patch) | |
| tree | 61fa5c3b60ac3b920311e77a539a87ec0b18046e /src/lib/maps | |
| parent | ca05a70e98e9066882de6394ffbd89db7af2cb9d (diff) | |
<hafid> Pinpoint done
Diffstat (limited to 'src/lib/maps')
| -rw-r--r-- | src/lib/maps/components/PinPointMap.jsx | 139 |
1 files changed, 77 insertions, 62 deletions
diff --git a/src/lib/maps/components/PinPointMap.jsx b/src/lib/maps/components/PinPointMap.jsx index acd5ab92..fde1f36c 100644 --- a/src/lib/maps/components/PinPointMap.jsx +++ b/src/lib/maps/components/PinPointMap.jsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useRef } from 'react'; +import React, { useState, useCallback, useRef, useEffect } from 'react'; import { GoogleMap, useJsApiLoader, @@ -8,49 +8,46 @@ import { import { useMaps } from '../stores/useMaps'; import { LocateFixed, MapPinIcon } from 'lucide-react'; import { Button } from '@chakra-ui/react'; -import { useForm } from 'react-hook-form'; const containerStyle = { width: '100%', height: '400px', }; -const center = { - lat: -6.2, // Default latitude (Jakarta) - lng: 106.816666, // Default longitude (Jakarta) +const defaultCenter = { + lat: -6.2, + lng: 106.816666, }; const PinpointLocation = () => { const { isLoaded } = useJsApiLoader({ - googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY, // Pastikan API key ada di .env.local + googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY, libraries: ['places'], }); - const { addressMaps, setAddressMaps, selectedPosition, setSelectedPosition, setDetailAddress, setPinedMaps } = - useMaps(); + const { + addressMaps, + setAddressMaps, + selectedPosition, + setSelectedPosition, + setDetailAddress, + setPinedMaps, + } = useMaps(); const [tempAddress, setTempAddress] = useState(''); - const [tempPosition, setTempPosition] = useState(center); - const { setValue } = useForm(); + const [tempPosition, setTempPosition] = useState(defaultCenter); + const [markerIcon, setMarkerIcon] = useState(null); const autocompleteRef = useRef(null); - const onMapClick = useCallback((event) => { - const lat = event.latLng.lat(); - const lng = event.latLng.lng(); - setTempPosition({ lat, lng }); - 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(); - setTempPosition({ lat, lng }); - setTempAddress(place.formatted_address); + 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), + }); } - }; + }, [isLoaded]); const getAddressComponent = (components, type) => { const component = components.find((comp) => comp.types.includes(type)); @@ -63,43 +60,59 @@ const PinpointLocation = () => { `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${process.env.NEXT_PUBLIC_GOOGLE_API_KEY}` ); 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 = { - route : getAddressComponent(addressComponents, 'route')+' '+getAddressComponent(addressComponents, 'street_number')+' '+getAddressComponent(addressComponents, 'administrative_area_level_7')+' '+getAddressComponent(addressComponents, 'administrative_area_level_6'), - 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' - ), + street: + getAddressComponent(addressComponents, 'route') + + ' ' + + getAddressComponent(addressComponents, 'street_number'), + 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(data.results[0].formatted_address); + 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; - setTempPosition({ lat, lng }); + const newPosition = { lat, lng }; + setTempPosition(newPosition); getAddress(lat, lng); }, (error) => { @@ -115,18 +128,16 @@ const PinpointLocation = () => { alert('Silahkan pilih lokasi terlebih dahulu'); return; } - // console.log('tempPosition', tempPosition.lat); - getAddress(tempPosition.lat, tempPosition.lng); + setSelectedPosition(tempPosition); setAddressMaps(tempAddress); - setPinedMaps(false) + setPinedMaps(false); }; - console.log('set selected position',selectedPosition); - return ( <div className='w-full'> <h3>Tentukan Pinpoint Lokasi</h3> + <div style={{ marginBottom: '10px' }}> {isLoaded ? ( <Autocomplete @@ -152,15 +163,20 @@ const PinpointLocation = () => { zoom={15} onClick={onMapClick} > - <Marker - position={tempPosition} - draggable={true} - onDragEnd={(e) => onMapClick(e)} - icon={{ - url: 'https://maps.google.com/mapfiles/ms/icons/red-pushpin.png', - scaledSize: new window.google.maps.Size(40, 40), - }} - /> + {markerIcon && ( + <Marker + position={tempPosition} + draggable={true} + onDragEnd={(e) => { + const lat = e.latLng.lat(); + const lng = e.latLng.lng(); + const newPosition = { lat, lng }; + setTempPosition(newPosition); + getAddress(lat, lng); + }} + icon={markerIcon} + /> + )} </GoogleMap> ) : ( <p>Loading map...</p> @@ -169,16 +185,15 @@ const PinpointLocation = () => { <div style={{ marginTop: '20px' }}> <Button variant='solid' onClick={handleUseCurrentLocation}> - <LocateFixed class='h-6 w-6 text-gray-500 mr-2' /> Gunakan Lokasi Saat - ini + <LocateFixed className='h-6 w-6 text-gray-500 mr-2' /> Gunakan Lokasi Saat Ini </Button> </div> <div style={{ marginTop: '10px' }}> <p>PinPoint :</p> <div className='flex gap-x-2 shadow-md rounded-sm text-gray-500 p-3 items-center'> - <MapPinIcon class='h-8 w-8 text-gray-500 mr-3' /> - <label> {tempAddress}</label> + <MapPinIcon className='h-8 w-8 text-gray-500 mr-3' /> + <label>{tempAddress || 'Pilih lokasi di peta'}</label> </div> </div> |
