Verlauf: Bewegungsart als Sinnbild statt als Wort

"Eingelagert"/"Ausgelagert"/"Korrektur" standen als Textbadge in einer eigenen
Spalte - in der schmalen Ansicht als dritte beschriftete Zeile je Eintrag. Jetzt
eine getoente Kachel mit Icon: Kiste mit Pfeil hinein, Kiste mit Pfeil heraus,
Stapel mit Stift (aus open-box (1).svg, open-box.svg, edit-server.svg). Die
Farbe traegt dieselbe Bedeutung wie vorher das Badge - gruen rein, orange raus,
neutral Korrektur; Titel und aria-label behalten das Wort.

Die Dashboard-Karte bekommt dabei das Layout aus der Skizze: Kachel links,
Zeitpunkt ueber Produkt, ohne Tabelle. Die Verlaufs-SEITE bleibt eine Tabelle -
dort stehen noch Menge und Benutzer -, dort weicht nur das Wort der Kachel.

Die Icon-Komponente kann jetzt auch GEFUELLTE Grafiken mit eigenem viewBox; die
vorhandenen sind Strichzeichnungen (fill:none, stroke:currentColor) und
vertragen sich damit nicht. Die Pfaddaten sind per Skript aus den SVGs
uebernommen, nicht abgetippt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-16 12:38:05 +02:00
parent e9a2b70728
commit 9a2dc3a482
8 changed files with 136 additions and 30 deletions

View File

@@ -4,6 +4,7 @@ import { api } from "../api";
import Icon from "../components/Icon";
import { CardSkeleton } from "../components/Skeleton";
import ShoppingNeedText from "../components/ShoppingNeedText";
import BewegungIcon from "../components/BewegungIcon";
import { useSettings } from "../settings";
import {
articlePrimary, articleSecondary, fmt, relativeExpiry,
@@ -393,33 +394,29 @@ function KarteEinkaufsliste({ props: karteProps }) {
);
}
const BEWEGUNG_LABEL = { in: "Eingelagert", out: "Ausgelagert", adjust: "Korrektur" };
function KarteBewegungen() {
const { daten, fehler } = useDaten(() => api.listMovements(20));
return (
<Zustand fehler={fehler} daten={daten} leer="Noch keine Bewegungen.">
<div className="table-wrap">
<table className="table">
<thead><tr><th>Zeitpunkt</th><th>Aktion</th><th>Produkt</th></tr></thead>
<tbody>
{(daten || []).map((m) => (
<tr key={m.id}>
<td data-label="Zeitpunkt" className="muted">
{new Date(m.created_at).toLocaleString("de-DE", {
day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit",
})}
</td>
<td data-label="Aktion">
<span className={`badge ${m.type === "in" ? "ok" : m.type === "out" ? "warn" : ""}`}>
{BEWEGUNG_LABEL[m.type] || m.type}
</span>
</td>
<td data-label="Produkt">{m.product_name}</td>
</tr>
))}
</tbody>
</table>
{/* Kachel links, Zeitpunkt ueber Produkt. Die Bewegungsart trug frueher
eine eigene Spalte mit dem Wort „Ausgelagert" als Sinnbild kostet
sie keine Zeile mehr und bleibt auf einen Blick erkennbar. */}
<div className="bewegung-liste">
{(daten || []).map((m) => (
<div className="bewegung-zeile" key={m.id}>
<BewegungIcon typ={m.type} />
<div className="text">
<div className="zeit">
{new Date(m.created_at).toLocaleString("de-DE", {
day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit",
})}
</div>
<div className="produkt">{m.product_name}</div>
</div>
</div>
))}
</div>
</Zustand>
);