fix: driver delivery UX — remove Загружено status, fix checkbox reset, fix confirmed label
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
This commit is contained in:
parent
1766ccb897
commit
fbfcb71d61
|
|
@ -74,21 +74,18 @@ export const DriverDeliveryDetail = ({ order, onStatusChange }) => {
|
||||||
const orderItems = Array.isArray(order.items) ? order.items.map(splitItem) : [];
|
const orderItems = Array.isArray(order.items) ? order.items.map(splitItem) : [];
|
||||||
|
|
||||||
const currentStatus = order.status;
|
const currentStatus = order.status;
|
||||||
const IN_TRANSIT_STATUSES = ["Загружен", "В пути"];
|
|
||||||
const isOnRoute = IN_TRANSIT_STATUSES.includes(currentStatus);
|
|
||||||
|
|
||||||
let actionButtons = [];
|
let actionButtons = [];
|
||||||
if (currentStatus === "Назначен водитель") {
|
if (currentStatus === "Назначен водитель") {
|
||||||
actionButtons = [
|
|
||||||
{ value: "Загружен", label: "Загружено" },
|
|
||||||
{ value: "Проблема доставки", label: "Проблема" },
|
|
||||||
];
|
|
||||||
} else if (isOnRoute) {
|
|
||||||
actionButtons = [
|
actionButtons = [
|
||||||
{ value: "Доставлен", label: "Доставлено" },
|
{ value: "Доставлен", label: "Доставлено" },
|
||||||
{ value: "Проблема доставки", label: "Проблема" },
|
{ value: "Проблема доставки", label: "Проблема" },
|
||||||
];
|
];
|
||||||
} else if (currentStatus === "Доставлен" || currentStatus === "Вывезено" || currentStatus === "Проблема доставки" || currentStatus === "Закрыт" || currentStatus === "Отменён") {
|
} else if (currentStatus === "Доставлен") {
|
||||||
|
actionButtons = [
|
||||||
|
{ value: "Назначен водитель", label: "Вернуть в работу" },
|
||||||
|
];
|
||||||
|
} else if (currentStatus === "Проблема доставки" || currentStatus === "Закрыт" || currentStatus === "Отменён") {
|
||||||
actionButtons = [];
|
actionButtons = [];
|
||||||
} else {
|
} else {
|
||||||
actionButtons = availableTransitions.map((status) => ({
|
actionButtons = availableTransitions.map((status) => ({
|
||||||
|
|
|
||||||
|
|
@ -138,11 +138,17 @@ export const DriverShipmentPanel = ({ order, onShipmentChange, onSaveShipment, i
|
||||||
const [comments, setComments] = React.useState(initialComments);
|
const [comments, setComments] = React.useState(initialComments);
|
||||||
const [commentInput, setCommentInput] = React.useState("");
|
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(() => {
|
React.useEffect(() => {
|
||||||
setShippedItems(initialShippedIds);
|
if (prevOrderId.current !== orderId) {
|
||||||
setComments(initialComments);
|
prevOrderId.current = orderId;
|
||||||
}, [initialShippedIds, initialComments]);
|
setShippedItems(initialShippedIds);
|
||||||
|
setComments(initialComments);
|
||||||
|
setJustSaved(false);
|
||||||
|
}
|
||||||
|
}, [orderId, initialShippedIds, initialComments]);
|
||||||
|
|
||||||
// Track last saved shipment data for visual display
|
// Track last saved shipment data for visual display
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
|
@ -170,7 +176,7 @@ export const DriverShipmentPanel = ({ order, onShipmentChange, onSaveShipment, i
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentDeliveryStatus = order?.deliveryStatus || order?.delivery_status;
|
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 = () => {
|
const unshipAll = () => {
|
||||||
if (isStatusFinal && onResetStatus) {
|
if (isStatusFinal && onResetStatus) {
|
||||||
|
|
@ -250,7 +256,7 @@ export const DriverShipmentPanel = ({ order, onShipmentChange, onSaveShipment, i
|
||||||
Отгрузить всё
|
Отгрузить всё
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" size="sm" onClick={unshipAll} disabled={shippedCount === 0 && !isStatusFinal}>
|
<Button variant="ghost" size="sm" onClick={unshipAll} disabled={shippedCount === 0 && !isStatusFinal}>
|
||||||
Сбросить
|
Сбросить отгрузку
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1102,7 +1102,7 @@ export const OrderDetailPanel = ({
|
||||||
if (onChangeDeliveryStatus) {
|
if (onChangeDeliveryStatus) {
|
||||||
onChangeDeliveryStatus({
|
onChangeDeliveryStatus({
|
||||||
orderGroupId: order.id,
|
orderGroupId: order.id,
|
||||||
status: "loaded",
|
status: "driver_assigned",
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
if (!response.success) {
|
if (!response.success) {
|
||||||
setFormMessage(response.error || "Не удалось сбросить статус");
|
setFormMessage(response.error || "Не удалось сбросить статус");
|
||||||
|
|
@ -1136,15 +1136,15 @@ export const OrderDetailPanel = ({
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2">
|
||||||
{(() => {
|
{(() => {
|
||||||
const currentStatus = order.deliveryStatus || order.delivery_status;
|
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";
|
const isPickup = (order.deliveryType || order.delivery_type) === "pickup" || currentStatus === "pickup";
|
||||||
|
|
||||||
let statusOptions = [];
|
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 = [];
|
statusOptions = [];
|
||||||
} else {
|
} else {
|
||||||
// Primary button matches delivery type, secondary requires confirmation
|
|
||||||
if (isPickup) {
|
if (isPickup) {
|
||||||
statusOptions = [
|
statusOptions = [
|
||||||
{ value: "picked_up", label: "Вывезено", mismatch: false },
|
{ 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);
|
const canReturn = ["delivered", "picked_up", "problem"].includes(currentStatus);
|
||||||
|
|
||||||
if (statusOptions.length === 0 && !canReturn) return null;
|
if (statusOptions.length === 0 && !canReturn) return null;
|
||||||
|
|
@ -1201,7 +1200,7 @@ export const OrderDetailPanel = ({
|
||||||
disabled={isSavingStatusChange}
|
disabled={isSavingStatusChange}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setPendingStatus({
|
setPendingStatus({
|
||||||
value: "loaded",
|
value: "driver_assigned",
|
||||||
label: "Вернуть в работу",
|
label: "Вернуть в работу",
|
||||||
mismatch: false,
|
mismatch: false,
|
||||||
deliveryType: "delivery",
|
deliveryType: "delivery",
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ const NOTIF_LABELS = {
|
||||||
paid_storage_sending: "Отправляется…",
|
paid_storage_sending: "Отправляется…",
|
||||||
paid_storage_sent: "Платное хранение: отправлено",
|
paid_storage_sent: "Платное хранение: отправлено",
|
||||||
draft: "Черновик",
|
draft: "Черновик",
|
||||||
|
confirmed: "Согласовано",
|
||||||
};
|
};
|
||||||
|
|
||||||
const NOTIF_TONES = {
|
const NOTIF_TONES = {
|
||||||
|
|
@ -36,6 +37,7 @@ const NOTIF_TONES = {
|
||||||
paid_storage_sending: "info",
|
paid_storage_sending: "info",
|
||||||
paid_storage_sent: "accent",
|
paid_storage_sent: "accent",
|
||||||
draft: "neutral",
|
draft: "neutral",
|
||||||
|
confirmed: "accent",
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── Helpers ──────────────────────────────────────────────────────────────────
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -240,10 +240,10 @@ export const ORDER_STATUS_TRANSITIONS = {
|
||||||
"Ожидает согласования доставки": ["Доставка согласована", "Самовывоз", "Требуется адрес", "Проблема доставки", "Отменён"],
|
"Ожидает согласования доставки": ["Доставка согласована", "Самовывоз", "Требуется адрес", "Проблема доставки", "Отменён"],
|
||||||
"Доставка согласована": ["Назначен водитель", "Ожидает согласования доставки", "Проблема доставки", "Самовывоз", "Требуется адрес"],
|
"Доставка согласована": ["Назначен водитель", "Ожидает согласования доставки", "Проблема доставки", "Самовывоз", "Требуется адрес"],
|
||||||
"Передан логисту": ["Доставка согласована", "Платное хранение", "Проблема доставки", "Отменён"],
|
"Передан логисту": ["Доставка согласована", "Платное хранение", "Проблема доставки", "Отменён"],
|
||||||
"Назначен водитель": ["Загружен", "Проблема доставки"],
|
"Назначен водитель": ["Доставлен", "Проблема доставки"],
|
||||||
Загружен: ["Доставлен", "Проблема доставки"],
|
Загружен: ["Доставлен", "Проблема доставки"],
|
||||||
"В пути": ["Доставлен", "Проблема доставки"],
|
"В пути": ["Доставлен", "Проблема доставки"],
|
||||||
Доставлен: ["Закрыт"],
|
Доставлен: ["Закрыт", "Назначен водитель"],
|
||||||
"Проблема доставки": ["Ожидает согласования доставки", "Назначен водитель", "Отменён", "Закрыт"],
|
"Проблема доставки": ["Ожидает согласования доставки", "Назначен водитель", "Отменён", "Закрыт"],
|
||||||
"Платное хранение": ["Доставка согласована", "Отменён", "Закрыт"],
|
"Платное хранение": ["Доставка согласована", "Отменён", "Закрыт"],
|
||||||
"Самовывоз": ["Доставка согласована", "Закрыт", "Отменён", "Платное хранение"],
|
"Самовывоз": ["Доставка согласована", "Закрыт", "Отменён", "Платное хранение"],
|
||||||
|
|
@ -270,7 +270,7 @@ export const ROLE_TRANSITION_TARGETS = {
|
||||||
"Закрыт",
|
"Закрыт",
|
||||||
"Отменён",
|
"Отменён",
|
||||||
],
|
],
|
||||||
driver: ["Загружен", "Доставлен", "Проблема доставки"],
|
driver: ["Доставлен", "Проблема доставки"],
|
||||||
admin: ORDER_STATUSES,
|
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 || "Комментарий не задан.";
|
export const getOrderStatusComment = (status) => ORDER_STATUS_META[status]?.comment || "Комментарий не задан.";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export const DRIVER_VISIBLE_DELIVERY_STATUSES = [
|
||||||
"paid_storage",
|
"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 = {
|
const HALF_DAY_LABELS = {
|
||||||
morning: "Первая половина дня",
|
morning: "Первая половина дня",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue