import { getDeliveryOrders, updateDeliveryOrderRoute, getDeliveryOrderDetails, getDeliveryAccessories, } from "../api.jsx"; import { getCoordinates } from "../geocoder.jsx"; import React, { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import polyline from "@mapbox/polyline"; import "./DeliveryOrdersList.css"; const DELIVERY_CITY = { name: "Челябинск", latitude: 55.159902, longitude: 61.402554, }; const DeliveryOrdersList = ({ totalOrderId, onSubOrderClick, setDeliveryOrdersCount, setTotalEstimatedTime, }) => { const [deliveryOrders, setDeliveryOrders] = useState([]); const [loadingDeliveryOrders, setLoadingDeliveryOrders] = useState(true); const [calculatingRoutes, setCalculatingRoutes] = useState([]); const [hoveredOrderId, setHoveredOrderId] = useState(null); const navigate = useNavigate(); useEffect(() => { fetchDeliveryOrders(); }, [totalOrderId]); const formatPrice = (price) => { if (!price) { return "не указана"; } return `${price.toFixed(2)} ₽`; }; const fetchDeliveryOrders = async () => { try { const orders = await getDeliveryOrders(totalOrderId); setDeliveryOrdersCount(orders.length); setDeliveryOrders(orders); const totalTime = orders.reduce((sum, order) => { return sum + (order.estimated_route_time_in_minutes || 0); }, 0); setTotalEstimatedTime(totalTime); } catch (error) { if (error.response && error.response.status === 401) { navigate("/login"); } console.error("Ошибка при загрузке подзаказов:", error); } finally { setLoadingDeliveryOrders(false); } }; const formatTimeInHours = (minutes) => { if (!minutes || minutes === 0) { return "ещё не рассчитывалось"; } return (minutes / 60).toFixed(2) + " час."; }; const calculateRoutes = async () => { const ordersToCalculate = deliveryOrders.filter( (order) => !order.estimated_route_time_in_minutes ); setCalculatingRoutes(ordersToCalculate.map((order) => order.id)); await Promise.all( ordersToCalculate.map(async (order) => { try { const deliveryOrderDetails = await getDeliveryOrderDetails(order.id); const accessories = await getDeliveryAccessories( deliveryOrderDetails.id ); const coords = await Promise.all( accessories.map(async (accessory) => { if (accessory.latitude && accessory.longitude) { return { city: accessory.city_name, latitude: accessory.latitude, longitude: accessory.longitude, accessory_name: accessory.accessory_name + Math.round( (accessory.accessory_volume * accessory.count) / 100 ) + "шт.", }; } else { const coords = await getCoordinates(accessory.city_name); return { city: accessory.city_name, accessory_name: accessory.accessory_name + ": " + Math.round( (accessory.accessory_volume * accessory.count) / 100 ) + "шт.", ...coords, }; } }) ); const fullCoordinates = [...coords, DELIVERY_CITY]; if (fullCoordinates.length > 1) { const waypoints = fullCoordinates .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); const duration = data.routes[0].duration; await updateDeliveryOrderRoute( order.id, duration / 60, decodedRoute ); } } } catch (error) { console.error("Ошибка при расчете маршрута для подзаказа:", error); } }) ); await fetchDeliveryOrders(); setCalculatingRoutes([]); }; const ordersToCalculate = deliveryOrders.filter( (order) => !order.estimated_route_time_in_minutes ); return (
{loadingDeliveryOrders ? (
) : ( <> {ordersToCalculate.length > 0 && ( )} {deliveryOrders.map((order, index) => (
onSubOrderClick(order.id)} onMouseEnter={() => setHoveredOrderId(order.id)} onMouseLeave={() => setHoveredOrderId(null)} >

Этап №{index + 1}

Прогнозируемое время этапа:{" "} {formatTimeInHours(order.estimated_route_time_in_minutes)}

Стоимость: {formatPrice(order.price)}

{calculatingRoutes.includes(order.id) && (
)} {hoveredOrderId === order.id && (

Нажмите, чтобы посмотреть подробную информацию

)}
))} )}
); }; export default DeliveryOrdersList;