import { useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import { ArrowLeft, Search, Printer, ChevronsDownUp, ChevronsUpDown } from "lucide-react"; import { useCategoryTaxonomy } from "../hooks/useCategoryTaxonomy"; import CategoryTaxonomyTree from "../components/categories/CategoryTaxonomyTree"; import type { TaxonomyNode } from "../services/categoryTaxonomyService"; function countNodes(nodes: TaxonomyNode[]): { roots: number; subcategories: number; leaves: number; } { let roots = 0; let subcategories = 0; let leaves = 0; for (const root of nodes) { roots += 1; for (const child of root.children) { if (child.children.length === 0) { // direct leaf under a root (rare but possible) leaves += 1; } else { subcategories += 1; for (const leaf of child.children) { if (leaf.children.length === 0) leaves += 1; else subcategories += 1; } } } } return { roots, subcategories, leaves }; } function collectAllIds(nodes: TaxonomyNode[]): number[] { const ids: number[] = []; const walk = (n: TaxonomyNode) => { ids.push(n.id); n.children.forEach(walk); }; nodes.forEach(walk); return ids; } export default function CategoriesStandardGuidePage() { const { t } = useTranslation(); const { taxonomy } = useCategoryTaxonomy(); const [search, setSearch] = useState(""); const [expanded, setExpanded] = useState>(() => { // Start with roots collapsed (user can expand as needed); counter and search still work. return new Set(); }); const counts = useMemo(() => countNodes(taxonomy.roots), [taxonomy.roots]); const total = counts.roots + counts.subcategories + counts.leaves; const toggleNode = (id: number) => { setExpanded((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }; const handleExpandAll = () => { setExpanded(new Set(collectAllIds(taxonomy.roots))); }; const handleCollapseAll = () => { setExpanded(new Set()); }; const handlePrint = () => { // window.print() opens the browser print dialog; @media print rules strip chrome. window.print(); }; const allExpanded = expanded.size > 0; return (
{/* Back link (hidden in print) */}
{t("categoriesSeed.guidePage.backToSettings")}
{/* Header */}

{t("categoriesSeed.guidePage.title")}

{t("categoriesSeed.guidePage.subtitle")}

{/* Intro card */}

{t("categoriesSeed.guidePage.intro.title")}

{t("categoriesSeed.guidePage.intro.body")}

{/* Counter + toolbar */}

{t("categoriesSeed.guidePage.counter", { roots: counts.roots, subcategories: counts.subcategories, leaves: counts.leaves, total, })}

{/* Toolbar: search + actions (hidden in print) */}
{/* Tree */}
); }