From fbfcb71d6118135cfcc926b26f2d3d7957c8e668 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 13 Jul 2026 11:51:56 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20driver=20delivery=20UX=20=E2=80=94=20rem?= =?UTF-8?q?ove=20=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B6=D0=B5=D0=BD=D0=BE=20?= =?UTF-8?q?status,=20fix=20checkbox=20reset,=20fix=20confirmed=20label?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Remove "Загружено" status from driver workflow — driver goes directly Назначен водитель → Доставлено (or Проблема) 2. Driver can undo "Доставлено" → "Вернуть в работу" (back to Назначен водитель) 3. Fix checkbox reset: shippedItems only resets when order ID changes, not on every order data refetch — driver can toggle items freely 4. Fix "confirmed" showing in SMS status card — add Russian label 5. onResetStatus resets to driver_assigned, not loaded 6. ShipmentPanel "Сбросить" works for all active statuses --- src/components/driver/DriverDeliveryDetail.jsx | 13 +++++-------- src/components/driver/DriverShipmentPanel.jsx | 18 ++++++++++++------ src/components/orders/OrderDetailPanel.jsx | 15 +++++++-------- src/components/orders/SmsStatusCard.jsx | 2 ++ src/constants/deliveryWorkflow.js | 8 ++++---- src/services/orderGroupViews.js | 2 +- 6 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/components/driver/DriverDeliveryDetail.jsx b/src/components/driver/DriverDeliveryDetail.jsx index 700c487..8a1cf69 100644 --- a/src/components/driver/DriverDeliveryDetail.jsx +++ b/src/components/driver/DriverDeliveryDetail.jsx @@ -74,21 +74,18 @@ export const DriverDeliveryDetail = ({ order, onStatusChange }) => { const orderItems = Array.isArray(order.items) ? order.items.map(splitItem) : []; const currentStatus = order.status; - const IN_TRANSIT_STATUSES = ["Загружен", "В пути"]; - const isOnRoute = IN_TRANSIT_STATUSES.includes(currentStatus); let actionButtons = []; if (currentStatus === "Назначен водитель") { - actionButtons = [ - { value: "Загружен", label: "Загружено" }, - { value: "Проблема доставки", label: "Проблема" }, - ]; - } else if (isOnRoute) { actionButtons = [ { value: "Доставлен", label: "Доставлено" }, { value: "Проблема доставки", label: "Проблема" }, ]; - } else if (currentStatus === "Доставлен" || currentStatus === "Вывезено" || currentStatus === "Проблема доставки" || currentStatus === "Закрыт" || currentStatus === "Отменён") { + } else if (currentStatus === "Доставлен") { + actionButtons = [ + { value: "Назначен водитель", label: "Вернуть в работу" }, + ]; + } else if (currentStatus === "Проблема доставки" || currentStatus === "Закрыт" || currentStatus === "Отменён") { actionButtons = []; } else { actionButtons = availableTransitions.map((status) => ({ diff --git a/src/components/driver/DriverShipmentPanel.jsx b/src/components/driver/DriverShipmentPanel.jsx index cf85859..b5a93a6 100644 --- a/src/components/driver/DriverShipmentPanel.jsx +++ b/src/components/driver/DriverShipmentPanel.jsx @@ -138,11 +138,17 @@ export const DriverShipmentPanel = ({ order, onShipmentChange, onSaveShipment, i const [comments, setComments] = React.useState(initialComments); const [commentInput, setCommentInput] = React.useState(""); - // Sync state when order data changes (e.g. after save) + // Sync state ONLY when order ID changes (navigating to different order), not on every order data update + const orderId = order?.id; + const prevOrderId = React.useRef(orderId); React.useEffect(() => { - setShippedItems(initialShippedIds); - setComments(initialComments); - }, [initialShippedIds, initialComments]); + if (prevOrderId.current !== orderId) { + prevOrderId.current = orderId; + setShippedItems(initialShippedIds); + setComments(initialComments); + setJustSaved(false); + } + }, [orderId, initialShippedIds, initialComments]); // Track last saved shipment data for visual display React.useEffect(() => { @@ -170,7 +176,7 @@ export const DriverShipmentPanel = ({ order, onShipmentChange, onSaveShipment, i }; const currentDeliveryStatus = order?.deliveryStatus || order?.delivery_status; - const isStatusFinal = ["delivered", "problem", "picked_up"].includes(currentDeliveryStatus); + const isStatusFinal = ["delivered", "problem", "picked_up", "loaded", "on_route", "driver_assigned"].includes(currentDeliveryStatus); const unshipAll = () => { if (isStatusFinal && onResetStatus) { @@ -250,7 +256,7 @@ export const DriverShipmentPanel = ({ order, onShipmentChange, onSaveShipment, i Отгрузить всё diff --git a/src/components/orders/OrderDetailPanel.jsx b/src/components/orders/OrderDetailPanel.jsx index 3d8cc74..dd1b570 100644 --- a/src/components/orders/OrderDetailPanel.jsx +++ b/src/components/orders/OrderDetailPanel.jsx @@ -1102,7 +1102,7 @@ export const OrderDetailPanel = ({ if (onChangeDeliveryStatus) { onChangeDeliveryStatus({ orderGroupId: order.id, - status: "loaded", + status: "driver_assigned", }).then((response) => { if (!response.success) { setFormMessage(response.error || "Не удалось сбросить статус"); @@ -1136,15 +1136,15 @@ export const OrderDetailPanel = ({
{(() => { const currentStatus = order.deliveryStatus || order.delivery_status; - const IN_TRANSIT_STATUSES = ["loaded", "on_route"]; - const isOnRoute = IN_TRANSIT_STATUSES.includes(currentStatus); const isPickup = (order.deliveryType || order.delivery_type) === "pickup" || currentStatus === "pickup"; - + let statusOptions = []; - if (currentStatus === "delivered" || currentStatus === "picked_up" || currentStatus === "problem" || currentStatus === "cancelled" || currentStatus === "paid_storage") { + if (currentStatus === "delivered" || currentStatus === "picked_up" || currentStatus === "problem") { + // Final statuses — show "Return to work" instead + statusOptions = []; + } else if (currentStatus === "cancelled" || currentStatus === "paid_storage") { statusOptions = []; } else { - // Primary button matches delivery type, secondary requires confirmation if (isPickup) { statusOptions = [ { value: "picked_up", label: "Вывезено", mismatch: false }, @@ -1160,7 +1160,6 @@ export const OrderDetailPanel = ({ } } - // "Return to work" button for final statuses const canReturn = ["delivered", "picked_up", "problem"].includes(currentStatus); if (statusOptions.length === 0 && !canReturn) return null; @@ -1201,7 +1200,7 @@ export const OrderDetailPanel = ({ disabled={isSavingStatusChange} onClick={() => { setPendingStatus({ - value: "loaded", + value: "driver_assigned", label: "Вернуть в работу", mismatch: false, deliveryType: "delivery", diff --git a/src/components/orders/SmsStatusCard.jsx b/src/components/orders/SmsStatusCard.jsx index 3f56c95..7be2971 100644 --- a/src/components/orders/SmsStatusCard.jsx +++ b/src/components/orders/SmsStatusCard.jsx @@ -22,6 +22,7 @@ const NOTIF_LABELS = { paid_storage_sending: "Отправляется…", paid_storage_sent: "Платное хранение: отправлено", draft: "Черновик", + confirmed: "Согласовано", }; const NOTIF_TONES = { @@ -36,6 +37,7 @@ const NOTIF_TONES = { paid_storage_sending: "info", paid_storage_sent: "accent", draft: "neutral", + confirmed: "accent", }; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/src/constants/deliveryWorkflow.js b/src/constants/deliveryWorkflow.js index 15f1491..dbad65b 100644 --- a/src/constants/deliveryWorkflow.js +++ b/src/constants/deliveryWorkflow.js @@ -240,10 +240,10 @@ export const ORDER_STATUS_TRANSITIONS = { "Ожидает согласования доставки": ["Доставка согласована", "Самовывоз", "Требуется адрес", "Проблема доставки", "Отменён"], "Доставка согласована": ["Назначен водитель", "Ожидает согласования доставки", "Проблема доставки", "Самовывоз", "Требуется адрес"], "Передан логисту": ["Доставка согласована", "Платное хранение", "Проблема доставки", "Отменён"], - "Назначен водитель": ["Загружен", "Проблема доставки"], + "Назначен водитель": ["Доставлен", "Проблема доставки"], Загружен: ["Доставлен", "Проблема доставки"], "В пути": ["Доставлен", "Проблема доставки"], - Доставлен: ["Закрыт"], + Доставлен: ["Закрыт", "Назначен водитель"], "Проблема доставки": ["Ожидает согласования доставки", "Назначен водитель", "Отменён", "Закрыт"], "Платное хранение": ["Доставка согласована", "Отменён", "Закрыт"], "Самовывоз": ["Доставка согласована", "Закрыт", "Отменён", "Платное хранение"], @@ -270,7 +270,7 @@ export const ROLE_TRANSITION_TARGETS = { "Закрыт", "Отменён", ], - driver: ["Загружен", "Доставлен", "Проблема доставки"], + driver: ["Доставлен", "Проблема доставки"], admin: ORDER_STATUSES, }; @@ -291,7 +291,7 @@ export const LOGISTICS_STATUSES = [ "Проблема доставки", ]; -export const DRIVER_STATUSES = ["Назначен водитель", "Загружен", "Доставлен"]; +export const DRIVER_STATUSES = ["Назначен водитель", "Доставлен"]; export const getOrderStatusComment = (status) => ORDER_STATUS_META[status]?.comment || "Комментарий не задан."; diff --git a/src/services/orderGroupViews.js b/src/services/orderGroupViews.js index 398b3bc..ce748ce 100644 --- a/src/services/orderGroupViews.js +++ b/src/services/orderGroupViews.js @@ -39,7 +39,7 @@ export const DRIVER_VISIBLE_DELIVERY_STATUSES = [ "paid_storage", ]; -export const DRIVER_ACTIVE_DELIVERY_STATUSES = ["driver_assigned", "loaded", "on_route", "problem"]; +export const DRIVER_ACTIVE_DELIVERY_STATUSES = ["driver_assigned", "problem"]; const HALF_DAY_LABELS = { morning: "Первая половина дня",