import { useMemo, useState } from "react"; import Icon from "../components/Icon"; import { ZEITRAEUME } from "./cards"; import { locationOptions } from "../locationPath"; import { artikelLabel } from "../units"; /** * Konfig-Dialog einer Karte – wie in HomeAssistant: ein eigener Dialog mit den * Optionen der Karte, statt Dropdowns im Kartenkopf. Welche Felder erscheinen, * bestimmt `karte.config`. Die Werte landen in den Karten-Props (bzw. `tage` * beim Zeitraum) und werden mit dem Layout gespeichert. */ export default function KartenConfig({ karte, props: karteProps = {}, tage, produkte = [], locations = [], onProps, onTage, onClose, }) { const felder = karte?.config || []; function feld(f) { if (f.type === "product") { return ( onProps({ [f.key]: id ?? undefined })} /> ); } if (f.type === "location") { return ( ); } if (f.type === "zeitraum") { return ( ); } if (f.type === "select") { return ( ); } if (f.type === "boolean") { return ( ); } return null; } return (
e.target === e.currentTarget && onClose()}>

{karte?.titel} einstellen

{felder.length === 0 ?

Diese Karte hat keine Einstellungen.

: felder.map(feld)}
); } /** * Artikel aussuchen – mit Suchfeld und sprechenden Zeilen. * * Eine blanke Auswahlliste ueber den ganzen Katalog ist unbrauchbar: Sie ist * hunderte Zeilen lang, und weil nur der Name darin stand, standen "Pesto * Rosso" und "Pesto Rosso" untereinander, ohne Unterschied. Jetzt steht Marke * und Gebindegroesse dabei, und das Suchfeld daruber kuerzt die Liste auf das, * was man meint. */ function ArtikelWahl({ label, produkte, wert, onWahl }) { const [suche, setSuche] = useState(""); const gefiltert = useMemo(() => { const begriffe = suche.toLowerCase().split(/\s+/).filter(Boolean); if (begriffe.length === 0) return produkte; return produkte.filter((p) => { const text = artikelLabel(p).toLowerCase(); return begriffe.every((b) => text.includes(b)); }); }, [produkte, suche]); // Der gewaehlte Artikel muss in der Liste bleiben, auch wenn die Suche ihn // gerade ausblendet - sonst zeigt das Feld nichts an und ein Klick daneben // wuerde die Wahl verwerfen. const gewaehlt = produkte.find((p) => String(p.id) === String(wert)); const sichtbar = gewaehlt && !gefiltert.includes(gewaehlt) ? [gewaehlt, ...gefiltert] : gefiltert; return (

{suche ? `${gefiltert.length} von ${produkte.length} Artikeln` : `${produkte.length} Artikel`}

); }