feat(frontend): fulfillment split, API-driven topics, hub-and-spoke nav, stock-count modal, FOUND ceiling, semantic colors
- bug1: quote header fulfillment counter («رسید: X از Y قلم» amber / «تکمیل شد» green / «در راه»); expanded line items visually split into the received part (رسید شده ✓ + date + target warehouse from the receipt allocations) and the in-transit remainder — quantities always sum to the original line (invariant D holds, display-only split) - bug2: 8-topic grids (suppliers/wizard/units) now come from /material-categories via the store (new lib/topics.ts; fixed the mismatched «ابزار و تجهیزات ساخت» label); suppliers topic->category resolution no longer falls back to an arbitrary category; duplicate month/status lists reuse the shared dictionaries; TopicGrid gained a loading EmptyState - bug3: hub-and-spoke — the tab strip renders only on the warehouse dashboard; sub-views hide it and navigate back via «بازگشت به داشبورد»; «افزایش موجود» became the «تغییر موجودی» entry button - bug4: stock count goes through a confirmation modal (current vs counted vs variance with کسری/مازاد badges) before posting STOCK_COUNT; numbers parsed defensively - bug5: found qty is capped client-side (red input + inline warning, submit disabled) and backend returns 422 when exceeding the missing balance; fully-recovered losses drop off the pending list - bug6+7: quantities render as absolute values with semantic color coding (emerald inflow / rose outflow / blue neutral) across dashboard timeline, daily control and the change-inventory form
This commit is contained in:
@@ -1,37 +1,8 @@
|
||||
// ============================================================
|
||||
// ثابتهای سراسری
|
||||
// ثابتهای سراسری — برچسبهای UI ثابت (وضعیتها و ...)
|
||||
// تاپیکها/دستهها اینجا نیستند — از API میآیند (lib/topics.ts)
|
||||
// ============================================================
|
||||
|
||||
import { normalize } from "./normalize";
|
||||
|
||||
export interface Topic {
|
||||
key: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
// ۸ تاپیک ثابت — HVAC و لولهکشی ادغام شدند؛ ابزار و تجهیزات ساخت اضافه شد
|
||||
export const TOPICS: Topic[] = [
|
||||
{ key: "hvac-plumb", name: "تاسیسات مکانیکی و آبی", icon: "/icons/topic-1.png" },
|
||||
{ key: "electric", name: "تجهیزات و لوازم برقی", icon: "/icons/topic-2.png" },
|
||||
{ key: "door-win", name: "درب، پنجره و شیشه", icon: "/icons/topic-3.png" },
|
||||
{ key: "metal", name: "فلزات و مقاطع فولادی", icon: "/icons/topic-4.png" },
|
||||
{ key: "build-mat", name: "مصالح ساختمانی", icon: "/icons/topic-6.png" },
|
||||
{ key: "chem", name: "مواد شیمیایی ساختمانی", icon: "/icons/topic-7.png" },
|
||||
{ key: "finish", name: "نازککاری و دکوراسیون داخلی", icon: "/icons/topic-8.png" },
|
||||
{ key: "tools", name: "ابزار و تجهیزات ساخت", icon: "/icons/topic-9.png" },
|
||||
];
|
||||
|
||||
function topicEq(a: string, b: string): boolean {
|
||||
return normalize(a) === normalize(b);
|
||||
}
|
||||
|
||||
// یافتن تاپیک بر اساس نام (نرمالشده)
|
||||
export function topicByName(name: string | null | undefined): Topic | null {
|
||||
if (!name) return null;
|
||||
return TOPICS.find((t) => topicEq(t.name, name)) || null;
|
||||
}
|
||||
|
||||
export const STATUS_LABEL: Record<string, string> = {
|
||||
offered: "پیشنهاد شده",
|
||||
accepted: "پذیرفته شده",
|
||||
@@ -47,6 +18,3 @@ export function statusOptionsFor(current: string): string[] {
|
||||
const idx = STATUS_ORDER.indexOf(current);
|
||||
return idx < 0 ? STATUS_ORDER : STATUS_ORDER.slice(0, idx + 1);
|
||||
}
|
||||
|
||||
// واحدهای شناختهشده از بکاند خوانده میشوند — این لیست حذف شد
|
||||
// (واحدها فقط در دیتابیس تعریف میشوند و واحد جدید هنگام تایپ ساخته میشود)
|
||||
|
||||
Reference in New Issue
Block a user