fix(procurement): improve mobile layout for QuoteCard and EditModal
This commit is contained in:
@@ -176,29 +176,60 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* اطلاعات کلیدی (گرید ۲ ستونه موبایل / ۴ ستونه دسکتاپ) */}
|
||||
<div className="grid grid-cols-2 gap-x-3 gap-y-2.5 p-3 sm:gap-x-5 sm:gap-y-3 sm:p-4 md:grid-cols-4">
|
||||
<InfoCell label="اقلام">
|
||||
{/* اطلاعات کلیدی — چیدمان بهینهشده موبایل */}
|
||||
<div className="grid grid-cols-2 gap-x-3 gap-y-3 p-3 sm:gap-x-5 sm:gap-y-3.5 sm:p-4 md:grid-cols-4">
|
||||
{/* ۱. پروژه — تمامعرض در موبایل */}
|
||||
<InfoCell label="پروژه" className="col-span-2 md:col-span-1">
|
||||
<div className="flex items-center gap-1.5 text-xs font-semibold text-ink sm:text-[13px]">
|
||||
<Building2 className="h-3.5 w-3.5 shrink-0 text-muted" />
|
||||
<span className="truncate">
|
||||
{q.projects && q.projects.length > 0 ? q.projects.join("، ") : projectCell(q)}
|
||||
</span>
|
||||
</div>
|
||||
</InfoCell>
|
||||
|
||||
{/* ۲. اقلام — تمامعرض زیر پروژه با شکستن متن بدون سهنقطه */}
|
||||
<InfoCell label="اقلام" className="col-span-2 md:col-span-1">
|
||||
{summary.count > 1 ? (
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="font-semibold text-xs sm:text-sm">{fmtNum(summary.count)} قلم کالا</span>
|
||||
<div className="flex flex-col gap-0.5 text-[11px] leading-4 text-muted sm:text-[11.5px] sm:leading-5">
|
||||
{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 (
|
||||
<span key={li.id} className="truncate">
|
||||
• {materialLabel(m)} ({fmtNum(li.quantity)} {li.unit})
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<span className="font-bold text-xs text-ink sm:text-sm">
|
||||
{fmtNum(summary.count)} قلم کالا
|
||||
</span>
|
||||
<div className="flex flex-col gap-1.5 rounded-lg border border-line/60 bg-bg/50 p-2.5 text-[11px] leading-5 text-muted sm:text-[11.5px]">
|
||||
{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 (
|
||||
<div
|
||||
key={li.id}
|
||||
className="flex items-start justify-between gap-2 border-b border-line/30 pb-1.5 last:border-0 last:pb-0"
|
||||
>
|
||||
<span className="min-w-0 flex-1 font-medium text-ink leading-snug break-words">
|
||||
• {materialLabel(m)}
|
||||
</span>
|
||||
<span className="shrink-0 font-semibold tabular-nums text-ink text-[10.5px] pt-0.5">
|
||||
{fmtNum(li.quantity)}{" "}
|
||||
<span className="font-normal text-muted text-[9.5px]">{li.unit}</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{(q.line_items?.length || 0) > 3 && (
|
||||
<span className="text-[10px] text-muted">و {(q.line_items?.length || 0) - 3} قلم دیگر...</span>
|
||||
<span className="pt-0.5 text-[10px] text-muted">
|
||||
و {(q.line_items?.length || 0) - 3} قلم دیگر...
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span className="truncate">{summary.text}</span>
|
||||
<div className="flex items-start gap-1.5 text-xs font-medium leading-5 text-ink sm:text-[13px]">
|
||||
<span className="break-words">{summary.text}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{unitWarns.map((w) => (
|
||||
<Link
|
||||
key={w.unit}
|
||||
@@ -206,25 +237,17 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
|
||||
className="unit-warn mt-1 inline-flex items-center gap-1 text-[10px]"
|
||||
title={`ضریب تبدیل «${esc(w.unit)}» را در داشبورد واحدها ثبت کنید`}
|
||||
>
|
||||
<TriangleAlert className="h-2.5 w-2.5" />
|
||||
<TriangleAlert className="h-2.5 w-2.5 shrink-0" />
|
||||
واحد جدید: {w.unit}
|
||||
</Link>
|
||||
))}
|
||||
</InfoCell>
|
||||
|
||||
<InfoCell label="پروژه">
|
||||
<span className="inline-flex items-center gap-1 text-xs sm:text-[13px]">
|
||||
<Building2 className="h-3.5 w-3.5 shrink-0 text-muted" />
|
||||
<span className="truncate">
|
||||
{q.projects && q.projects.length > 0 ? q.projects.join("، ") : projectCell(q)}
|
||||
</span>
|
||||
</span>
|
||||
</InfoCell>
|
||||
|
||||
<InfoCell label="مجموع مبلغ">
|
||||
{/* ۳. مجموع مبلغ */}
|
||||
<InfoCell label="مجموع مبلغ" className="col-span-1">
|
||||
{pc ? (
|
||||
<div>
|
||||
<div className="text-sm font-extrabold text-ink tabular-nums sm:text-base">
|
||||
<div className="text-sm font-extrabold tabular-nums text-ink sm:text-base">
|
||||
{pc.num} <span className="text-[10px] font-normal text-muted sm:text-xs">تومان</span>
|
||||
</div>
|
||||
<div className="hidden text-[11px] text-muted sm:block">({pc.words})</div>
|
||||
@@ -234,10 +257,11 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
|
||||
)}
|
||||
</InfoCell>
|
||||
|
||||
<InfoCell label="شرایط معامله">
|
||||
{/* ۴. شرایط معامله */}
|
||||
<InfoCell label="شرایط معامله" className="col-span-1">
|
||||
{ts.title !== "—" ? (
|
||||
<div>
|
||||
<div className="font-semibold text-xs sm:text-[13px]" style={ts.color ? { color: ts.color } : undefined}>
|
||||
<div className="text-xs font-semibold sm:text-[13px]" style={ts.color ? { color: ts.color } : undefined}>
|
||||
{ts.title}
|
||||
</div>
|
||||
{ts.sub && <div className="truncate text-[10px] text-muted sm:text-[11px]">{ts.sub}</div>}
|
||||
@@ -248,12 +272,12 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
|
||||
</InfoCell>
|
||||
</div>
|
||||
|
||||
{/* تاریخها و اکشنها (۲ ستونه در موبایل، نواری در دسکتاپ) */}
|
||||
{/* تاریخها و اکشنها */}
|
||||
<div className="grid grid-cols-2 gap-2 border-t border-line bg-bg/40 p-2.5 text-[11px] text-muted sm:flex sm:flex-wrap sm:items-center sm:gap-x-5 sm:gap-y-2 sm:px-4 sm:py-2 sm:text-[11.5px]">
|
||||
<span className="inline-flex items-center gap-1.5 truncate">
|
||||
<Package className="h-3 w-3 shrink-0" />
|
||||
<span>تاریخ:</span>
|
||||
<b className="text-ink tabular-nums">{fmtDate(q.quote_date)}</b>
|
||||
<b className="tabular-nums text-ink">{fmtDate(q.quote_date)}</b>
|
||||
</span>
|
||||
|
||||
<span className="inline-flex items-center gap-1.5 truncate">
|
||||
@@ -262,7 +286,7 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
|
||||
<b className={cn("tabular-nums", expired ? "text-amber" : "text-ink")}>
|
||||
{fmtDate(q.expiry_date)}
|
||||
</b>
|
||||
{expired && <AlarmClock className="h-3 w-3 text-amber shrink-0" aria-label="منقضی" />}
|
||||
{expired && <AlarmClock className="h-3 w-3 shrink-0 text-amber" aria-label="منقضی" />}
|
||||
</span>
|
||||
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
|
||||
Reference in New Issue
Block a user