import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import { api } from "../api"; import { useAuth } from "../auth"; import Icon from "../components/Icon"; import { ProduktThumb } from "../components/ProduktBild"; import { fmt, gebinde, unitShort } from "../units"; import { asTree } from "../categoryTree"; import CategorySelect from "../components/CategorySelect"; // Wie viele Basiseinheiten eine "Artikeleinheit" umfasst (Gebinde oder Produkteinheit). function unitCount(p) { return p.package_size && p.package_size > 0 ? p.package_size : (p.unit_factor || 1); } // Mengenabhaengig, damit "3 Gläser" dasteht und nicht "3 Glas". function countLabel(p, menge) { return p.package_size && p.package_size > 0 ? gebinde(menge, p.package_label) : (p.unit_name || unitShort(p.base_unit)); } export default function Products() { const { isAdmin } = useAuth(); const [products, setProducts] = useState([]); const [q, setQ] = useState(""); const [categories, setCategories] = useState([]); // "" = alle, "0" = ohne Kategorie, sonst die ID (Unterkategorien zaehlen mit). const [categoryId, setCategoryId] = useState(""); // "" = alle, sonst "food"/"object": trennt Lebensmittel und Gegenstände. const [typ, setTyp] = useState(""); const [error, setError] = useState(null); async function load(cat = categoryId) { try { setProducts(await api.listProducts(q, cat)); } catch (err) { setError(err.message); } } useEffect(() => { load(); api.listCategories().then(setCategories).catch(() => {}); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); function onSearch(e) { e.preventDefault(); load(); } // Typ umschalten: passt der Kategoriefilter nicht mehr, zurücksetzen. function changeTyp(neu) { setTyp(neu); if (neu && categoryId && categoryId !== "0") { const cat = categories.find((c) => String(c.id) === String(categoryId)); if (cat && cat.tracking !== neu) { setCategoryId(""); load(""); } } } const sichtbar = products.filter((p) => !typ || p.tracking === typ); return (

Produkte

{sichtbar.length} Produkte{typ ? (typ === "food" ? " · Lebensmittel" : " · Gegenstände") : " im Katalog"}
{isAdmin && ( Neues Produkt )}
{error &&
{error}
}
{sichtbar.map((p) => { const low = p.min_stock != null && p.stock < p.min_stock; return ( ); })} {sichtbar.length === 0 && ( )}
Name Marke Kategorie Einheit Bestand Einheiten (ist / soll)
{p.name} {p.expired_count > 0 && ( {p.expired_count} abgelaufen )} {p.brand || "–"} {p.category_name || "–"} {p.unit_name || unitShort(p.base_unit)} {p.package_size ? ` · ${p.package_label || "Packung"} ${fmt(p.package_size)} ${unitShort(p.base_unit)}` : ""} {fmt(p.stock / (p.unit_factor || 1))} {p.unit_name || unitShort(p.base_unit)} {fmt(p.stock / unitCount(p))} {p.min_stock != null ? ` / ${fmt(p.min_stock / unitCount(p))}` : ""}{" "} {countLabel(p, p.stock / unitCount(p))} {low && niedrig} Details
Keine Produkte gefunden.
); }