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,
itemsSummary,
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 (
);
}
// کارت پیشنهاد خرید — بهینهشده برای کاربری سرپا با موبایل
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);
const summary = itemsSummary(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}
{sup.location &&
{sup.location}
}
{fulfillmentBadge ?? (
{STATUS_LABEL[q.status]}
)}
{/* اطلاعات کلیدی — چیدمان بهینهشده موبایل */}
{/* ۱. پروژه — تمامعرض در موبایل */}
{q.projects && q.projects.length > 0 ? q.projects.join("، ") : projectCell(q)}
{/* ۲. اقلام — تمامعرض زیر پروژه با شکستن متن بدون سهنقطه */}
{summary.count > 1 ? (
{fmtNum(summary.count)} قلم کالا
{store.quotes
.find((x) => x.id === q.id)
?.line_items?.filter((li) => !li.rejected)
.slice(0, 3)
.map((li) => {
const m = materialById(store.materials, li.material_id);
return (
• {materialLabel(m)}
{fmtNum(li.quantity)}{" "}
{li.unit}
);
})}
{(q.line_items?.length || 0) > 3 && (
و {(q.line_items?.length || 0) - 3} قلم دیگر...
)}
) : (
{summary.text}
)}
{unitWarns.map((w) => (
واحد جدید: {w.unit}
))}
{(() => {
const activeItems = (q.line_items || []).filter((li) => !li.rejected);
if (q.status === "accepted" || q.status === "arrived") {
// فقط پروژهی هدف پذیرفتهشده — همان منطق itemProjects در وضعیت accepted
const targetProj = activeItems.find((li) => li.target_project)?.target_project;
return targetProj?.name ?? projectCell(q);
}
// وضعیت offered: همهی پروژههای کاندیدا از line_items (همان منطق itemProjects)
const names = new Set();
activeItems.forEach((li) =>
(li.projects || []).forEach((p) => {
const name = typeof p === "string" ? p : p.name;
if (name) names.add(name);
})
);
if (names.size > 0) return [...names].join("، ");
return projectCell(q);
})()}
{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 &&
}
);
}