// Dashboard — real analytics computed from the поручения register + documents. function Dashboard({ onNavigate }) { const { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid } = Recharts; const YEARS = [2024, 2025, 2026]; const [year, setYear] = React.useState(2025); const [tasks, setTasks] = React.useState([]); const [docs, setDocs] = React.useState([]); const [loading, setLoading] = React.useState(true); const load = React.useCallback(() => { if (!window.API) { setLoading(false); return; } setLoading(true); Promise.all([ window.API.listTasks().catch(() => []), window.API.listDocuments().catch(() => []), ]).then(([t, d]) => { setTasks(Array.isArray(t) ? t : []); setDocs(Array.isArray(d) ? d : []); }).finally(() => setLoading(false)); }, []); React.useEffect(() => { load(); }, [load]); const eff = (t) => (typeof effStatus === "function" ? effStatus(t) : t.status); const yearTasks = tasks.filter(t => t.year === year); const stat = { total: yearTasks.length, done: 0, overdue: 0, work: 0 }; yearTasks.forEach(t => { const e = eff(t); if (e === "done") stat.done++; else if (e === "overdue") stat.overdue++; else stat.work++; }); const donePct = stat.total ? Math.round(stat.done / stat.total * 100) : 0; const months = (typeof MONTH_ORDER !== "undefined") ? MONTH_ORDER : []; const byMonth = months.map(m => ({ name: m.slice(0, 3), Поручений: yearTasks.filter(t => t.mon === m).length })); const depts = (typeof DEPARTMENTS !== "undefined") ? DEPARTMENTS : []; const byDept = depts.map(d => { const list = yearTasks.filter(t => t.dept === d); return { name: d.replace("Отдел ", "").replace(" отдел", ""), Всего: list.length, Выполнено: list.filter(t => eff(t) === "done").length, }; }).filter(x => x.Всего > 0); const recent = docs.slice(0, 5); return (
Аналитика по реестру поручений · {year} год{loading ? " · загрузка…" : ""}
| Название | Тип | Загружен | Размер |
|---|---|---|---|
| Документов пока нет — загрузите на странице «Документы» | |||
| {d.type || "file"} | {d.date} | {d.size} | |