import { useMemo, useState } from "react"; import { Link } from "react-router-dom"; import { Users, FolderKanban, Ruler, Plus } from "lucide-react"; import { useMaterials, useProjects, useQuotes, useStoreData, useSuppliers, useUnits, } from "../../hooks"; import { useAppStore } from "../../store"; import { filterQuotes } from "../../lib/quoteUtils"; import { daysBetween } from "../../lib/formatters"; import { Header, PageLayout } from "../../components/layout/Header"; import { StatsBar } from "../../components/StatsBar"; import { FilterToolbar, type Filters } from "./FilterToolbar"; import { LedgerTable } from "./LedgerTable"; import { PanelMenu } from "../../components/PanelMenu"; import { useLogout } from "../Inventory/panelMenu"; import { AcceptModal } from "./AcceptModal"; import { EditModal } from "./EditModal"; const EMPTY_FILTERS: Filters = { category: "", supplier: "", status: "", search: "" }; // صفحه‌ی اصلی دفتر پیشنهادهای خرید export function DashboardPage() { useStoreData(); const logout = useLogout(); const quotes = useQuotes(); const suppliers = useSuppliers(); const materials = useMaterials(); const projects = useProjects(); const { categoryUnits, unitConversions, standardConversions } = useUnits(); const expandedQuoteIds = useAppStore((s) => s.expandedQuoteIds); const toggleExpand = useAppStore((s) => s.toggleExpand); const topics = useAppStore((s) => s.topics); const [filters, setFilters] = useState(EMPTY_FILTERS); const [sortDir, setSortDir] = useState<"desc" | "asc">("desc"); const [acceptId, setAcceptId] = useState(null); const [editId, setEditId] = useState(null); const store = useMemo( () => ({ quotes, suppliers, materials, projects, categoryUnits, unitConversions, standardConversions, topics }), [quotes, suppliers, materials, projects, categoryUnits, unitConversions, standardConversions, topics], ); // فیلتر + مرتب‌سازی بر اساس زمان ساخت (created_at) — فیلترها بازنشانی نمی‌شوند const filtered = useMemo(() => { const list = filterQuotes(store, filters); const createdTs = (q: (typeof store.quotes)[number]) => { const iso = q.created_at || q.quote_date; const ts = iso ? new Date(iso).getTime() : 0; return Number.isFinite(ts) ? ts : 0; }; return [...list].sort((a, b) => (sortDir === "desc" ? createdTs(b) - createdTs(a) : createdTs(a) - createdTs(b))); }, [store, filters, sortDir]); const stats = useMemo(() => { const total = quotes.length; const offered = quotes.filter((q) => q.status === "offered").length; const accepted = quotes.filter((q) => q.status === "accepted").length; const leadTimes = quotes .filter((q) => q.status === "arrived" && q.accepted_date && q.arrived_date) .map((q) => daysBetween(q.arrived_date, q.accepted_date)) .filter((x): x is number => x != null); const avgLead = leadTimes.length ? Math.round(leadTimes.reduce((a, b) => a + b, 0) / leadTimes.length) : null; return { total, offered, accepted, avgLead }; }, [quotes]); const categoryOptions = useMemo(() => [...new Set(materials.map((m) => m.category))], [materials]); const supplierOptions = useMemo(() => suppliers.map((s) => ({ id: s.id, name: s.name })), [suppliers]); return (
} actions={ <> تأمین‌کننده‌ها پروژه‌ها ضرایب تبدیل افزودن پیشنهاد جدید } /> setSortDir((d) => (d === "desc" ? "asc" : "desc"))} /> setAcceptId(null)} /> setEditId(null)} />
); }