import React, { useState, useEffect } from 'react'; import { Order, WaybillEntry } from '../types'; import { waybillApi, ordersApi } from '../services/api'; import Loading from '../components/Loading'; import ErrorAlert from '../components/ErrorAlert'; interface WaybillWidgetProps { vehicleId: number; date: string; } const WaybillWidget: React.FC = ({ vehicleId, date }) => { const [entries, setEntries] = useState([]); const [orders, setOrders] = useState([]); const [availableOrders, setAvailableOrders] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedOrder, setSelectedOrder] = useState(null); const [selectedTimeSlot, setSelectedTimeSlot] = useState(null); const [duration, setDuration] = useState(2); const timeSlots = Array.from({ length: 13 }, (_, i) => { const hour = i + 8; return `${hour.toString().padStart(2, '0')}:00`; }); const loadData = async () => { try { const response = await ordersApi.getOrders(); setOrders((response.data as any).data.items); setLoading(true); setError(null); const entriesResponse = (await waybillApi.getEntries() as any).data; const vehicleEntries = entriesResponse.data.filter( (entry: { vehicleId: number; date: string; }) => entry.vehicleId === vehicleId && entry.date === date ); setEntries(vehicleEntries); const ordersResponse = (await ordersApi.getOrders() as any).data.data.items; const assignedOrderIds = new Set(vehicleEntries.map((entry: { orderId: any; }) => entry.orderId)); const available = ordersResponse.filter( (order: Order) => !assignedOrderIds.has(order.id) && order.status !== 'completed' ); setAvailableOrders(available); } catch (err) { setError('Не удалось загрузить данные путевого листа'); console.error('Error loading waybill data:', err); } finally { setLoading(false); } }; useEffect(() => { loadData(); }, [vehicleId, date]); const getOrderForTimeSlot = (timeSlot: string): WaybillEntry | undefined => { return entries.find(entry => { const startHour = parseInt(entry.startTime.split(':')[0]); const endHour = parseInt(entry.endTime.split(':')[0]); const slotHour = parseInt(timeSlot.split(':')[0]); return slotHour >= startHour && slotHour < endHour; }); }; const getOrderInfo = (orderId: number, allOrders: Order[]): Order | undefined => { const foundOrder = allOrders.find(order => order.id === orderId); if (foundOrder) { return foundOrder; } const waybillEntry = entries.find(entry => entry.orderId === orderId); if (waybillEntry) { const basicOrder: Order = { id: waybillEntry.orderId, clientName: `Заказ #${waybillEntry.orderId}`, orderCost: 0, orderDate: new Date().toISOString().split('T')[0], status: 'in_progress' as const, address: 'Адрес не указан', description: 'Заказ запланирован в путевом листе' }; return basicOrder; } return undefined; }; const handleTimeSlotClick = async (timeSlot: string) => { if (selectedOrder) { try { const startHour = parseInt(timeSlot.split(':')[0]); const endHour = startHour + duration; const newEntry: Omit = { vehicleId, orderId: selectedOrder.id, startTime: timeSlot, endTime: `${endHour.toString().padStart(2, '0')}:00`, date }; console.log('Sending waybill entry:', newEntry); await waybillApi.createEntry(newEntry); setSelectedOrder(null); setSelectedTimeSlot(null); await loadData(); } catch (err) { setError('Не удалось добавить заказ в путевой лист'); console.error('Error creating waybill entry:', err); } } else { setSelectedTimeSlot(timeSlot); } }; const handleOrderSelect = async (order: Order) => { if (selectedTimeSlot) { try { const startHour = parseInt(selectedTimeSlot.split(':')[0]); const endHour = startHour + duration; const newEntry: Omit = { vehicleId, orderId: order.id, startTime: selectedTimeSlot, endTime: `${endHour.toString().padStart(2, '0')}:00`, date }; console.log('Sending waybill entry:', newEntry); await waybillApi.createEntry(newEntry); setSelectedTimeSlot(null); setSelectedOrder(null); await loadData(); } catch (err) { setError('Не удалось добавить заказ в путевой лист'); console.error('Error creating waybill entry:', err); } } else { setSelectedOrder(order); } }; const handleRemoveEntry = async (entryId: number) => { try { await waybillApi.deleteEntry(entryId); await loadData(); } catch (err) { setError('Не удалось удалить запись из путевого листа'); console.error('Error deleting waybill entry:', err); } }; if (loading) return ; if (error) return ; return (
Путевой лист на {new Date(date).toLocaleDateString()}
{selectedOrder && !selectedTimeSlot && (

Выбран заказ: {selectedOrder.clientName}. Теперь выберите время.

setDuration(parseInt(e.target.value) || 1)} style={{ width: '100px', display: 'inline-block', marginLeft: '10px' }} />
)} {selectedTimeSlot && !selectedOrder && (

Выбрано время: {selectedTimeSlot}. Теперь выберите заказ.

setDuration(parseInt(e.target.value) || 1)} style={{ width: '100px', display: 'inline-block', marginLeft: '10px' }} />
)} {!selectedOrder && !selectedTimeSlot && (

Выберите время или заказ для планирования доставки.

)} {selectedOrder && selectedTimeSlot && (

Готово к добавлению: {selectedOrder.clientName} на время {selectedTimeSlot} продолжительностью {duration} час(ов)

)}
{timeSlots.map(timeSlot => { const entry = getOrderForTimeSlot(timeSlot); const order = entry ? getOrderInfo(entry.orderId, orders) : undefined; return ( ); })}
Время Заказ Действия
{timeSlot} {order ? (
{order.clientName}
{order.address}
) : ( Свободно )}
{order && entry ? ( ) : ( )}
Доступные заказы:
{availableOrders.map(order => (
handleOrderSelect(order)} >
{order.clientName}

{order.address}

{order.orderCost.toLocaleString()} руб.

))}
); }; export default WaybillWidget;