|
| 1 | +import { useEffect, useState, useRef } from 'react'; |
| 2 | +import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'; |
| 3 | +import 'leaflet/dist/leaflet.css'; |
1 | 4 | import { FaTruck } from 'react-icons/fa';
|
| 5 | +import L from 'leaflet'; |
| 6 | + |
| 7 | +// Custom marker icon |
| 8 | +const customIcon = new L.Icon({ |
| 9 | + iconUrl: |
| 10 | + 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', |
| 11 | + iconSize: [25, 41], |
| 12 | + iconAnchor: [12, 41], |
| 13 | + popupAnchor: [1, -34], |
| 14 | +}); |
| 15 | + |
| 16 | +const MoveMap = ({ location }) => { |
| 17 | + const map = useMap(); |
| 18 | + useEffect(() => { |
| 19 | + map.setView([location.lat, location.lng], 13, { animate: true }); |
| 20 | + }, [location, map]); |
| 21 | + return null; |
| 22 | +}; |
2 | 23 |
|
3 | 24 | const DeliveryCard = () => {
|
| 25 | + const [location, setLocation] = useState({ lat: 50.4501, lng: 30.5234 }); // Default: Kyiv |
| 26 | + const [userLocated, setUserLocated] = useState(false); |
| 27 | + const [error, setError] = useState(null); |
| 28 | + const mapRef = useRef(null); |
| 29 | + |
| 30 | + useEffect(() => { |
| 31 | + if (navigator.geolocation) { |
| 32 | + navigator.geolocation.getCurrentPosition( |
| 33 | + (position) => { |
| 34 | + const newLocation = { |
| 35 | + lat: position.coords.latitude, |
| 36 | + lng: position.coords.longitude, |
| 37 | + }; |
| 38 | + setLocation(newLocation); |
| 39 | + setUserLocated(true); |
| 40 | + }, |
| 41 | + (error) => { |
| 42 | + console.error('Geolocation error:', error); |
| 43 | + setError('Location access denied. Using default location (Kyiv).'); |
| 44 | + } |
| 45 | + ); |
| 46 | + } else { |
| 47 | + setError('Geolocation is not supported in this browser.'); |
| 48 | + } |
| 49 | + }, []); |
| 50 | + |
4 | 51 | return (
|
5 |
| - <div className="p-4 shadow-lg rounded-2xl w-full bg-white"> |
6 |
| - <h2 className="text-lg font-semibold mb-2 self-start">Delivery</h2> |
| 52 | + <div className="p-4 shadow-lg rounded-2xl w-full bg-white"> |
| 53 | + <h2 className="text-lg font-semibold mb-2">Delivery</h2> |
7 | 54 | <div className="relative w-full h-40 rounded-lg overflow-hidden">
|
8 |
| - <iframe |
9 |
| - src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3151.8354345093703!2d144.95373631531795!3d-37.816279979751554!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x6ad642af0f11fd81%3A0xf57760c2f073bdde!2sMelbourne%20CBD%2C%20Victoria%2C%20Australia!5e0!3m2!1sen!2sus!4v1633044297056!5m2!1sen!2sus" |
10 |
| - width="100%" |
11 |
| - height="100%" |
12 |
| - style={{ border: 0 }} |
13 |
| - allowFullScreen="" |
14 |
| - loading="lazy" |
15 |
| - referrerPolicy="no-referrer-when-downgrade" |
16 |
| - ></iframe> |
| 55 | + <MapContainer |
| 56 | + center={[location.lat, location.lng]} |
| 57 | + zoom={13} |
| 58 | + style={{ height: '100%', width: '100%' }} |
| 59 | + ref={mapRef} |
| 60 | + > |
| 61 | + <TileLayer |
| 62 | + url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" |
| 63 | + attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
| 64 | + /> |
| 65 | + <Marker position={[location.lat, location.lng]} icon={customIcon}> |
| 66 | + <Popup> |
| 67 | + {userLocated ? 'You are here!' : 'Default location: Kyiv'} |
| 68 | + </Popup> |
| 69 | + </Marker> |
| 70 | + <MoveMap location={location} /> |
| 71 | + </MapContainer> |
17 | 72 | </div>
|
| 73 | + {error && <p className="text-red-500 text-sm mt-2">{error}</p>} |
18 | 74 | <div className="flex justify-between items-center mt-4">
|
19 | 75 | <div className="flex items-center gap-2">
|
20 | 76 | <FaTruck size={20} />
|
|
0 commit comments