import { formatDateTime } from "../../utils/formatters"; import { Badge } from "../UI/Badge"; import { Panel } from "../UI/Panel"; import { SkeletonTable } from "../UI/Loading"; import { OrderFilters } from "./OrderFilters"; import { getOrderGroupDisplayStatusLabel, getOrderGroupStatusTone, } from "../../services/orderGroupViews"; const MAX_VISIBLE_INVOICES = 2; const TERMINAL_STATUSES = ["delivered", "picked_up", "cancelled"]; const fmtDate = (d) => { if (!d) return ''; const [y, m, day] = d.split('-'); if (!y || !m || !day) return d; return `${day}.${m}.${y}`; }; const hasNoSms = (group) => { if (!group) return false; if (group.firstSmsSentAt) return false; if (TERMINAL_STATUSES.includes(group.deliveryStatus)) return false; return true; }; const getDaysSinceCreation = (group) => { if (!group) return null; const ts = group.createdFromExchangeAt || group.createdAt || group.updatedAt; if (!ts) return null; const days = Math.floor((Date.now() - new Date(ts)) / 86400000); return days < 0 ? 0 : days; }; const getDaysColorClass = (days) => { if (days == null) return "text-[var(--color-text-muted)]"; if (days < 3) return "text-[var(--color-text)]"; if (days <= 7) return "text-[var(--color-warning)]"; return "text-[var(--color-danger)]"; }; const getShipmentIssues = (group) => { const data = group?.driverShipmentData; if (!Array.isArray(data) || data.length === 0) return null; const unshipped = data.filter((i) => !i.shipped); if (unshipped.length === 0) return null; return unshipped; }; const buildGroupSummary = (group) => { const orderCountLabel = `${group.ordersCount || 0} ${group.ordersCount === 1 ? "заказ" : group.ordersCount < 5 ? "заказа" : "заказов"}`; const parts = [orderCountLabel]; if (group.deliveryDate) { const datePart = group.deliveryTime ? `${fmtDate(group.deliveryDate)} · ${group.deliveryTime}` : fmtDate(group.deliveryDate); parts.push(datePart); } if (group.assignedDriverName) { parts.push(group.assignedDriverName); } return parts.join(" · "); }; const renderOrderNumbers = (group) => { const numbers = group.allBillNumbers || group.orderNumbers; if (!Array.isArray(numbers) || !numbers.length) { return "Номера не указаны"; } if (numbers.length <= MAX_VISIBLE_INVOICES) { return numbers.join(", "); } const visible = numbers.slice(0, MAX_VISIBLE_INVOICES); const remaining = numbers.length - MAX_VISIBLE_INVOICES; return `${visible.join(", ")} +${remaining}`; }; const getDeliveryTypeLabel = (deliveryType) => { if (deliveryType === "pickup") return "Самовывоз"; if (deliveryType === "delivery") return "Доставка"; return "—"; }; const renderMobileOrderNumbers = (group) => { const numbers = group.allBillNumbers || group.orderNumbers; if (!Array.isArray(numbers) || !numbers.length) { return "Номера не указаны"; } if (numbers.length <= MAX_VISIBLE_INVOICES) { return numbers.join(", "); } const visible = numbers.slice(0, MAX_VISIBLE_INVOICES); const remaining = numbers.length - MAX_VISIBLE_INVOICES; return ( <> {visible.join(", ")} +{remaining} ); }; export const OrdersTable = ({ orderGroups = [], selectedOrderGroupId, onOpenOrder, filters, setFilters, statusOptions, cities = [], isLoading = false, }) => { if (isLoading) { return ; } return (

Группы доставки

Поиск по группе, клиенту, телефону и дате доставки.

{orderGroups.length}
{filters && setFilters ? ( ) : null}
{!orderGroups.length ? (
Группы не найдены. Попробуйте изменить поиск или статус.
) : null} {orderGroups.map((group) => { const hasProblem = group.hasDeliveryProblem; const noSms = hasNoSms(group); const days = getDaysSinceCreation(group); const baseClass = "w-full rounded-[22px] border text-left transition"; const selectedClass = selectedOrderGroupId === group.id ? "border-[var(--color-accent)] bg-[var(--color-accent-soft)]" : hasProblem ? "border-[var(--color-danger)] bg-[rgba(201,61,61,0.1)]" : noSms ? "border-[var(--color-border)] bg-[rgba(245,158,11,0.05)]" : "border-[var(--color-border)] bg-[var(--color-surface-strong)]"; const allNumbers = group.allBillNumbers || group.orderNumbers || []; const primaryBill = allNumbers[0] || "—"; const totalCount = allNumbers.length; return (
№ {primaryBill} {totalCount > 1 && ( {totalCount} сч. )}
); })}
{!orderGroups.length ? (
Группы не найдены. Попробуйте изменить поиск или статус.
) : (
Группа / Клиент
Счета
Город
Статус
Дата доставки
Дней
Тип
Водитель
{orderGroups.map((group) => { const hasProblem = group.hasDeliveryProblem; const noSms = hasNoSms(group); const days = getDaysSinceCreation(group); let rowBg = ""; if (selectedOrderGroupId === group.id) { rowBg = "bg-[var(--color-accent-soft)]"; } else if (hasProblem) { rowBg = "bg-[rgba(201,61,61,0.1)] hover:bg-[rgba(201,61,61,0.15)]"; } else if (noSms) { rowBg = "bg-[rgba(245,158,11,0.05)] hover:bg-[rgba(245,158,11,0.1)]"; } else { rowBg = "hover:bg-[var(--color-accent-soft)]"; } const rowClassName = `grid grid-cols-[minmax(130px,2fr)_minmax(90px,1fr)_minmax(100px,0.8fr)_minmax(100px,1fr)_minmax(100px,1fr)_minmax(70px,0.5fr)_minmax(100px,0.8fr)_minmax(90px,0.8fr)] gap-0 w-full border-t border-[var(--color-border)] text-left transition ${rowBg}`; const billNumbers = group.allBillNumbers || group.orderNumbers || []; const primaryBill = billNumbers[0] || "—"; const totalBills = billNumbers.length; return ( ); })}
)}
); };