import { Link } from "react-router-dom"; import { AlarmClock, ChevronDown, Pencil, TriangleAlert, Building2, Package, CreditCard, Check } from "lucide-react"; import type { Quote, Store } from "../../lib/types"; import { isExpired, materialById, materialLabel, projectCell, quoteTotal, supplierById, termsheetSummary, unitWarning, } from "../../lib/quoteUtils"; import { STATUS_LABEL } from "../../lib/constants"; import { esc, fmtDate, fmtDateTime, fmtNum, priceCell } from "../../lib/formatters"; import { Badge } from "../../components/ui/badge"; import { cn } from "../../lib/utils"; import { QuoteDetail } from "./QuoteDetail"; export interface QuoteCardProps { store: Store; q: Quote; expanded: boolean; onToggleExpand: () => void; onAccept: () => void; onEdit: () => void; } function InfoCell({ label, children, className }: { label: string; children: React.ReactNode; className?: string }) { return (
{label}
{children}
); } // کارت پیشنهاد خرید — بهینه‌شده برای کاربری سرپا با موبایل export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit }: QuoteCardProps) { const sup = supplierById(store.suppliers, q.supplier_id); const expired = isExpired(q); const total = quoteTotal(q); const pc = priceCell(total); const ts = termsheetSummary(store, q); const unitWarns = unitWarning(store, q); // ستون / دکمه پذیرش let acceptedCell: React.ReactNode; if (q.status === "offered") { acceptedCell = ( ); } else if (q.accepted_date) { acceptedCell = {fmtDateTime(q.accepted_date)}; } else { acceptedCell = —; } // وضعیت رسید کالا const activeItems = (q.line_items || []).filter((li) => !li.rejected); const receivedSum = activeItems.reduce((s, li) => s + (li.received_qty || 0), 0); const orderedSum = activeItems.reduce((s, li) => s + (li.quantity || 0), 0); const fulfilledItems = activeItems.filter( (li) => li.quantity != null && li.quantity > 0 && (li.received_qty || 0) >= li.quantity, ).length; const anyReceived = receivedSum > 0; const fullyDelivered = activeItems.length > 0 && fulfilledItems === activeItems.length && anyReceived; // نشان پیشرفت تکمیل let fulfillmentBadge: React.ReactNode = null; if (q.status === "accepted" || q.status === "arrived") { if (fullyDelivered || q.status === "arrived") { fulfillmentBadge = ( ✓ تکمیل ); } else if (anyReceived) { fulfillmentBadge = ( رسید: {fmtNum(fulfilledItems)}/{fmtNum(activeItems.length)} ); } else { fulfillmentBadge = ( ⏳ در راه ); } } let arrivedCell: React.ReactNode; const lastReceiptAt = activeItems.reduce((acc, li) => { if (!li.arrived_date) return acc; const t = new Date(li.arrived_date).getTime(); if (Number.isNaN(t)) return acc; return !acc || t > acc.getTime() ? new Date(li.arrived_date) : acc; }, null); if (q.status === "accepted") { if (q.arrived_date) { arrivedCell = {fmtDateTime(q.arrived_date)}; } else if (receivedSum > 0) { arrivedCell = ( {fmtNum(receivedSum)} از {fmtNum(orderedSum)} ); } else { arrivedCell = در انتظار انبار; } } else if (q.status === "arrived") { arrivedCell = ( {fmtDateTime(q.arrived_date || (lastReceiptAt ? lastReceiptAt.toISOString() : ""))} ); } else { arrivedCell = —; } return (
{/* سربرگ کارت */}
{sup.name.slice(0, 1)}
{sup.name} {/* فاکتور رسمی / غیررسمی — از چک‌باکس «فاکتور رسمی» هنگام ثبت پیشنهاد */} {q.is_official ? "رسمی" : "غیررسمی"}
{sup.location &&
{sup.location}
}
{fulfillmentBadge ?? ( {STATUS_LABEL[q.status]} )}
{/* اطلاعات کلیدی — چیدمان بهینه‌شده موبایل */}
{/* ۱. پروژه — تمام‌عرض در موبایل */}
{q.projects && q.projects.length > 0 ? q.projects.join("، ") : projectCell(q)}
{/* ۲. اقلام — نمایش عمودی چندخطی */}
{activeItems.length > 0 ? ( activeItems.map((li) => { const m = materialById(store.materials, li.material_id); return ( {materialLabel(m)} ); }) ) : ( — )}
{unitWarns.map((w) => ( واحد جدید: {w.unit} ))}
{pc ? (
{pc.num} تومان
({pc.words})
) : ( "—" )}
{/* ۴. شرایط معامله */} {ts.title !== "—" ? (
{ts.title}
{ts.sub &&
{ts.sub}
}
) : ( — )}
{/* تاریخ‌ها و اکشن‌ها */}
تاریخ: {fmtDate(q.quote_date)} اعتبار: {fmtDate(q.expiry_date)} {expired && } پذیرش: {acceptedCell} رسید: {arrivedCell}
{/* جزئیات تکمیلی بازشونده */} {expanded && }
); }