Verlauf: klarere Bewegungs-Icons, Spalte nach vorn
Die beiden Kisten unterschieden sich nur in einem kleinen Pfeil. Bei 18 px war das nicht zu trennen - erkannt hat man sie allein an der Farbe, und die war gerade wegen der Wertung (gruen rein, orange raus) rausgeflogen. Ohne Farbe blieb nichts uebrig, woran man sie auseinanderhaelt. Jetzt die Strich-Icons checkin/checkout/edit: grosser Pfeil auf eine Linie zu bzw. von ihr weg, Stift fuer die Korrektur. Dieselben Zeichen wie auf den Ein-/Auslagern-Knoepfen, also schon vertraut, und auch klein eindeutig - die Richtung liegt im Zeichen statt in der Farbe. Auf der Verlaufsseite steht die Spalte jetzt an erster Stelle; sie sagt in einem Blick worum es geht und braucht als Zeichen kaum Breite. Der gefuellte Icon-Zweig in Icon.jsx wird damit nicht mehr gebraucht und ist raus. Die SVG-Quellen bleiben unter brand/icons/ liegen - das README sagt jetzt ausdruecklich, dass sie ungenutzt sind, warum, und wie man sie zurueckholt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,9 +8,8 @@ Name `box`) in Weiß auf der Akzentfläche.
|
|||||||
- **`app-icon.svg`** – 1024×1024, vollflächig, feste Farbe (`#4d5cd4`), ohne
|
- **`app-icon.svg`** – 1024×1024, vollflächig, feste Farbe (`#4d5cd4`), ohne
|
||||||
abgerundete Ecken. Für App-Icon (iOS/macOS via Icon Composer oder Xcode
|
abgerundete Ecken. Für App-Icon (iOS/macOS via Icon Composer oder Xcode
|
||||||
„AppIcon", App Store). Die Rundung macht das System selbst.
|
„AppIcon", App Store). Die Rundung macht das System selbst.
|
||||||
- **`icons/`** – Quellgrafiken der gefüllten Icons (Ein-/Auslagern, Korrektur).
|
- **`icons/`** – Quellgrafiken für Ein-/Auslagern und Korrektur. Derzeit nicht
|
||||||
Ihre Pfaddaten stehen inline in `../web/src/components/Icon.jsx`; siehe
|
im Einsatz; siehe `icons/README.md`.
|
||||||
`icons/README.md`.
|
|
||||||
- **Favicon / Web-Logo:** `../web/public/favicon.svg` – dasselbe Zeichen mit
|
- **Favicon / Web-Logo:** `../web/public/favicon.svg` – dasselbe Zeichen mit
|
||||||
abgerundeter Platte und Hell-/Dunkel-Umschaltung (für den Browser-Tab).
|
abgerundeter Platte und Hell-/Dunkel-Umschaltung (für den Browser-Tab).
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +1,32 @@
|
|||||||
# Icon-Quellen
|
# Icon-Quellen
|
||||||
|
|
||||||
Hier liegen zugekaufte/heruntergeladene Grafiken, deren Pfaddaten **inline** in
|
> **Derzeit nicht im Einsatz.** Die Verlaufsansicht nutzt die Strich-Icons
|
||||||
`web/src/components/Icon.jsx` stehen (Abschnitt `GEFUELLT`). Zur Laufzeit lädt
|
> `checkin` / `checkout` / `edit` aus `web/src/components/Icon.jsx` – dieselben
|
||||||
niemand diese Dateien – sie sind die Quelle, nicht das Auslieferungsformat.
|
> wie die Ein-/Auslagern-Knöpfe.
|
||||||
|
>
|
||||||
Warum inline statt `<img src>`: Die Icons sollen die Textfarbe annehmen
|
> Grund: Die beiden Kisten unterscheiden sich **nur in der Pfeilrichtung**. Bei
|
||||||
(`fill="currentColor"`), damit sie sich mit Thema und Zustand mitfärben. Als
|
> 18–20 px war das nicht zu trennen; erkannt hat man sie allein an der Farbe,
|
||||||
externe Datei ginge das nicht; die Originale tragen eine feste schwarze Füllung.
|
> und die trug mit Grün/Orange eine Wertung, die es nicht geben soll –
|
||||||
|
> Auslagern ist kein Missstand. Die Dateien bleiben liegen, falls sie später
|
||||||
|
> woanders passen; größer dargestellt trennen sie sehr wohl.
|
||||||
|
|
||||||
## Dateien
|
## Dateien
|
||||||
|
|
||||||
| Datei | Icon-Name | Bedeutung |
|
| Datei | Bedeutung |
|
||||||
|---|---|---|
|
|---|---|
|
||||||
| `einlagern.svg` | `einlagern` | Kiste, Pfeil **hinein** – Bewegungsart „Eingelagert" |
|
| `einlagern.svg` | Kiste, Pfeil **hinein** – Bewegungsart „Eingelagert" |
|
||||||
| `auslagern.svg` | `auslagern` | Kiste, Pfeil **heraus** – Bewegungsart „Ausgelagert" |
|
| `auslagern.svg` | Kiste, Pfeil **heraus** – Bewegungsart „Ausgelagert" |
|
||||||
| `korrektur.svg` | `korrektur` | Stapel mit Stift – Bewegungsart „Korrektur" |
|
| `korrektur.svg` | Stapel mit Stift – Bewegungsart „Korrektur" |
|
||||||
|
|
||||||
Die beiden Kisten unterscheiden sich nur in **einem** Pfad: der Pfeilrichtung.
|
## Wieder einbauen
|
||||||
Wer sie verwechselt, dreht Ein- und Auslagern um, ohne dass etwas kaputtgeht –
|
|
||||||
deshalb die ausdrückliche Zuordnung oben.
|
|
||||||
|
|
||||||
## Nach einer Änderung neu übernehmen
|
Es sind gefüllte Grafiken mit eigenem `viewBox`; die übrigen in `Icon.jsx` sind
|
||||||
|
Strichzeichnungen (`fill:none`, `stroke:currentColor`) und vertragen sich nicht
|
||||||
|
damit. Es braucht also wieder einen eigenen Zweig, der mit
|
||||||
|
`fill="currentColor"` rendert – inline, damit die Icons die Textfarbe annehmen
|
||||||
|
(die Originale tragen festes Schwarz).
|
||||||
|
|
||||||
Die Pfaddaten wurden per Skript übernommen, nicht abgetippt. Wird eine Datei
|
Die Pfaddaten übernimmt man mit einem kurzen Skript, statt sie abzutippen:
|
||||||
ersetzt, dieselbe Extraktion wiederholen und das Ergebnis in `GEFUELLT`
|
`viewBox` aus dem `<svg>`-Tag lesen und alle `d="…"` der enthaltenen `<path>`
|
||||||
eintragen (`viewBox` mitnehmen – die Kisten sind 24×24, die Korrektur 64×64):
|
ausgeben. Ein Tippfehler in den Kurvendaten fällt sonst erst am gerenderten
|
||||||
|
Bild auf.
|
||||||
```sh
|
|
||||||
python3 - <<'PY'
|
|
||||||
import re, pathlib
|
|
||||||
for name in ("einlagern", "auslagern", "korrektur"):
|
|
||||||
roh = pathlib.Path(f"brand/icons/{name}.svg").read_text()
|
|
||||||
print(name, re.search(r'viewBox="([^"]+)"', roh).group(1))
|
|
||||||
for d in re.findall(r'<path[^>]*\sd="([^"]+)"', roh):
|
|
||||||
print(f' <path d="{d}" />')
|
|
||||||
PY
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -3,18 +3,23 @@ import Icon from "./Icon";
|
|||||||
/**
|
/**
|
||||||
* Die Art einer Bestandsbewegung als Sinnbild statt als Wort.
|
* Die Art einer Bestandsbewegung als Sinnbild statt als Wort.
|
||||||
*
|
*
|
||||||
* Kiste mit Pfeil hinein (Einlagern), Kiste mit Pfeil heraus (Auslagern),
|
* Grosser Pfeil auf eine Linie zu (Einlagern), von ihr weg (Auslagern), Stift
|
||||||
* Stapel mit Stift (Korrektur). Alle drei in derselben Farbe: gruen fuer rein
|
* (Korrektur) – dieselben Zeichen wie auf den Ein-/Auslagern-Knoepfen.
|
||||||
* und orange fuer raus las sich wie gut und schlecht, dabei ist Auslagern
|
*
|
||||||
* schlicht der Normalfall. Unterschieden wird ueber die Pfeilrichtung.
|
* Vorher standen hier zwei gefuellte Kisten, die sich NUR in einem kleinen
|
||||||
|
* Pfeil unterschieden. Bei 18 px war das nicht zu trennen; erkannt hat man sie
|
||||||
|
* allein an der Farbe – und die trug mit Gruen/Orange eine Wertung, die es
|
||||||
|
* nicht geben soll. Auslagern ist kein Missstand.
|
||||||
|
*
|
||||||
|
* Deshalb: eine Farbe fuer alle drei, die Richtung liegt im Zeichen selbst.
|
||||||
*
|
*
|
||||||
* Titel und aria-label behalten das Wort: fuer Screenreader und fuer alle, die
|
* Titel und aria-label behalten das Wort: fuer Screenreader und fuer alle, die
|
||||||
* ein Sinnbild nicht auf Anhieb lesen.
|
* ein Sinnbild nicht auf Anhieb lesen.
|
||||||
*/
|
*/
|
||||||
const LABEL = { in: "Eingelagert", out: "Ausgelagert", adjust: "Korrektur" };
|
const LABEL = { in: "Eingelagert", out: "Ausgelagert", adjust: "Korrektur" };
|
||||||
const ICON = { in: "einlagern", out: "auslagern", adjust: "korrektur" };
|
const ICON = { in: "checkin", out: "checkout", adjust: "edit" };
|
||||||
|
|
||||||
export default function BewegungIcon({ typ, size = 18 }) {
|
export default function BewegungIcon({ typ, size = 19 }) {
|
||||||
const wort = LABEL[typ] || typ;
|
const wort = LABEL[typ] || typ;
|
||||||
return (
|
return (
|
||||||
<span className="bewegung-icon" title={wort} aria-label={wort} role="img">
|
<span className="bewegung-icon" title={wort} aria-label={wort} role="img">
|
||||||
|
|||||||
@@ -143,72 +143,7 @@ const PATHS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Gefuellte Icons mit EIGENEM viewBox. Die uebrigen hier sind Strichzeichnungen
|
|
||||||
// (fill:none, stroke:currentColor); diese kommen als fertige Grafik und muessen
|
|
||||||
// deshalb getrennt gehalten werden.
|
|
||||||
//
|
|
||||||
// Quelle der Pfade: brand/icons/*.svg (dort steht auch, wie man sie nach einer
|
|
||||||
// Aenderung neu uebernimmt). Inline statt <img>, damit sie ueber currentColor
|
|
||||||
// die Textfarbe annehmen – die Originaldateien tragen festes Schwarz.
|
|
||||||
const GEFUELLT = {
|
|
||||||
// Kiste mit Pfeil HINEIN – aus open-box (1).svg
|
|
||||||
einlagern: {
|
|
||||||
viewBox: "0 0 24 24",
|
|
||||||
node: (
|
|
||||||
<>
|
|
||||||
<path d="m11.987 24c-.03 0-.061-.002-.09-.006l-8.243-1c-.377-.045-.66-.365-.66-.744v-6c0-.414.336-.75.75-.75s.75.336.75.75v5.336l6.743.817v-11.543c-.034-.236.044-.482.234-.655.221-.2.543-.258.813-.136.271.12.452.384.452.681v12.5c0 .215-.092.419-.253.562-.136.122-.313.188-.496.188z" />
|
|
||||||
<path d="m12.007 24c-.183 0-.359-.066-.497-.188-.161-.143-.253-.347-.253-.562v-12.25c0-.414.336-.75.75-.75s.75.336.75.75v11.403l6.742-.817v-5.336c0-.414.336-.75.75-.75s.75.336.75.75v6c0 .379-.283.699-.659.744l-8.242 1c-.031.004-.061.006-.091.006z" />
|
|
||||||
<path d="m22.25 17h-6.753c-.257 0-.495-.131-.633-.348l-3.494-5.5c-.155-.245-.156-.558-.002-.803.155-.244.439-.379.725-.344l8.246 1c.263.031.488.198.596.439l2.001 4.5c.103.232.082.5-.057.713s-.375.343-.629.343zm-6.341-1.5h5.187l-1.359-3.057-6.251-.758z" />
|
|
||||||
<path d="m8.503 17h-6.753c-.254 0-.49-.129-.629-.342s-.159-.48-.057-.713l2.001-4.5c.107-.241.333-.408.596-.439l8.246-1c.286-.036.569.1.725.344.154.245.153.558-.002.803l-3.494 5.5c-.138.216-.376.347-.633.347zm-5.599-1.5h5.187l2.424-3.814-6.251.758z" />
|
|
||||||
<path d="m12 8c-.414 0-.75-.336-.75-.75v-6.5c0-.414.336-.75.75-.75s.75.336.75.75v6.5c0 .414-.336.75-.75.75z" />
|
|
||||||
<path d="m12 8c-.161 0-.322-.052-.457-.155l-3.25-2.5c-.328-.253-.39-.724-.138-1.052.253-.328.724-.391 1.052-.138l2.793 2.149 2.793-2.148c.328-.253.799-.19 1.052.138.252.328.19.799-.138 1.052l-3.25 2.5c-.135.102-.296.154-.457.154z" />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Kiste mit Pfeil HERAUS – aus open-box.svg
|
|
||||||
auslagern: {
|
|
||||||
viewBox: "0 0 24 24",
|
|
||||||
node: (
|
|
||||||
<>
|
|
||||||
<path d="m11.987 24c-.03 0-.061-.002-.09-.006l-8.243-1c-.377-.045-.66-.365-.66-.744v-6c0-.414.336-.75.75-.75s.75.336.75.75v5.336l6.743.817v-11.543c-.034-.236.044-.482.234-.655.221-.2.543-.258.813-.136.271.12.452.384.452.681v12.5c0 .215-.092.419-.253.562-.136.122-.313.188-.496.188z" />
|
|
||||||
<path d="m12.007 24c-.183 0-.359-.066-.497-.188-.161-.143-.253-.347-.253-.562v-12.25c0-.414.336-.75.75-.75s.75.336.75.75v11.403l6.742-.817v-5.336c0-.414.336-.75.75-.75s.75.336.75.75v6c0 .379-.283.699-.659.744l-8.242 1c-.031.004-.061.006-.091.006z" />
|
|
||||||
<path d="m22.25 17h-6.753c-.257 0-.495-.131-.633-.348l-3.494-5.5c-.155-.245-.156-.558-.002-.803.155-.244.44-.379.725-.344l8.246 1c.263.031.488.198.596.439l2.001 4.5c.103.232.082.5-.057.713s-.375.343-.629.343zm-6.341-1.5h5.187l-1.359-3.057-6.251-.758z" />
|
|
||||||
<path d="m8.503 17h-6.753c-.254 0-.49-.129-.629-.342s-.159-.48-.057-.713l2.001-4.5c.107-.241.333-.408.596-.439l8.246-1c.288-.036.569.1.725.344.154.245.153.558-.002.803l-3.494 5.5c-.138.216-.376.347-.633.347zm-5.599-1.5h5.187l2.424-3.814-6.251.758z" />
|
|
||||||
<path d="m12 8c-.414 0-.75-.336-.75-.75v-6.5c0-.414.336-.75.75-.75s.75.336.75.75v6.5c0 .414-.336.75-.75.75z" />
|
|
||||||
<path d="m15.249 4c-.159 0-.32-.051-.456-.155l-2.793-2.149-2.793 2.149c-.328.252-.799.19-1.052-.138-.252-.328-.19-.799.138-1.052l3.25-2.5c.27-.207.645-.207.914 0l3.25 2.5c.328.253.39.724.138 1.052-.149.192-.37.293-.596.293z" />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
// Stapel mit Stift – aus edit-server.svg
|
|
||||||
korrektur: {
|
|
||||||
viewBox: "0 0 64 64",
|
|
||||||
node: (
|
|
||||||
<>
|
|
||||||
<path d="m64 39.97-8.58-8.58-18.48 18.47-3.86 12.36 12.44-3.76zm-25.83 17.21 1.73-5.53 15.52-15.52 3.84 3.84-15.51 15.53z" />
|
|
||||||
<path d="m26.74 34.89c10.1 0 20.29-2.02 24.6-5.92h2.14v-18.79c0-6.67-13.45-10.16-26.73-10.16-13.3.01-26.75 3.5-26.75 10.16v43.62c0 6.67 13.45 10.17 26.74 10.17v-3.35c-14.28 0-23.39-4.04-23.39-6.82v-9.35c4.82 3.28 14.14 4.97 23.39 4.97 1.9 0 3.72-.07 5.42-.2l-.26-3.34c-1.61.12-3.35.19-5.16.19-14.28 0-23.39-4.04-23.39-6.82v-9.35c4.82 3.29 14.14 4.99 23.39 4.99zm0-31.51c14.28 0 23.38 4.03 23.38 6.81s-9.11 6.81-23.38 6.81-23.39-4.04-23.39-6.82c0-2.77 9.11-6.8 23.39-6.8zm-23.39 12c.02.01.04.02.06.04.28.19.57.37.88.55.03.02.06.03.08.05.29.17.6.33.91.48.05.03.1.05.16.08 5.14 2.5 13.25 3.78 21.3 3.78s16.16-1.28 21.3-3.78c.05-.03.11-.05.16-.08.32-.16.62-.32.91-.48.03-.01.05-.03.08-.04.31-.18.6-.36.88-.55.02-.01.04-.02.06-.04v9.35c0 2.78-9.11 6.81-23.38 6.81s-23.4-4.05-23.4-6.82z" />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function Icon({ name, size = 18, className = "", strokeWidth = 2 }) {
|
export default function Icon({ name, size = 18, className = "", strokeWidth = 2 }) {
|
||||||
const gefuellt = GEFUELLT[name];
|
|
||||||
if (gefuellt) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
className={`icon ${className}`}
|
|
||||||
width={size}
|
|
||||||
height={size}
|
|
||||||
viewBox={gefuellt.viewBox}
|
|
||||||
fill="currentColor"
|
|
||||||
stroke="none"
|
|
||||||
aria-hidden="true"
|
|
||||||
focusable="false"
|
|
||||||
>
|
|
||||||
{gefuellt.node}
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const path = PATHS[name];
|
const path = PATHS[name];
|
||||||
if (!path) return null;
|
if (!path) return null;
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ export default function History() {
|
|||||||
<table className="table">
|
<table className="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
{/* Die Bewegungsart zuerst: sie sagt in einem Blick, worum
|
||||||
|
es geht, und braucht als Zeichen kaum Breite. */}
|
||||||
|
<th style={{ width: 64 }}>Aktion</th>
|
||||||
<th>Zeitpunkt</th>
|
<th>Zeitpunkt</th>
|
||||||
<th>Aktion</th>
|
|
||||||
<th>Produkt</th>
|
<th>Produkt</th>
|
||||||
<th className="num">Menge</th>
|
<th className="num">Menge</th>
|
||||||
<th>Benutzer</th>
|
<th>Benutzer</th>
|
||||||
@@ -37,11 +39,11 @@ export default function History() {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{movements.map((m) => (
|
{movements.map((m) => (
|
||||||
<tr key={m.id}>
|
<tr key={m.id}>
|
||||||
<td data-label="Zeitpunkt" className="muted">{new Date(m.created_at).toLocaleString("de-DE")}</td>
|
|
||||||
{/* Nur das Sinnbild – die Tabelle hat noch Menge und
|
{/* Nur das Sinnbild – die Tabelle hat noch Menge und
|
||||||
Benutzer zu zeigen, und das Wort stand ohnehin dreimal
|
Benutzer zu zeigen, und das Wort stand ohnehin dreimal
|
||||||
untereinander. Titel und aria-label tragen es weiter. */}
|
untereinander. Titel und aria-label tragen es weiter. */}
|
||||||
<td data-label="Aktion"><BewegungIcon typ={m.type} /></td>
|
<td data-label="Aktion"><BewegungIcon typ={m.type} /></td>
|
||||||
|
<td data-label="Zeitpunkt" className="muted">{new Date(m.created_at).toLocaleString("de-DE")}</td>
|
||||||
<td data-label="Produkt">{m.product_name}</td>
|
<td data-label="Produkt">{m.product_name}</td>
|
||||||
<td data-label="Menge" className="num">
|
<td data-label="Menge" className="num">
|
||||||
{articlePrimary(m)}
|
{articlePrimary(m)}
|
||||||
|
|||||||
Reference in New Issue
Block a user