Web: Kassenzettel-Trefferschwelle in den Einstellungen

Prozent-Feld fuer receipt_match_threshold (Default 45) analog zur Ablaufwarnung;
speichert ueber den generischen Settings-Endpunkt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-30 18:26:20 +02:00
parent 91adee5333
commit 9cc3e325bb

View File

@@ -10,11 +10,13 @@ import { DATE_FORMATS, formatDate } from "../units";
import { applyFavicon } from "../branding";
const EXPIRY_KEY = "expiry_warning_days";
const RECEIPT_KEY = "receipt_match_threshold";
export default function Settings() {
const { reload } = useSettings();
const toast = useToast();
const [days, setDays] = useState("");
const [threshold, setThreshold] = useState("");
const [dateFormat, setDateFormat] = useState("de");
const [error, setError] = useState(null);
const [busy, setBusy] = useState(false);
@@ -23,6 +25,7 @@ export default function Settings() {
try {
const settings = await api.listSettings();
setDays(settings.find((s) => s.key === EXPIRY_KEY)?.value ?? "7");
setThreshold(settings.find((s) => s.key === RECEIPT_KEY)?.value ?? "45");
setDateFormat(settings.find((s) => s.key === DATE_FORMAT_KEY)?.value ?? "de");
} catch (err) {
setError(err.message);
@@ -36,6 +39,7 @@ export default function Settings() {
setError(null); setBusy(true);
try {
await api.setSetting(EXPIRY_KEY, String(parseInt(days, 10)));
await api.setSetting(RECEIPT_KEY, String(Math.max(0, Math.min(100, parseInt(threshold, 10) || 0))));
await api.setSetting(DATE_FORMAT_KEY, dateFormat);
await reload();
toast("Gespeichert.");
@@ -71,6 +75,20 @@ export default function Settings() {
bereits überschritten ist), erscheinen auf der Übersicht unter Bald ablaufend.
</p>
<div className="card-head" style={{ marginTop: "var(--sp-5)" }}>
<Icon name="cart" /><h2>Kassenzettel-Scan</h2>
</div>
<label>
Trefferschwelle (%)
<input type="number" min="0" max="100" step="1" value={threshold}
onChange={(e) => setThreshold(e.target.value)} style={{ maxWidth: 160 }} />
</label>
<p className="muted small mt-0">
Beim Scannen eines Kassenzettels (iOS) werden je Zeile nur Artikel vorgeschlagen,
deren Übereinstimmung mindestens so hoch ist. Höher = strenger (weniger, dafür
sicherere Vorschläge), niedriger = mehr Vorschläge.
</p>
<div className="card-head" style={{ marginTop: "var(--sp-5)" }}>
<Icon name="settings" /><h2>Darstellung</h2>
</div>