Domain model (v2.6): suppliers.category_id NOT NULL (1:N from the 8 fixed categories), materials are global and link to suppliers via supplier_materials. This fixes three regressions of the old inverted tree: - remove the intermediate 'یک متریال را انتخاب کنید' screen: a category card now routes straight to that category's supplier list (/suppliers/category/:category); TopicPage is deleted and legacy /topics/:topic[/:category] URLs redirect to the new hierarchy - kill the accidental-category bug: api.materials.create silently POSTed /material-categories for any unknown 'category' (a material name!), which is how the rogue «پریز» category (+ junk material) appeared. Unknown categories now fail loudly instead of creating catalog rows (DB cleaned: exactly the 8 canonical categories remain) - fix inverted wording: supplier list is «تأمینکنندههای این دسته» with category-first breadcrumbs; the legacy material multi-select on the add-supplier form is gone (a supplier gets the page's category) - supplier details screen logic untouched — only its breadcrumb link targets were updated to the new routes
43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
import { useMemo } from "react";
|
|
import { useStoreData, useSuppliers } from "../../hooks";
|
|
import { useAppStore } from "../../store";
|
|
import { normalize } from "../../lib/normalize";
|
|
import { Header, PageLayout } from "../../components/layout/Header";
|
|
import { TopicGrid } from "../../components/TopicGrid";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
// صفحهی تأمینکنندهها — انتخاب موضوع (دستهها از API میآیند)
|
|
export function SuppliersPage() {
|
|
useStoreData();
|
|
const suppliers = useSuppliers();
|
|
const topics = useAppStore((s) => s.topics);
|
|
const navigate = useNavigate();
|
|
|
|
const counts = useMemo(() => {
|
|
const out: Record<string, number> = {};
|
|
topics.forEach((t) => {
|
|
out[t.name] = suppliers.filter((s) => normalize(s.topic) === normalize(t.name)).length;
|
|
});
|
|
return out;
|
|
}, [topics, suppliers]);
|
|
|
|
return (
|
|
<div className="min-h-screen">
|
|
<Header
|
|
title="تأمینکنندهها"
|
|
sub="اول دستهبندی را انتخاب کنید"
|
|
backTo="/"
|
|
backLabel="بازگشت به دفتر"
|
|
/>
|
|
<PageLayout>
|
|
<TopicGrid
|
|
topics={topics}
|
|
onSelect={(topic) => navigate(`/suppliers/category/${encodeURIComponent(topic)}`)}
|
|
showCounts
|
|
counts={counts}
|
|
/>
|
|
</PageLayout>
|
|
</div>
|
|
);
|
|
}
|