import { useEffect, useState } from "react"; import { api } from "../api"; import { useConfirm } from "../confirm"; import Icon from "../components/Icon"; import DataTable from "../components/DataTable"; /** * Hausmaße – Stammdaten. * * Hier stehen nur die **Namen** („Esslöffel", „Tasse"). Die Mengen gehören * nicht hierher, sondern an die Kategorie oder den Artikel: Ein Esslöffel Mehl * sind etwa 10 g, einer Zucker etwa 12 g, und eine Tasse Milch ist Milliliter. * Ein globaler Wert wäre bei jedem zweiten Artikel falsch. * * Deshalb ist diese Seite absichtlich kurz. Die Arbeit passiert unter * Kategorien ▸ Maße & Frist. */ export default function Masse() { const confirm = useConfirm(); const [masse, setMasse] = useState([]); const [form, setForm] = useState({ name: "", short: "" }); const [error, setError] = useState(null); const [loading, setLoading] = useState(true); async function load() { setLoading(true); try { setMasse(await api.listMeasures()); setError(null); } catch (err) { setError(err.message); } finally { setLoading(false); } } useEffect(() => { load(); }, []); async function add(e) { e.preventDefault(); setError(null); try { await api.createMeasure({ name: form.name.trim(), short: form.short.trim() || null, position: masse.length, }); setForm({ name: "", short: "" }); load(); } catch (err) { setError(err.message); } } async function patch(mass, body) { setError(null); try { await api.updateMeasure(mass.id, { name: body.name ?? mass.name, short: body.short !== undefined ? body.short : mass.short, position: mass.position, }); load(); } catch (err) { setError(err.message); load(); } } async function remove(mass) { const ok = await confirm({ title: `Maß „${mass.name}" löschen?`, message: "Die bei Kategorien und Artikeln hinterlegten Mengen dieses Maßes " + "verschwinden mit. Buchungen, die damit gemacht wurden, bleiben.", confirmLabel: "Löschen", danger: true, }); if (!ok) return; try { await api.deleteMeasure(mass.id); load(); } catch (err) { setError(err.message); } } const columns = [ { key: "name", header: "Name", grow: true, min: 160, filterText: (m) => m.name, sortValue: (m) => m.name, render: (m) => ( { const v = e.target.value.trim(); if (v && v !== m.name) patch(m, { name: v }); }} /> {m.is_builtin && eingebaut} ) }, { key: "short", header: "Kurzform", width: 160, filterText: (m) => m.short || "", render: (m) => ( { const v = e.target.value.trim(); if (v !== (m.short || "")) patch(m, { short: v || null }); }} /> ) }, { key: "actions", header: "", label: "Aktionen", fixed: true, width: 56, align: "num", render: (m) => ( ) }, ]; return (
Unter Kategorien öffnet der Knopf „Maße & Frist" je Kategorie die Mengen – dort trägst du ein, dass ein Esslöffel bei Mehl 10 g sind. Unterkategorien erben das; der nächste Vorfahr mit einem Eintrag gewinnt. Einzelne Artikel können davon abweichen.