summaryrefslogtreecommitdiff
path: root/src/lib/maps/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/maps/components')
-rw-r--r--src/lib/maps/components/PinPointMap.jsx163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/lib/maps/components/PinPointMap.jsx b/src/lib/maps/components/PinPointMap.jsx
new file mode 100644
index 00000000..0781d8a8
--- /dev/null
+++ b/src/lib/maps/components/PinPointMap.jsx
@@ -0,0 +1,163 @@
+import React, { useState, useCallback, useRef } 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 center = {
+ lat: -6.2, // Default latitude (Jakarta)
+ lng: 106.816666, // Default longitude (Jakarta)
+};
+
+const PinpointLocation = () => {
+ const { isLoaded } = useJsApiLoader({
+ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_API_KEY, // Pastikan API key ada di .env.local
+ libraries: ['places'],
+ });
+
+ const { addressMaps, setAddressMaps, selectedPosition, setSelectedPosition } =
+ useMaps();
+
+ const [tempAddress, setTempAddress] = useState('');
+ const [tempPosition, setTempPosition] = useState(center);
+
+ 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);
+ }
+ };
+
+ 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}`
+ );
+ const data = await response.json();
+ if (data.results[0]) {
+ setTempAddress(data.results[0].formatted_address);
+ }
+ } catch (error) {
+ console.error('Error fetching address:', error);
+ }
+ };
+
+ const handleUseCurrentLocation = () => {
+ if (navigator.geolocation) {
+ navigator.geolocation.getCurrentPosition(
+ (position) => {
+ const lat = position.coords.latitude;
+ const lng = position.coords.longitude;
+ setTempPosition({ lat, lng });
+ getAddress(lat, lng);
+ },
+ (error) => {
+ console.error('Error getting current location:', error);
+ }
+ );
+ }
+ };
+
+ const handleSavePinpoint = (event) => {
+ event.preventDefault();
+ if(tempAddress === '') {
+ alert('Silahkan pilih lokasi terlebih dahulu');
+ return;
+ }
+ setSelectedPosition(tempPosition);
+ setAddressMaps(tempAddress);
+ };
+
+ return (
+ <div className='w-full'>
+ <h3>Tentukan Pinpoint Lokasi</h3>
+ <div style={{ marginBottom: '10px' }}>
+ {isLoaded ? (
+ <Autocomplete
+ onLoad={(ref) => (autocompleteRef.current = ref)}
+ onPlaceChanged={handlePlaceSelect}
+ >
+ <input
+ type='text'
+ placeholder='Cari Alamat...'
+ style={{ width: '100%', padding: '8px' }}
+ />
+ </Autocomplete>
+ ) : (
+ <p>Loading autocomplete...</p>
+ )}
+ </div>
+
+ <div>
+ {isLoaded ? (
+ <GoogleMap
+ mapContainerStyle={containerStyle}
+ center={tempPosition}
+ 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),
+ }}
+ />
+ </GoogleMap>
+ ) : (
+ <p>Loading map...</p>
+ )}
+ </div>
+
+ <div style={{ marginTop: '20px' }}>
+ <Button
+ variant='solid'
+ onClick={handleUseCurrentLocation}
+ >
+ <LocateFixed class='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>
+ </div>
+ </div>
+
+ <div className='mt-6 flex justify-end'>
+ <button className='p-3 border border-red-500 bg-red-600 text-white font-semibold rounded-lg' onClick={handleSavePinpoint}>
+ Simpan Lokasi Ini
+ </button>
+ </div>
+ </div>
+ );
+};
+
+export default PinpointLocation;