From cea238149b8c205c0398b43171e69699c4f5b5f1 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Mon, 7 Sep 2026 14:39:08 +0200 Subject: [PATCH] fix: Bei einem langen Formular war "Speichern" nicht erreichbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der Dialog wuchs mit seinem Inhalt und lief unten aus dem Bild. Scrollen ging nicht – damit war der Knopf schlicht weg, und das Konto liess sich nicht mehr speichern. Jetzt bleibt der Dialog im Fenster: Kopf und Knopfleiste stehen fest, nur der Inhalt dazwischen rollt. Co-Authored-By: Claude Opus 5 --- web/src/components/Icon.jsx | 218 ++++++++++++++++++++++++++++++ web/src/components/IconPicker.jsx | 21 ++- web/src/styles.css | 16 ++- 3 files changed, 248 insertions(+), 7 deletions(-) diff --git a/web/src/components/Icon.jsx b/web/src/components/Icon.jsx index d6cc4d0..91154af 100644 --- a/web/src/components/Icon.jsx +++ b/web/src/components/Icon.jsx @@ -344,6 +344,224 @@ const PATHS = { ), + // --- Ausgabe-Kategorien (Nachtrag) -------------------------------------- + heart: ( + + ), + // Notgroschen: Der Tresor sagt "beiseitegelegt", nicht "ausgegeben". + vault: ( + <> + + + + + + + + ), + umbrella: ( + <> + + + + + ), + "life-buoy": ( + <> + + + + + + + + ), + // Dienstleistung, Handwerk, Reparatur. + wrench: ( + + ), + hammer: ( + <> + + + + + ), + briefcase: ( + <> + + + + ), + "book-open": ( + <> + + + + ), + music: ( + <> + + + + + ), + coffee: ( + <> + + + + + + ), + wine: ( + <> + + + + + + ), + fuel: ( + <> + + + + + + ), + bus: ( + <> + + + + + + + + + ), + bike: ( + <> + + + + + + ), + phone: ( + + ), + pill: ( + <> + + + + ), + scissors: ( + <> + + + + + + ), + sparkle: ( + + ), + zap: ( + + ), + droplet: ( + + ), + flame: ( + + ), + store: ( + <> + + + + + + ), + "shopping-bag": ( + <> + + + + + ), + ticket: ( + <> + + + + + + ), + monitor: ( + <> + + + + + ), + cloud: ( + + ), + newspaper: ( + <> + + + + + + ), + cake: ( + <> + + + + + + + + ), + bed: ( + <> + + + + + + ), + baby: ( + <> + + + + + + ), + sprout: ( + <> + + + + + + ), + scale: ( + <> + + + + + + + ), }; export default function Icon({ name, size = 18, className = "", strokeWidth = 2 }) { diff --git a/web/src/components/IconPicker.jsx b/web/src/components/IconPicker.jsx index a739927..f9c0c23 100644 --- a/web/src/components/IconPicker.jsx +++ b/web/src/components/IconPicker.jsx @@ -1,14 +1,25 @@ import Icon from "./Icon"; export const ACCOUNT_ICONS = [ - "wallet", "landmark", "piggy-bank", "credit-card", "trending-up", "banknote", "coins", + "wallet", "landmark", "piggy-bank", "vault", "credit-card", "trending-up", + "banknote", "coins", ]; +// Lose nach Lebensbereich sortiert, damit man beim Suchen nicht das ganze +// Gitter absuchen muss: Wohnen, Alltag, Unterwegs, Gesundheit & Koerper, +// Freizeit, Familie, Geld & Vorsorge, Sonstiges. export const CATEGORY_ICONS = [ - "home", "shopping-cart", "utensils", "car", "shield", "heart-pulse", "film", - "refresh-ccw", "shirt", "wifi", "plane", "gift", "graduation-cap", "dumbbell", - "paw-print", "piggy-bank", "percent", "more-horizontal", "banknote", "coins", - "receipt", "list", "landmark", "wallet", "trending-up", "credit-card", + "home", "bed", "zap", "droplet", "flame", "wifi", "monitor", "cloud", + "shopping-cart", "shopping-bag", "store", "utensils", "coffee", "wine", + "shirt", "scissors", "sparkle", + "car", "fuel", "bus", "bike", "plane", "ticket", + "heart-pulse", "pill", "dumbbell", + "film", "music", "book-open", "newspaper", "graduation-cap", "paw-print", + "sprout", "cake", "gift", "baby", "heart", + "piggy-bank", "vault", "umbrella", "life-buoy", "shield", "scale", + "briefcase", "wrench", "hammer", "phone", "refresh-ccw", "percent", + "receipt", "banknote", "coins", "landmark", "wallet", "trending-up", + "credit-card", "list", "more-horizontal", ]; // Auswahlgitter für ein Icon. `value` ist der aktuell gewählte Icon-Name. diff --git a/web/src/styles.css b/web/src/styles.css index 2e840bf..e7a802e 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -695,10 +695,22 @@ td select { width: auto; min-width: 0; max-width: 100%; } border-radius: var(--radius); padding: var(--sp-5); box-shadow: 0 12px 32px rgba(9, 12, 18, 0.28); + /* Ein langes Formular darf nicht unten aus dem Bild laufen: Der Dialog + bleibt im Fenster, nur sein Inhalt rollt. Kopf und Knopfleiste stehen + fest – sonst ist "Speichern" bei einem hohen Formular nicht erreichbar. */ + display: flex; flex-direction: column; + max-height: calc(100vh - 2 * var(--sp-4)); + min-height: 0; } -.modal-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); } +.modal-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); flex: none; } .modal-head h2 { margin: 0; } -.modal-body { margin: 0 0 var(--sp-5); color: var(--muted); font-size: 0.9rem; } +.modal-body { + margin: 0 0 var(--sp-5); color: var(--muted); font-size: 0.9rem; + overflow-y: auto; min-height: 0; + /* Platz fuer den Fokusrahmen, den `overflow` sonst abschneidet. */ + padding: 2px; +} +.modal > .btn-pair { flex: none; } .icon-danger { color: var(--danger); } /* Gefuellter Knopf fuer unwiderrufliche Schritte - der flache .btn.danger geht in einem Dialog zu leicht unter. */