feat: Add MapComponent for displaying location on a map and TrackingPage for tracking shipments

This commit is contained in:
2025-07-10 10:55:42 +02:00
parent 32672387a6
commit 8ef7fb9230
3 changed files with 438 additions and 1 deletions

View File

@@ -0,0 +1,68 @@
import { useEffect, useState } from 'react';
const MapComponent = ({ latitude, longitude, name, description, officeType }) => {
const [mapLoaded, setMapLoaded] = useState(false);
useEffect(() => {
// Load Leaflet on client-side only
if (typeof window !== 'undefined' && latitude && longitude) {
// Import Leaflet dynamically
import('leaflet').then((L) => {
// Safety check to see if map element exists
const mapElement = document.getElementById('map');
if (!mapElement) return;
// Clean up any existing map instance
if (mapElement._leaflet_map) {
mapElement._leaflet_map.remove();
}
// Initialize map
const map = L.map('map').setView([latitude, longitude], 15);
// Store the map instance on the DOM element to clean up later
mapElement._leaflet_map = map;
// Add OpenStreetMap tiles
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 19
}).addTo(map);
// Add marker for post office
const marker = L.marker([latitude, longitude])
.addTo(map)
.bindPopup(`
<div style="font-family: 'Segoe UI', sans-serif;">
<h4 style="margin: 0 0 8px 0; color: #004d99;">${name}</h4>
<p style="margin: 4px 0;"><strong>📍 Adres:</strong><br>${description.street} ${description.houseNumber}<br>${description.zipCode} ${description.city}</p>
<p style="margin: 4px 0;"><strong>🏢 Typ:</strong> ${officeType === 'UP' ? 'Urząd Pocztowy' : officeType}</p>
</div>
`, {
maxWidth: 300
});
// Open popup by default
marker.openPopup();
// Make sure map renders correctly
setTimeout(() => {
map.invalidateSize();
setMapLoaded(true);
}, 300);
});
}
// Clean up function
return () => {
const mapElement = document.getElementById('map');
if (mapElement && mapElement._leaflet_map) {
mapElement._leaflet_map.remove();
}
};
}, [latitude, longitude, name, description, officeType]);
return <div id="map" style={{ height: '400px', borderRadius: '8px' }}></div>;
};
export default MapComponent;

View File

@@ -10,13 +10,15 @@ import {
Bars3Icon as MenuIcon,
XMarkIcon as XIcon,
UserIcon,
ArrowRightOnRectangleIcon as LogoutIcon
ArrowRightOnRectangleIcon as LogoutIcon,
TruckIcon
} from '@heroicons/react/24/outline';
const navigationItems = [
{ name: 'Przekrój terenu', href: '/', icon: HomeIcon },
{ name: 'Siatka', href: '/cross', icon: GridIcon },
{ name: 'Uziomy', href: '/uziomy', icon: LightningBoltIcon },
{ name: 'Śledzenie przesyłek', href: '/tracking', icon: TruckIcon },
];
export default function Layout({ children, title = 'Wastpol' }) {