diff --git a/frontend/src/pages/Dashboard/EditModal.tsx b/frontend/src/pages/Dashboard/EditModal.tsx index a35ef2a..76ecb31 100644 --- a/frontend/src/pages/Dashboard/EditModal.tsx +++ b/frontend/src/pages/Dashboard/EditModal.tsx @@ -61,7 +61,7 @@ export interface EditModalProps { onClose: () => void; } -// مودال ویرایش کامل پیشنهاد +// مودال ویرایش کامل پیشنهاد — بهینه‌شده برای صفحات موبایل export function EditModal({ quoteId, onClose }: EditModalProps) { const quotes = useQuotes(); const suppliers = useSuppliers(); @@ -112,7 +112,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { } }; - // گزینه‌های مشخصه — همه‌ی مشخصه‌های ثبت‌شده (کش) + رجیستری سراسری + // گزینه‌های مشخصه const [globalSpecs, setGlobalSpecs] = useState([]); useEffect(() => { let alive = true; @@ -120,7 +120,9 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { .specsList() .then((list) => alive && setGlobalSpecs(list)) .catch(() => {}); - return () => { alive = false; }; + return () => { + alive = false; + }; }, []); const specOptions = useMemo(() => { @@ -131,7 +133,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { return [...set].sort((a, b) => a.localeCompare(b, "fa")); }, [materials, itemRows, globalSpecs]); - // گزینه‌های پروژه — پروژه‌های ثبت‌شده + پروژه‌های خود پیشنهاد + // گزینه‌های پروژه const projectOptions = useMemo(() => { const set = new Set(); projects.forEach((p) => p.name && set.add(p.name)); @@ -183,7 +185,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { setReady(true); }, [q, suppliers, materials]); - // فاکتورها مستقیماً از سرور (MinIO) خوانده می‌شوند — نه از state محلی + // بارگذاری فاکتورها useEffect(() => { if (!quoteId) return; let alive = true; @@ -250,7 +252,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { const next: Quote = JSON.parse(JSON.stringify(q)); - // تأمین‌کننده — موجود یا جدید + // تأمین‌کننده if (supplierName.trim()) { const norm = normalize(supplierName); const exist = suppliers.find((s) => normalize(s.name) === norm); @@ -259,7 +261,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { } else { const newSup = { id: nextId("s", suppliers), name: supplierName.trim(), location: "", phone: "", contact: "", topic: "", categories: [] }; const created = await addSupplier.mutateAsync(newSup); - next.supplier_id = created.id; // UUID واقعی از بک‌اند + next.supplier_id = created.id; } } @@ -268,7 +270,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { next.notes = notes.trim(); next.invoices = invoices; - // termsheetها — id موجود حفظ می‌شود، جدیدها ساخته می‌شوند + // termsheetها const tsIdMap: Record = {}; const newTermsheets: Termsheet[] = []; tsCards.forEach((card, i) => { @@ -296,7 +298,7 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { const qty = row.qty; const price = row.price; const total = row.total; - if (!cat && !brand && qty == null && price == null) continue; // ردیف خالی + if (!cat && !brand && qty == null && price == null) continue; let material = materialsCopy.find( (m) => @@ -318,7 +320,6 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { base_unit: unit, }; materialsCopy.push(nm); - // منتظر ساخت متریال می‌مانیم تا id واقعی (UUID) به قلم وصل شود const created = await addMaterial.mutateAsync(nm); materialId = created.id; } @@ -366,7 +367,6 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { } next.line_items = newItems.length ? newItems : next.line_items; - // ترم‌شیت بدون قلم بی‌معنی است — حذف const referencedTs = new Set(); next.line_items.forEach((li) => (li.termsheet_ids || []).forEach((tid) => referencedTs.add(tid))); next.termsheets = next.termsheets.filter((t) => referencedTs.has(t.id)); @@ -383,7 +383,6 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { next.arrived_date = arrivedDate; next.status = status as Quote["status"]; - // پاک‌سازی خودکار در بازگشت وضعیت if (next.status === "offered") { next.accepted_date = null; next.arrived_date = null; @@ -417,363 +416,394 @@ export function EditModal({ quoteId, onClose }: EditModalProps) { return ( <> !o && onClose()}> - - - ویرایش پیشنهاد - + + + ویرایش پیشنهاد + - {hasReceipts && ( -
- - این پیشنهاد به‌دلیل ثبت رسید در انبار، غیرقابل ویرایش یا بازگشت است. -
- )} + {hasReceipts && ( +
+ + این پیشنهاد به‌دلیل ثبت رسید در انبار، غیرقابل ویرایش یا بازگشت است. +
+ )} -
-
- - setSupplierName(it.label)} - items={suppliers.map((s) => ({ id: s.id, name: s.name }))} - allowAdd - addSuffix="به عنوان تأمین‌کنندهٔ جدید" - placeholder="نام تأمین‌کننده" - onInputChange={(v) => setSupplierName(v)} - /> -
-
- - -
-
- -