feat(frontend): add React UI — procurement office, wizard, suppliers, inventory panel (dash port), role-based login
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { TOPICS } from "../lib/constants";
|
||||
import { normalize } from "../lib/normalize";
|
||||
import { faNum } from "../lib/formatters";
|
||||
import { cn } from "../lib/utils";
|
||||
|
||||
export interface TopicGridProps {
|
||||
selectedTopic?: string;
|
||||
onSelect: (topicKey: string) => void;
|
||||
showCounts?: boolean; // تعداد تأمینکنندههای هر تاپیک
|
||||
counts?: Record<string, number>; // topic name → count
|
||||
}
|
||||
|
||||
// گرید ۴ ستونهی ۸ تاپیک
|
||||
export function TopicGrid({ selectedTopic, onSelect, showCounts = false, counts }: TopicGridProps) {
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4">
|
||||
{TOPICS.map((t) => {
|
||||
const selected = selectedTopic != null && normalize(selectedTopic) === normalize(t.name);
|
||||
const count = counts?.[t.name] ?? 0;
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
key={t.key}
|
||||
className={cn("topic-card", selected && "selected")}
|
||||
onClick={() => onSelect(t.name)}
|
||||
>
|
||||
<img src={t.icon} alt="" />
|
||||
<div className="t-name">{t.name}</div>
|
||||
{showCounts && <div className="t-count">{faNum(count)} تأمینکننده</div>}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user