fix: date format dd.MM.yyyy in logistics board, align columns via CSS grid

- LogisticsReadinessBoard: formatDate() for delivery date (was raw yyyy-MM-dd)
- LogisticsReadinessBoard: replaced <table> with CSS grid for aligned columns
- OrdersTable: replaced <table> with CSS grid for aligned columns
- Both tables: 6-column grid with fixed proportions, all columns visible
This commit is contained in:
root 2026-06-12 19:28:10 +00:00
parent d313a3b6b9
commit 491b7705fd
2 changed files with 69 additions and 79 deletions

View File

@ -10,7 +10,7 @@ import { Badge } from "../UI/Badge";
import { Panel } from "../UI/Panel";
import { SkeletonPage } from "../UI/Loading";
import { OrderFilters } from "../orders/OrderFilters";
import { formatDateTime } from "../../utils/formatters";
import { formatDate, formatDateTime } from "../../utils/formatters";
export const LogisticsReadinessBoard = ({ orderGroups = [], onSelectSet, statusOptions = ORDER_GROUP_DISPLAY_STATUS_OPTIONS, isLoading = false }) => {
const [filters, setFilters] = React.useState({ query: "", displayStatus: "all", city: "" });
@ -60,17 +60,17 @@ export const LogisticsReadinessBoard = ({ orderGroups = [], onSelectSet, statusO
const totalGroups = filteredGroups.length;
const COLS = "grid-cols-[minmax(140px,2fr)_minmax(80px,1fr)_minmax(100px,1.2fr)_minmax(80px,1fr)_minmax(100px,1fr)_minmax(120px,1fr)]";
const TableHeader = () => (
<thead className="bg-[var(--color-surface-strong)] text-left text-xs uppercase tracking-[0.14em] text-[var(--color-text-muted)]">
<tr>
<th className="px-4 py-3 font-medium">Клиент</th>
<th className="px-4 py-3 font-medium hidden sm:table-cell">Город</th>
<th className="px-4 py-3 font-medium hidden md:table-cell">Дата доставки</th>
<th className="px-4 py-3 font-medium hidden lg:table-cell">Водитель</th>
<th className="px-4 py-3 font-medium">Статус</th>
<th className="px-4 py-3 font-medium hidden md:table-cell">Обновлён</th>
</tr>
</thead>
<div className={`grid ${COLS} gap-0 border-b border-[var(--color-border)] bg-[var(--color-surface-strong)] text-xs uppercase tracking-[0.14em] text-[var(--color-text-muted)]`}>
<div className="px-4 py-3 font-medium">Клиент</div>
<div className="px-4 py-3 font-medium">Город</div>
<div className="px-4 py-3 font-medium">Дата доставки</div>
<div className="px-4 py-3 font-medium">Водитель</div>
<div className="px-4 py-3 font-medium">Статус</div>
<div className="px-4 py-3 font-medium">Обновлён</div>
</div>
);
if (isLoading) {
@ -146,42 +146,38 @@ export const LogisticsReadinessBoard = ({ orderGroups = [], onSelectSet, statusO
{!isCollapsed && (
<div className="overflow-x-auto">
<table className="min-w-full border-collapse border-t border-[var(--color-border)]">
<TableHeader />
<tbody>
{groups.map((group) => (
<tr
<button
key={group.id}
className="cursor-pointer border-t border-[var(--color-border)] transition hover:bg-[var(--color-accent-soft)]"
type="button"
className={`grid ${COLS} gap-0 w-full border-t border-[var(--color-border)] text-left transition hover:bg-[var(--color-accent-soft)]`}
onClick={() => { if (onSelectSet) onSelectSet(group.id); }}
>
<td className="px-4 py-2.5">
<div className="px-4 py-2.5">
<div className="font-medium">{group.displayTitle || group.customerName || group.groupKey}</div>
<div className="text-xs text-[var(--color-text-muted)] sm:hidden">{group.customerPhone || "—"}</div>
<div className="text-xs text-[var(--color-text-muted)] md:hidden">{group.deliveryDate || "—"}</div>
</td>
<td className="px-4 py-2.5 text-sm hidden sm:table-cell">
<div className="text-xs text-[var(--color-text-muted)]">{group.customerPhone || "—"}</div>
</div>
<div className="px-4 py-2.5 text-sm">
{group.city || group.customerAddress || "—"}
</td>
<td className="px-4 py-2.5 text-sm hidden md:table-cell">
</div>
<div className="px-4 py-2.5 text-sm">
{group.deliveryDate
? <span>{group.deliveryDate}{group.deliveryTime ? <span className="text-[var(--color-text-muted)]"> · {group.deliveryTime}</span> : ""}</span>
? <span>{formatDate(group.deliveryDate)}{group.deliveryTime ? <span className="text-[var(--color-text-muted)]"> · {group.deliveryTime}</span> : ""}</span>
: <span className="text-[var(--color-text-muted)]"></span>
}
</td>
<td className="px-4 py-2.5 text-sm hidden lg:table-cell">
</div>
<div className="px-4 py-2.5 text-sm">
{group.assignedDriverName || <span className="text-[var(--color-text-muted)]"></span>}
</td>
<td className="px-4 py-2.5">
</div>
<div className="px-4 py-2.5">
<Badge tone={getOrderGroupStatusTone(group)}>{getOrderGroupDisplayStatusLabel(group)}</Badge>
</td>
<td className="px-4 py-2.5 text-sm text-[var(--color-text-muted)] hidden md:table-cell">
</div>
<div className="px-4 py-2.5 text-sm text-[var(--color-text-muted)]">
{formatDateTime(group.updatedAt)}
</td>
</tr>
</div>
</button>
))}
</tbody>
</table>
</div>
)}
</Panel>

View File

@ -141,57 +141,51 @@ export const OrdersTable = ({
Группы не найдены. Попробуйте изменить поиск или статус.
</div>
) : (
<table className="min-w-full border-collapse">
<thead className="bg-[var(--color-surface-strong)] text-left text-xs uppercase tracking-[0.16em] text-[var(--color-text-muted)]">
<tr>
<th className="px-5 py-4 font-medium">Группа / Клиент</th>
<th className="px-5 py-4 font-medium">Счёта</th>
<th className="px-5 py-4 font-medium">Статус</th>
<th className="px-5 py-4 font-medium">Водитель</th>
<th className="px-5 py-4 font-medium">Дата доставки</th>
<th className="px-5 py-4 font-medium">Обновлён</th>
</tr>
</thead>
<tbody>
<div>
<div className="grid grid-cols-[minmax(180px,2.5fr)_minmax(100px,1.2fr)_minmax(100px,1fr)_minmax(80px,1fr)_minmax(120px,1.2fr)_minmax(130px,1.2fr)] gap-0 border-b border-[var(--color-border)] bg-[var(--color-surface-strong)] text-xs uppercase tracking-[0.16em] text-[var(--color-text-muted)]">
<div className="px-5 py-4 font-medium">Группа / Клиент</div>
<div className="px-5 py-4 font-medium">Счёта</div>
<div className="px-5 py-4 font-medium">Статус</div>
<div className="px-5 py-4 font-medium">Водитель</div>
<div className="px-5 py-4 font-medium">Дата доставки</div>
<div className="px-5 py-4 font-medium">Обновлён</div>
</div>
{orderGroups.map((group) => (
<tr
<button
key={group.id}
className={[
"cursor-pointer border-t border-[var(--color-border)] transition hover:bg-[var(--color-accent-soft)]",
selectedOrderGroupId === group.id ? "bg-[var(--color-accent-soft)]" : "",
].join(" ")}
type="button"
className={`grid grid-cols-[minmax(180px,2.5fr)_minmax(100px,1.2fr)_minmax(100px,1fr)_minmax(80px,1fr)_minmax(120px,1.2fr)_minmax(130px,1.2fr)] gap-0 w-full border-t border-[var(--color-border)] text-left transition hover:bg-[var(--color-accent-soft)] ${selectedOrderGroupId === group.id ? "bg-[var(--color-accent-soft)]" : ""}`}
onClick={() => onOpenOrder(group.id)}
>
<td className="px-5 py-4">
<div className="px-5 py-4">
<div className="font-medium">{group.displayTitle || group.customerName || group.groupKey}</div>
<div className="mt-1 text-sm text-[var(--color-text-muted)]">
{[group.customerName, group.customerPhone].filter(Boolean).join(" · ")}
</div>
<div className="text-xs text-[var(--color-text-muted)]">{group.groupKey}</div>
</td>
<td className="max-w-[260px] px-5 py-4 text-sm text-[var(--color-text-muted)]">
</div>
<div className="max-w-[260px] px-5 py-4 text-sm text-[var(--color-text-muted)]">
{renderOrderNumbers(group)}
</td>
<td className="px-5 py-4 text-center">
</div>
<div className="px-5 py-4">
<Badge tone={getOrderGroupStatusTone(group)}>{getOrderGroupDisplayStatusLabel(group)}</Badge>
</td>
<td className="px-5 py-4 text-sm">
</div>
<div className="px-5 py-4 text-sm">
{group.assignedDriverName || <span className="text-[var(--color-text-muted)]"></span>}
</td>
<td className="px-5 py-4 text-sm">
</div>
<div className="px-5 py-4 text-sm">
{group.deliveryDate ? (
<span>{fmtDate(group.deliveryDate)}{group.deliveryTime ? <span className="text-[var(--color-text-muted)]"> · {group.deliveryTime}</span> : ""}</span>
) : (
<span className="text-[var(--color-text-muted)]"></span>
)}
</td>
<td className="px-5 py-4 text-sm text-[var(--color-text-muted)]">
</div>
<div className="px-5 py-4 text-sm text-[var(--color-text-muted)]">
{formatDateTime(group.updatedAt)}
</td>
</tr>
</div>
</button>
))}
</tbody>
</table>
</div>
)}
</div>
</Panel>