fix: resolve typescript configs and finish merge

This commit is contained in:
fatemeh sane
2026-10-07 12:23:42 +03:30
parent bc86d35e1e
commit 416683b3d7
2 changed files with 0 additions and 76 deletions
-22
View File
@@ -458,16 +458,9 @@ function adaptBrandLink(raw: RawBrandLink): BrandLinkRow {
return { id: raw.id, brand_id: raw.brand_id, brand_name: raw.brand?.name || "" }; return { id: raw.id, brand_id: raw.brand_id, brand_name: raw.brand?.name || "" };
} }
<<<<<<< Updated upstream
// تأمین‌کنندگان متصل به یک متریال — پاسخ GET /materials/{id}/suppliers
// Raw shape mirrors the backend dict exactly: clean supplier objects produced
// by an atomic JOIN (select(Supplier).join(SupplierMaterial)…) — the name
// always comes from the suppliers table, never from the material row.
=======
// ── تأمین‌کننده‌های متریال — پاسخ GET /materials/{id}/suppliers ────────────── // ── تأمین‌کننده‌های متریال — پاسخ GET /materials/{id}/suppliers ──────────────
// Raw shape mirrors the backend dict exactly. The backend uses an atomic // Raw shape mirrors the backend dict exactly. The backend uses an atomic
// column-level JOIN so `name` always comes from the suppliers table. // column-level JOIN so `name` always comes from the suppliers table.
>>>>>>> Stashed changes
interface RawMaterialSupplier { interface RawMaterialSupplier {
id: string; id: string;
name: string; name: string;
@@ -488,11 +481,6 @@ export interface MaterialSupplier {
function adaptMaterialSupplier(raw: RawMaterialSupplier): MaterialSupplier { function adaptMaterialSupplier(raw: RawMaterialSupplier): MaterialSupplier {
return { return {
id: raw.id, id: raw.id,
<<<<<<< Updated upstream
// Bound straight from the supplier object in the API response — there is
// no fallback, so a supplier row can never render the material's name.
=======
>>>>>>> Stashed changes
name: raw.name, name: raw.name,
phone: raw.phone, phone: raw.phone,
contact_person: raw.contact_person, contact_person: raw.contact_person,
@@ -1168,20 +1156,10 @@ export const api = {
updateCanonicalUnit: async (id: string, canonical_unit_id: number): Promise<void> => { updateCanonicalUnit: async (id: string, canonical_unit_id: number): Promise<void> => {
await patchData(`/materials/${id}`, { canonical_unit_id }); await patchData(`/materials/${id}`, { canonical_unit_id });
}, },
<<<<<<< Updated upstream
// فهرست تأمین‌کننده‌های متصل به یک متریال (GET /materials/{id}/suppliers)
listSuppliers: async (materialId: string): Promise<MaterialSupplier[]> => {
// The backend returns { data: [...clean supplier objects] } from an
// atomic JOIN; getData<T> unwraps the envelope. No fallback data —
// an empty array means the material genuinely has no suppliers.
const raw = await getData<RawMaterialSupplier[]>(
`/materials/${materialId}/suppliers`,
=======
// فهرست تأمین‌کننده‌های متصل به یک متریال — GET /materials/{id}/suppliers // فهرست تأمین‌کننده‌های متصل به یک متریال — GET /materials/{id}/suppliers
listSuppliers: async (materialId: string): Promise<MaterialSupplier[]> => { listSuppliers: async (materialId: string): Promise<MaterialSupplier[]> => {
const raw = await getData<RawMaterialSupplier[]>( const raw = await getData<RawMaterialSupplier[]>(
`/materials/${materialId}/suppliers?page_size=100`, `/materials/${materialId}/suppliers?page_size=100`,
>>>>>>> Stashed changes
); );
return raw.map(adaptMaterialSupplier); return raw.map(adaptMaterialSupplier);
}, },
-54
View File
@@ -104,16 +104,10 @@ export function UnitsPage() {
const [rowsLoading, setRowsLoading] = useState(false); const [rowsLoading, setRowsLoading] = useState(false);
const [brandLinks, setBrandLinks] = useState<BrandLinkRow[]>([]); const [brandLinks, setBrandLinks] = useState<BrandLinkRow[]>([]);
<<<<<<< Updated upstream
// تأمین‌کننده‌های متریال انتخاب‌شده — type imported from api.ts
const [materialSuppliers, setMaterialSuppliers] = useState<MaterialSupplier[]>([]);
const [suppliersLoading, setSuppliersLoading] = useState(false);
=======
// تأمین‌کننده‌های متریال انتخاب‌شده — داده از GET /materials/{id}/suppliers // تأمین‌کننده‌های متریال انتخاب‌شده — داده از GET /materials/{id}/suppliers
const [materialSuppliers, setMaterialSuppliers] = useState<MaterialSupplier[]>([]); const [materialSuppliers, setMaterialSuppliers] = useState<MaterialSupplier[]>([]);
const [suppliersLoading, setSuppliersLoading] = useState(false); const [suppliersLoading, setSuppliersLoading] = useState(false);
// کلید پیشگیری از flicker: قبل از رسیدن پاسخ جدید، empty state نشان نمی‌دهیم // کلید پیشگیری از flicker: قبل از رسیدن پاسخ جدید، empty state نشان نمی‌دهیم
>>>>>>> Stashed changes
const [suppliersLoadedId, setSuppliersLoadedId] = useState<string | null>(null); const [suppliersLoadedId, setSuppliersLoadedId] = useState<string | null>(null);
// واحدها و برندهای سراسری (فهرست دیتابیس) // واحدها و برندهای سراسری (فهرست دیتابیس)
@@ -289,11 +283,7 @@ export function UnitsPage() {
setSuppliersLoading(true); setSuppliersLoading(true);
api.materials api.materials
.listSuppliers(materialId) .listSuppliers(materialId)
<<<<<<< Updated upstream
.then((list) => {
=======
.then((list) => { .then((list) => {
>>>>>>> Stashed changes
if (alive) { if (alive) {
setMaterialSuppliers(list); setMaterialSuppliers(list);
setSuppliersLoadedId(materialId); setSuppliersLoadedId(materialId);
@@ -303,13 +293,7 @@ export function UnitsPage() {
if (!alive) return; if (!alive) return;
setMaterialSuppliers([]); setMaterialSuppliers([]);
setSuppliersLoadedId(materialId); setSuppliersLoadedId(materialId);
<<<<<<< Updated upstream
// Surface the real error so backend issues are not silently hidden
const msg = err instanceof Error ? err.message : "خواندن تأمین‌کننده‌های متریال ناموفق بود";
toast.error(msg);
=======
toast.error(err instanceof Error ? err.message : "خواندن تأمین‌کننده‌های متریال ناموفق بود"); toast.error(err instanceof Error ? err.message : "خواندن تأمین‌کننده‌های متریال ناموفق بود");
>>>>>>> Stashed changes
}) })
.finally(() => { if (alive) setSuppliersLoading(false); }); .finally(() => { if (alive) setSuppliersLoading(false); });
return () => { alive = false; }; return () => { alive = false; };
@@ -598,43 +582,6 @@ export function UnitsPage() {
</div> </div>
) : ( ) : (
<> <>
<<<<<<< Updated upstream
{/* تامین‌کنندگان متریال — پاسخ GET /materials/{id}/suppliers */}
<div className="mb-6 flex flex-col overflow-hidden rounded-xl border border-line bg-panel shadow-sm">
<div className="shrink-0 border-b border-line bg-panel px-4 py-3">
<h4 className="flex items-center gap-2 text-[14px] font-bold text-accent">
<Building2 className="h-4 w-4" /> تامین‌کنندگان متریال
</h4>
</div>
<div className="flex w-full flex-1 flex-col p-4 transition-opacity duration-300 ease-in-out opacity-100 min-h-[80px] md:min-h-[100px]">
{suppliersLoading || materialId !== suppliersLoadedId ? (
<div className="flex flex-1 flex-col items-center justify-center text-center text-sm text-muted">
<div className="h-5 w-5 animate-spin rounded-full border-2 border-muted border-t-transparent"></div>
</div>
) : materialSuppliers.length === 0 ? (
<div className="flex flex-1 flex-col items-center justify-center text-center text-sm text-gray-400 md:text-base">
تامین‌کننده‌ای برای این متریال ثبت نشده است
</div>
) : (
<div className="flex flex-col gap-2 max-h-[200px] overflow-y-auto custom-scrollbar pr-1">
{materialSuppliers.map((s) => (
<div
key={s.id}
className="rounded-lg border border-line bg-slate-bg px-3 py-2.5 text-sm shrink-0"
>
{/* نام تأمین‌کننده — مستقیم از پاسخ API، بدون fallback */}
<div className="flex items-center gap-1.5 text-[13px] font-semibold">
<Building2 className="h-3.5 w-3.5 shrink-0 text-accent" />
{s.name}
</div>
{(s.location || s.phone || s.contact_person) && (
<div className="mt-0.5 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[11.5px] text-muted">
{s.location && <span>{s.location}</span>}
{s.phone && <span dir="ltr">{s.phone}</span>}
{s.contact_person && <span>{s.contact_person}</span>}
</div>
)}
=======
{/* ── تامین‌کنندگان متریال ── */} {/* ── تامین‌کنندگان متریال ── */}
<div className="mb-5 overflow-hidden rounded-xl border border-line bg-panel shadow-sm"> <div className="mb-5 overflow-hidden rounded-xl border border-line bg-panel shadow-sm">
{/* سرصفحه — همیشه نمایش داده می‌شود */} {/* سرصفحه — همیشه نمایش داده می‌شود */}
@@ -699,7 +646,6 @@ export function UnitsPage() {
{s.location || <span className="text-gray-500">ثبت نشده</span>} {s.location || <span className="text-gray-500">ثبت نشده</span>}
</span> </span>
</div> </div>
>>>>>>> Stashed changes
</div> </div>
))} ))}
</div> </div>