120 lines
3.9 KiB
JavaScript
120 lines
3.9 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
||
import { getDeliveryAccessories } from "../api.jsx";
|
||
import { useParams } from "react-router-dom";
|
||
import { getCoordinates } from "../geocoder.jsx";
|
||
import {
|
||
MapContainer,
|
||
TileLayer,
|
||
Marker,
|
||
Popup,
|
||
Polyline,
|
||
} from "react-leaflet";
|
||
import polyline from "@mapbox/polyline";
|
||
import "./DeliveryOrderDetails.css";
|
||
|
||
const DeliveryOrderDetails = () => {
|
||
const { id: deliveryOrderId } = useParams();
|
||
const [deliveryAccessories, setDeliveryAccessories] = useState([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [coordinates, setCoordinates] = useState([]);
|
||
const [route, setRoute] = useState([]);
|
||
|
||
useEffect(() => {
|
||
fetchDeliveryAccessories();
|
||
}, [deliveryOrderId]);
|
||
|
||
const fetchDeliveryAccessories = async () => {
|
||
try {
|
||
const accessories = await getDeliveryAccessories(deliveryOrderId);
|
||
setDeliveryAccessories(accessories);
|
||
|
||
const coords = await Promise.all(
|
||
accessories.map(async (accessory) => {
|
||
const coords = await getCoordinates(accessory.city_name);
|
||
return { city: accessory.city_name, ...coords };
|
||
})
|
||
);
|
||
setCoordinates(coords);
|
||
|
||
if (coords.length > 1) {
|
||
const waypoints = coords
|
||
.map(({ longitude, latitude }) => `${longitude},${latitude}`)
|
||
.join(";");
|
||
const routeUrl = `https://router.project-osrm.org/route/v1/driving/${waypoints}?overview=full`;
|
||
|
||
const response = await fetch(routeUrl);
|
||
const data = await response.json();
|
||
|
||
if (data.routes && data.routes.length > 0) {
|
||
const geometry = data.routes[0].geometry;
|
||
const decodedRoute = polyline.decode(geometry);
|
||
setRoute(decodedRoute);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error("Ошибка при загрузке доставок:", error);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="delivery-order-details">
|
||
{loading ? (
|
||
<div className="spinner-border" role="status">
|
||
<span className="visually-hidden">Загрузка...</span>
|
||
</div>
|
||
) : (
|
||
<div className="content-container">
|
||
<ol className="city-list">
|
||
{deliveryAccessories.map((accessory) => {
|
||
const coord = coordinates.find(
|
||
(c) => c.city === accessory.city_name
|
||
);
|
||
return (
|
||
<li key={accessory.id} className="city-item">
|
||
<strong>Доставка:</strong> {accessory.name}
|
||
<span className="city-info">
|
||
(Город: {accessory.city_name}, Координаты:{" "}
|
||
{coord
|
||
? `${coord.latitude}, ${coord.longitude}`
|
||
: "Не найдены"}
|
||
)
|
||
</span>
|
||
</li>
|
||
);
|
||
})}
|
||
</ol>
|
||
{coordinates.length > 0 && (
|
||
<div className="map-container">
|
||
<MapContainer
|
||
center={[coordinates[0].latitude, coordinates[0].longitude]}
|
||
zoom={5}
|
||
style={{ height: "400px", width: "100%" }}
|
||
>
|
||
<TileLayer
|
||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||
/>
|
||
{coordinates.map((coord, index) => (
|
||
<Marker
|
||
key={index}
|
||
position={[coord.latitude, coord.longitude]}
|
||
>
|
||
<Popup>{coord.city}</Popup>
|
||
</Marker>
|
||
))}
|
||
{route.length > 0 && (
|
||
<Polyline positions={route} color="blue" />
|
||
)}
|
||
</MapContainer>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default DeliveryOrderDetails;
|