feat(order-detail): collapsible order composition with table layout
- Extracted IIFE into CollapsibleOrderComposition component to fix React hooks error - Состав заказа свернут по умолчанию, разворачивается по клику - Позиции отображаются в табличном виде (grid 1fr + auto) - Количество и единицы измерения не обрезаются (whitespace-nowrap) - Парсинг работает из source_orders, order_list, order_list_structured
This commit is contained in:
parent
0d3be0502c
commit
a2196d232b
|
|
@ -232,6 +232,64 @@ const normalizeDateForInput = (value) => {
|
|||
return "";
|
||||
};
|
||||
|
||||
const CollapsibleOrderComposition = ({ order }) => {
|
||||
const [isExpanded, setIsExpanded] = React.useState(false);
|
||||
const orders = parseOrderList(order);
|
||||
const totalPositions = orders.reduce((sum, o) => sum + (o.items?.length || 0), 0);
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<button
|
||||
type="button"
|
||||
className="flex w-full items-center justify-between text-left"
|
||||
onClick={() => setIsExpanded(!isExpanded)}
|
||||
>
|
||||
<span className="font-semibold">Состав заказа</span>
|
||||
<span className="flex items-center gap-2 text-sm text-[var(--color-text-muted)]">
|
||||
{totalPositions > 0 ? `${totalPositions} поз.` : ''}
|
||||
<svg
|
||||
className="h-4 w-4 transition-transform"
|
||||
style={{ transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)' }}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
{isExpanded && (
|
||||
<div className="space-y-3">
|
||||
{!orders.length ? (
|
||||
<p className="text-sm text-[var(--color-text-muted)]">Позиции не указаны</p>
|
||||
) : (
|
||||
orders.map((orderItem, idx) => (
|
||||
<div key={idx} className="rounded-[20px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-4">
|
||||
<p className="font-medium !text-[var(--color-text)] mb-3 text-sm">{orderItem.nom || orderItem.name || `Заказ ${idx + 1}`}</p>
|
||||
{orderItem.items && orderItem.items.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
{orderItem.items.map((item, itemIdx) => (
|
||||
<div key={itemIdx} className="grid grid-cols-[1fr_auto] gap-x-4 gap-y-1 text-sm">
|
||||
<span className="text-[var(--color-text)] min-w-0">{item.product_name || item.name || item.title || ''}</span>
|
||||
<span className="text-[var(--color-text-muted)] whitespace-nowrap text-right">
|
||||
{item.product_quantity || item.quantity || item.count || item.amount || ""} {item.product_ed || item.unit || ""}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-[var(--color-text-muted)]">Позиции не указаны</p>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const OrderDetailPanel = ({
|
||||
order,
|
||||
canManageDelivery = false,
|
||||
|
|
@ -692,37 +750,9 @@ export const OrderDetailPanel = ({
|
|||
{renderList(order.orderNumbers)}
|
||||
</Panel>
|
||||
|
||||
<Panel className="space-y-4 p-5">
|
||||
<strong>Состав заказа</strong>
|
||||
<div className="space-y-3">
|
||||
{(() => {
|
||||
const orders = parseOrderList(order);
|
||||
if (!orders.length) {
|
||||
return <p className="text-sm text-[var(--color-text-muted)]">Позиции не указаны</p>;
|
||||
}
|
||||
return orders.map((orderItem, idx) => (
|
||||
<div key={idx} className="rounded-[20px] border border-[var(--color-border)] bg-[var(--color-surface-strong)] p-4">
|
||||
<p className="font-medium !text-[var(--color-text)] mb-2">{orderItem.nom || orderItem.name || `Заказ ${idx + 1}`}</p>
|
||||
{orderItem.items && orderItem.items.length > 0 ? (
|
||||
<div className="space-y-1">
|
||||
{orderItem.items.map((item, itemIdx) => (
|
||||
<div key={itemIdx} className="flex justify-between text-sm">
|
||||
<span className="text-[var(--color-text)]">{item.product_name || item.name || item.title || JSON.stringify(item)}</span>
|
||||
<span className="text-[var(--color-text-muted)]">
|
||||
{item.product_quantity || item.quantity || item.count || item.amount || ""} {item.product_ed || item.unit || ""}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-[var(--color-text-muted)]">Позиции не указаны</p>
|
||||
)}
|
||||
</div>
|
||||
));
|
||||
})()}
|
||||
</div>
|
||||
<Panel className="space-y-4 p-5">
|
||||
<CollapsibleOrderComposition order={order} />
|
||||
</Panel>
|
||||
|
||||
{userRole !== "driver" ? (
|
||||
<Panel className="space-y-4 p-5">
|
||||
<strong>Дополнительные данные</strong>
|
||||
|
|
|
|||
Loading…
Reference in New Issue