From 550abd30e7150a21bda7a59c90f794cd12c3ad97 Mon Sep 17 00:00:00 2001 From: s4luorth Date: Thu, 1 Oct 2026 12:48:35 +0200 Subject: [PATCH] Fix: Empfaenger/Suche (company-Feld), kontraststarke feste Farben + sichtbare Rahmen ROOT CAUSE Empfaenger-"-" + tote Suche: order_entries hat KEIN company-Feld. Die Abfrage forderte company an -> 403/FORBIDDEN -> ganzer Request scheiterte -> Empfaenger-Index leer -> "-" ueberall + Suche ohne Daten. company aus allen order_entries-Abfragen entfernt. Echte Empfaenger stehen in free_text (wird gelesen). Farben/Barrierefreiheit: Extensions nutzten alte Directus-10-Variablen (--border-normal etc.), die im aktuellen Theme nicht definiert sind -> blasse/ unsichtbare Rahmen, verschwimmende Farben. Alle unzuverlaessigen Theme-Variablen durch feste, kontraststarke Farben ersetzt (WCAG-AA, helles Weiss-Blau-Theme): sichtbare Rahmen (#b4c0d2), dunklere Labels (#566070), Text (#1b2430). Status- und Ablauf-Pillen mit soliden Farben + Rahmen + kraeftigerer Schrift. Co-Authored-By: Claude Opus 4.8 --- .../dist/index.js | 50 ++--- .../dist/index.js | 206 +++++++++--------- .../dist/index.js | 110 +++++----- 3 files changed, 183 insertions(+), 183 deletions(-) diff --git a/extensions/directus-extension-skrift-neuauftrag/dist/index.js b/extensions/directus-extension-skrift-neuauftrag/dist/index.js index c955168..d9b9520 100644 --- a/extensions/directus-extension-skrift-neuauftrag/dist/index.js +++ b/extensions/directus-extension-skrift-neuauftrag/dist/index.js @@ -14,10 +14,10 @@ import { useApi } from '@directus/extensions-sdk'; const ACCENT = '#1E50A5'; // Klar umrandetes, theme-sicheres Eingabefeld (dezente Füllung → sieht wie ein Feld aus). -const WFELD = 'background:var(--background-subdued,#f4f6fa);border:1px solid var(--border-normal);border-radius:8px;padding:10px 12px;font:inherit;font-size:14px;color:var(--foreground-normal);outline:none;'; +const WFELD = 'background:#eef2f8;border:1px solid #b4c0d2;border-radius:8px;padding:10px 12px;font:inherit;font-size:14px;color:#1b2430;outline:none;'; const WSELECT = WFELD + 'cursor:pointer;'; // Bereich = klar abgegrenzte weiße Karte mit sichtbarem Rahmen + feinem Schatten. -const BEREICH = 'background:var(--background-page,#fff);border:1px solid var(--border-normal);border-radius:12px;padding:20px 22px;box-shadow:0 1px 2px rgba(16,24,40,.05);'; +const BEREICH = 'background:#ffffff;border:1px solid #b4c0d2;border-radius:12px;padding:20px 22px;box-shadow:0 1px 2px rgba(16,24,40,.05);'; const STANDARD_PLATZHALTER = ['Anrede', 'Vorname', 'Nachname', 'Strasse', 'PLZ', 'Ort', 'Land', 'Briefnummer']; // Echtes Directus-Icon (Material Symbols) statt Emoji. @@ -25,20 +25,20 @@ const icon = (name, extra = {}) => h(resolveComponent('v-icon'), { name, small: function btn(label, onClick, kind, ic) { const base = 'cursor:pointer;border-radius:8px;padding:9px 16px;font:inherit;font-size:14px;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;border:1px solid;'; const style = kind === 'primary' ? base + `border-color:${ACCENT};background:${ACCENT};color:#fff;` - : base + 'border-color:var(--border-normal);background:var(--background-page,#fff);color:var(--foreground-normal);'; + : base + 'border-color:#b4c0d2;background:#ffffff;color:#1b2430;'; return h('button', { type: 'button', onClick, style }, [ic ? icon(ic) : null, label].filter(Boolean)); } -function subdued(t, extra) { return h('div', { style: `color:var(--foreground-subdued);font-size:13px;${extra || ''}` }, t); } +function subdued(t, extra) { return h('div', { style: `color:#566070;font-size:13px;${extra || ''}` }, t); } function segToggle(value, opts, onSel) { - return h('div', { style: 'display:flex;width:100%;border-radius:8px;overflow:hidden;border:1px solid var(--border-normal);background:var(--background-page,#fff);' }, + return h('div', { style: 'display:flex;width:100%;border-radius:8px;overflow:hidden;border:1px solid #b4c0d2;background:#ffffff;' }, opts.map((o) => h('button', { type: 'button', onClick: () => onSel(o.key), style: `flex:1;padding:10px 8px;font:inherit;font-size:13px;text-align:center;cursor:pointer;border:none;` - + (value === o.key ? `background:${ACCENT};color:#fff;font-weight:500;` : `background:transparent;color:var(--foreground-normal);`), + + (value === o.key ? `background:${ACCENT};color:#fff;font-weight:500;` : `background:transparent;color:#1b2430;`), }, o.label))); } -function bereichKopf(ic, txt) { return h('div', { style: 'display:flex;align-items:center;gap:8px;font-size:15px;font-weight:600;color:var(--foreground-normal);margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--border-subdued);' }, [h('span', { style: `color:${ACCENT};display:inline-flex;align-items:center;` }, icon(ic)), txt]); } -function label(txt) { return h('label', { style: 'display:block;font-size:11.5px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--foreground-subdued);margin-bottom:5px;' }, txt); } +function bereichKopf(ic, txt) { return h('div', { style: 'display:flex;align-items:center;gap:8px;font-size:15px;font-weight:600;color:#1b2430;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #d2dae6;' }, [h('span', { style: `color:${ACCENT};display:inline-flex;align-items:center;` }, icon(ic)), txt]); } +function label(txt) { return h('label', { style: 'display:block;font-size:11.5px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:#566070;margin-bottom:5px;' }, txt); } const NeuAuftrag = defineComponent({ setup() { @@ -541,13 +541,13 @@ const NeuAuftrag = defineComponent({ const txt = (d?.art === 'umschlag' ? '✉ Kuvert' : '📄 Schriftstück') + seite; return h('div', { style: 'display:flex;flex-direction:column;align-items:center;gap:4px;' }, [ src ? h('img', { src, onClick: () => { neu.lb = src; neu.lbDoc = d; }, style: 'width:100%;max-height:260px;object-fit:contain;border-radius:6px;background:#fff;cursor:zoom-in;box-shadow:0 1px 3px rgba(0,0,0,.12);' }) - : h('div', { style: 'width:100%;height:200px;border-radius:6px;display:flex;align-items:center;justify-content:center;background:#fff;color:var(--foreground-subdued);' }, 'Dok.'), - h('span', { style: 'font-size:11px;color:var(--foreground-subdued);' }, txt), + : h('div', { style: 'width:100%;height:200px;border-radius:6px;display:flex;align-items:center;justify-content:center;background:#fff;color:#566070;' }, 'Dok.'), + h('span', { style: 'font-size:11px;color:#566070;' }, txt), ]); }; // Weißes, einzeiliges Zellenfeld (feste Breite → Zeile scrollt bei Bedarf). const feld = (lbl, val, on, ph, onPaste) => h('div', { style: 'display:flex;flex-direction:column;gap:3px;flex:1 1 0;min-width:90px;' }, [ - h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--foreground-subdued);' }, lbl), + h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:#566070;' }, lbl), h('input', { value: val, placeholder: ph || '', style: WFELD + 'width:100%;padding:7px 9px;font-size:13px;', onInput: on, onPaste }), ]); @@ -605,7 +605,7 @@ const NeuAuftrag = defineComponent({ h('input', { type: 'number', min: 1, max: 1000, step: 1, value: neu.anzahl, style: WFELD + 'width:170px;', onInput: (e) => { neu.anzahl = e.target.value; neu.previewSession = null; }, onBlur: (e) => { const n = Math.round(Number(e.target.value)); neu.anzahl = (Number.isFinite(n) && n) ? Math.max(1, Math.min(1000, n)) : 1; } }), - h('div', { style: 'font-size:12px;color:var(--foreground-subdued,#888);margin-top:6px;line-height:1.5;' }, + h('div', { style: 'font-size:12px;color:#566070;margin-top:6px;line-height:1.5;' }, 'Ohne Kuvert werden keine Empfängeradressen gebraucht – es entstehen so viele gleiche Schriftstücke wie angegeben. ' + 'Sobald „Kuverts generieren" aktiv ist oder der Text eigene [[Platzhalter]] enthält, erscheint wieder die Empfängertabelle.'), ]) : h('div', {}, [ @@ -613,7 +613,7 @@ const NeuAuftrag = defineComponent({ neu.rows.map((e, i) => h('div', { style: 'display:flex;gap:8px;align-items:center;' }, [ h('span', { style: `min-width:22px;font-weight:700;color:${ACCENT};` }, `#${i + 1}`), h('div', { style: 'flex:1;min-width:0;display:flex;gap:6px;flex-wrap:nowrap;overflow-x:auto;padding-bottom:2px;' }, zeile(e, i)), - h('button', { type: 'button', onClick: () => delZeile(i), style: 'cursor:pointer;border:none;background:transparent;color:var(--danger,#c62828);font-size:18px;padding:2px 6px;' }, '×'), + h('button', { type: 'button', onClick: () => delZeile(i), style: 'cursor:pointer;border:none;background:transparent;color:#c0392b;font-size:18px;padding:2px 6px;' }, '×'), ]))), h('div', { style: 'margin-top:12px;display:grid;grid-template-columns:1fr 1fr;gap:12px;' }, [ btn('+ Empfänger', addZeile), @@ -621,7 +621,7 @@ const NeuAuftrag = defineComponent({ ]), ]), // Postkarte: Hinweis auf das Kartenlayout; kein separates Kuvert. - istPostkarte() ? h('div', { style: 'font-size:12px;color:var(--foreground-subdued,#888);margin-top:12px;line-height:1.5;' }, + istPostkarte() ? h('div', { style: 'font-size:12px;color:#566070;margin-top:12px;line-height:1.5;' }, 'Postkarte: Text auf der linken Hälfte, Absender + Empfänger rechts, Briefmarkenfeld oben rechts frei. Ein separates Kuvert wird nicht erzeugt.') : null, !istPostkarte() ? h('label', { style: 'display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer;margin-top:12px;' }, [ h('input', { type: 'checkbox', checked: neu.kuverts, onChange: (e) => { neu.kuverts = e.target.checked; neu.previewSession = null; }, style: 'width:16px;height:16px;' }), @@ -650,7 +650,7 @@ const NeuAuftrag = defineComponent({ onInput: (e) => { neu.envelopeSenderScale = e.target.value; neu.previewSession = null; }, onBlur: (e) => { const n = Math.round(Number(e.target.value)); neu.envelopeSenderScale = (Number.isFinite(n) && n) ? Math.max(50, Math.min(200, n)) : 100; } }), ]), - h('div', { style: 'font-size:11px;color:var(--foreground-subdued,#888);margin-top:4px;line-height:1.5;' }, + h('div', { style: 'font-size:11px;color:#566070;margin-top:4px;line-height:1.5;' }, istPostkarte() ? 'Empfänger steht darunter in der Anschriftzone (rechte Hälfte).' : 'Der Empfänger rutscht dann auf dem Kuvert automatisch nach unten rechts.'), ]) : null, (neu.importOpen && !identischModus()) ? h('div', { style: 'margin-top:12px;' }, [ @@ -682,7 +682,7 @@ const NeuAuftrag = defineComponent({ neu.previewSession = null; requestAnimationFrame(() => { try { ta.selectionStart = ta.selectionEnd = s + 1; } catch {} }); } }), - h('div', { style: 'font-size:11px;color:var(--foreground-subdued,#888);margin-top:4px;line-height:1.5;' }, + h('div', { style: 'font-size:11px;color:#566070;margin-top:4px;line-height:1.5;' }, 'Tipp: [[seitenumbruch]] erzwingt an dieser Stelle eine neue Seite (mehrseitiger Brief). [[signatur1]] setzt die Unterschrift. ' + 'Platzhalter: [[Vorname]], [[Nachname]], [[Anrede]], [[Strasse]], [[PLZ]], [[Ort]] – im 5-Zeilen-Modus außerdem [[Zeile1]]…[[Zeile5]].'), // ── Unterschrift auf den Brief ───────────────────────────────────── @@ -727,12 +727,12 @@ const NeuAuftrag = defineComponent({ h('div', { style: 'flex:1 1 280px;max-width:420px;' }, [ label('Kunde verknüpfen (E-Mail, optional)'), h('input', { type: 'email', value: neu.customer_email, placeholder: 'kunde@example.de', style: WFELD + 'width:100%;', onInput: (e) => { neu.customer_email = e.target.value; pruefeKunde(); } }), - neu.kundeStatus === 'vorhanden' ? h('div', { style: 'font-size:12px;color:var(--success,#2e7d32);margin-top:5px;font-weight:600;' }, '✓ Bestehender Kunde wird verknüpft') : null, + neu.kundeStatus === 'vorhanden' ? h('div', { style: 'font-size:12px;color:#1b6b2e;margin-top:5px;font-weight:600;' }, '✓ Bestehender Kunde wird verknüpft') : null, neu.kundeStatus === 'neu' ? h('div', { style: 'font-size:12px;color:#1E50A5;margin-top:5px;font-weight:600;' }, 'Neuer Kunde – bitte unten Stammdaten erfassen.') : null, ]), ]), // Neukundenanlage erzwingen, sobald eine unbekannte E-Mail eingetragen ist. - neu.kundeStatus === 'neu' ? h('div', { style: 'margin-top:14px;border:1px solid var(--border-normal);border-radius:10px;padding:16px;background:var(--background-subdued,#f1f4f9);' }, [ + neu.kundeStatus === 'neu' ? h('div', { style: 'margin-top:14px;border:1px solid #b4c0d2;border-radius:10px;padding:16px;background:#eef2f8;' }, [ h('div', { style: 'font-weight:600;margin-bottom:10px;' }, 'Neuen Kunden anlegen'), h('div', { style: 'display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;' }, [ h('div', {}, [label('Vorname'), h('input', { value: neu.kundeVorname, style: WFELD + 'width:100%;', onInput: (e) => { neu.kundeVorname = e.target.value; } })]), @@ -751,8 +751,8 @@ const NeuAuftrag = defineComponent({ ]); const aktionen = h('div', { class: 'sk-btnrow', style: 'display:flex;gap:8px;flex-wrap:wrap;' }, [ - neu.hinweis ? h('div', { style: `color:var(--danger,#c62828);font-size:13px;width:100%;` }, neu.hinweis) : null, - neu.err ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;width:100%;' }, neu.err) : null, + neu.hinweis ? h('div', { style: `color:#c0392b;font-size:13px;width:100%;` }, neu.hinweis) : null, + neu.err ? h('div', { style: 'color:#c0392b;font-size:13px;width:100%;' }, neu.err) : null, neu.msg ? h('div', { style: 'width:100%;' }, subdued(neu.msg)) : null, btn(neu.pLaedt ? 'Vorschau …' : '👁 Vorschau', preview), btn('In Druck geben', absenden, 'primary'), @@ -776,7 +776,7 @@ const NeuAuftrag = defineComponent({ btn('Berechnen', seitenBerechnen), ]), neu.seitenInfo - ? h('pre', { style: 'margin:0;white-space:pre-wrap;font:inherit;font-size:13px;color:var(--foreground);' }, neu.seitenInfo) + ? h('pre', { style: 'margin:0;white-space:pre-wrap;font:inherit;font-size:13px;color:#1b2430;' }, neu.seitenInfo) : subdued('„Berechnen" klicken – zeigt, wie viele Seiten je Empfänger entstehen.'), ]) : null, ]); @@ -894,7 +894,7 @@ const NeuAuftrag = defineComponent({ function signaturPanel() { const sigFeld = (s, k, lbl, step) => h('div', { style: 'display:flex;flex-direction:column;gap:3px;flex:1;min-width:90px;' }, [ - h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:var(--foreground-subdued);' }, lbl), + h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:#566070;' }, lbl), h('input', { value: s[k], type: k === 'marker_key' ? 'text' : 'number', step: step || 'any', style: WFELD + 'width:100%;padding:7px 9px;font-size:13px;', onInput: (e) => { s[k] = k === 'marker_key' ? e.target.value : (parseFloat(e.target.value) || 0); sig.pdf = ''; } }), @@ -964,7 +964,7 @@ const NeuAuftrag = defineComponent({ ]), ]); const meldung = h('div', {}, [ - sig.err ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;margin-top:8px;' }, sig.err) : null, + sig.err ? h('div', { style: 'color:#c0392b;font-size:13px;margin-top:8px;' }, sig.err) : null, sig.msg ? subdued(sig.msg, 'margin-top:8px;') : null, ]); const links = h('div', { style: 'flex:1;min-width:0;display:flex;flex-direction:column;gap:16px;' }, [b1, b2, meldung]); @@ -984,7 +984,7 @@ const NeuAuftrag = defineComponent({ const navItem = (label, aktiv, onClick) => h('div', { onClick, style: 'display:flex;align-items:center;gap:8px;border-radius:6px;padding:10px 12px;margin-bottom:3px;font-size:14px;cursor:pointer;' - + (aktiv ? `background:${ACCENT};color:#fff;font-weight:600;` : 'color:var(--foreground-normal);'), + + (aktiv ? `background:${ACCENT};color:#fff;font-weight:600;` : 'color:#1b2430;'), }, label); return () => h(resolveComponent('private-view'), { title: ansicht.value === 'signatur' ? 'Unterschriften' : 'Neuer Auftrag' }, { @@ -995,7 +995,7 @@ const NeuAuftrag = defineComponent({ default: () => [ // Mobil: Button-Reihen bleiben in einer Zeile und füllen die Breite. h('style', {}, '@media(max-width:640px){.sk-btnrow>button{flex:1 1 auto!important;}}'), - h('div', { style: 'padding:24px 28px;background:var(--background-subdued,#f1f4f9);min-height:100%;' }, + h('div', { style: 'padding:24px 28px;background:#eef2f8;min-height:100%;' }, ansicht.value === 'signatur' ? signaturPanel() : (!geladen.value ? subdued('Lädt …') : formular())), neu.lb ? h(Teleport, { to: 'body' }, [ h('div', { diff --git a/extensions/directus-extension-skrift-produktion/dist/index.js b/extensions/directus-extension-skrift-produktion/dist/index.js index 148ba98..a484c26 100644 --- a/extensions/directus-extension-skrift-produktion/dist/index.js +++ b/extensions/directus-extension-skrift-produktion/dist/index.js @@ -69,12 +69,12 @@ const STATUS_LABEL = { }; // Farbe + Material-Icon je Produktionsstatus (für den klaren Status-Pill). const STATUS_META = { - eingegangen: { bg: 'var(--background-subdued,#eef1f6)', fg: 'var(--foreground-subdued)', icon: 'inbox' }, - im_druck: { bg: 'rgba(30,80,165,.12)', fg: '#1E50A5', icon: 'print' }, - kuvertieren: { bg: 'rgba(106,63,208,.12)', fg: '#6a3fd0', icon: 'mail' }, - versandfertig: { bg: 'rgba(230,160,0,.16)', fg: '#8a6d00', icon: 'inventory_2' }, - versendet: { bg: 'rgba(46,125,50,.14)', fg: 'var(--success,#2e7d32)', icon: 'local_shipping' }, - storniert: { bg: 'rgba(198,40,40,.12)', fg: 'var(--danger,#c62828)', icon: 'cancel' }, + eingegangen: { bg: '#eef2f8', fg: '#566070', bd: '#d2dae6', icon: 'inbox' }, + im_druck: { bg: '#e3ecfa', fg: '#1E50A5', bd: '#bcd0ef', icon: 'print' }, + kuvertieren: { bg: '#ece4fb', fg: '#5b32b8', bd: '#d3c4f2', icon: 'mail' }, + versandfertig: { bg: '#fbeccb', fg: '#8a5a00', bd: '#f0d79a', icon: 'inventory_2' }, + versendet: { bg: '#e3f4e6', fg: '#1b6b2e', bd: '#bfe2c6', icon: 'local_shipping' }, + storniert: { bg: '#fbe3e0', fg: '#c0392b', bd: '#f3c6bf', icon: 'cancel' }, }; // Tage, nach denen ein versendeter Auftrag automatisch ins Archiv wandert. const ARCHIV_TAGE = 14; @@ -86,11 +86,11 @@ const PARAM_FELDER = [ // Einheitliche, ruhige Optik über das ganze Board (Directus-Theme-Variablen → // Light/Dark-sicher). Flach, klare Hierarchie, großzügige Abstände. // Karte: 12px Radius, Haarlinie, dezenter Schatten, viel Innenabstand. -const CARD = 'border:1px solid var(--border-subdued);border-radius:12px;padding:18px 20px;background:var(--background-page,#fff);box-shadow:0 1px 2px rgba(0,0,0,.04);'; +const CARD = 'border:1px solid #d2dae6;border-radius:12px;padding:18px 20px;background:#ffffff;box-shadow:0 1px 2px rgba(0,0,0,.04);'; // Getönte Sektion (Formulare). -const SECTION = 'background:var(--background-subdued,#f1f4f9);border:1px solid var(--border-subdued);border-radius:12px;padding:18px 20px;margin-bottom:16px;'; -const S_FELD = 'border:1px solid var(--border-normal);border-radius:8px;padding:8px 11px;background:var(--background-page,#fff);'; -const S_INPUT = 'padding:8px 11px;border:1px solid var(--border-normal);border-radius:8px;background:var(--background-page);color:var(--foreground-normal);font:inherit;font-size:14px;'; +const SECTION = 'background:#eef2f8;border:1px solid #d2dae6;border-radius:12px;padding:18px 20px;margin-bottom:16px;'; +const S_FELD = 'border:1px solid #b4c0d2;border-radius:8px;padding:8px 11px;background:#ffffff;'; +const S_INPUT = 'padding:8px 11px;border:1px solid #b4c0d2;border-radius:8px;background:#ffffff;color:#1b2430;font:inherit;font-size:14px;'; const S_SELECT = S_INPUT + 'cursor:pointer;'; // Directus-Primärfarbe (Marke) + Vorgangs-Akzente. @@ -109,40 +109,40 @@ function btn(label, onClick, kind, ic) { const style = kind === 'primary' ? base + `border-color:${ACCENT};background:${ACCENT};color:#fff;` : kind === 'danger' - ? base + 'border-color:var(--border-normal);background:var(--background-page,#fff);color:var(--danger,#c62828);' - : base + 'border-color:var(--border-normal);background:var(--background-page,#fff);color:var(--foreground-normal);'; + ? base + 'border-color:#b4c0d2;background:#ffffff;color:#c0392b;' + : base + 'border-color:#b4c0d2;background:#ffffff;color:#1b2430;'; return h('button', { type: 'button', onClick, style }, [ic ? icon(ic) : null, label].filter(Boolean)); } // Pill (Status/Badge): ruhig, lesbar. farbe = Hintergrund (Theme-Tint), textFarbe optional. function chip(text, farbe, textFarbe) { return h('span', { style: `display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:500;padding:3px 11px;border-radius:999px;` - + `background:${farbe || 'var(--background-subdued)'};color:${textFarbe || 'var(--foreground-subdued)'};white-space:nowrap;`, + + `background:${farbe || '#eef2f8'};color:${textFarbe || '#566070'};white-space:nowrap;`, }, text); } function subdued(text, extra) { - return h('div', { style: `color:var(--foreground-subdued);font-size:13px;${extra || ''}` }, text); + return h('div', { style: `color:#566070;font-size:13px;${extra || ''}` }, text); } // Eckdaten-Zeile: eine ruhige Zeile „Icon Wert · Icon Wert" statt Chip-Wand. function metaItem(text) { - return h('span', { style: 'display:inline-flex;align-items:center;gap:5px;color:var(--foreground-subdued);font-size:13.5px;white-space:nowrap;' }, text); + return h('span', { style: 'display:inline-flex;align-items:center;gap:5px;color:#566070;font-size:13.5px;white-space:nowrap;' }, text); } // Beschriftete Eckdaten-Kachel (Label oben, Wert darunter) – klare Struktur. function tile(labelTxt, value, gross) { - return h('div', { style: 'background:var(--background-subdued,#f1f4f9);border:1px solid var(--border-normal);border-radius:8px;padding:9px 12px;min-width:0;' }, [ - h('div', { style: 'font-size:11.5px;color:var(--foreground-subdued);' }, labelTxt), + return h('div', { style: 'background:#eef2f8;border:1px solid #b4c0d2;border-radius:8px;padding:9px 12px;min-width:0;' }, [ + h('div', { style: 'font-size:11.5px;color:#566070;' }, labelTxt), h('div', { style: `font-weight:500;overflow:hidden;text-overflow:ellipsis;${gross ? 'font-size:20px;line-height:1.1;margin-top:2px;' : 'font-size:15px;margin-top:3px;'}` }, value), ]); } // Feld-Beschriftung über einem Eingabefeld. function feldLabel(t) { - return h('label', { style: 'display:block;font-size:13px;font-weight:500;color:var(--foreground-subdued);margin-bottom:5px;' }, t); + return h('label', { style: 'display:block;font-size:13px;font-weight:500;color:#566070;margin-bottom:5px;' }, t); } // Editierbares Notizfeld (speichert beim Verlassen/Blur) – klar sichtbares Feld. function notizFeld(wert, onSave, ph) { return h('textarea', { rows: 2, placeholder: ph || 'Notiz …', - style: 'width:100%;box-sizing:border-box;border:1px solid var(--border-normal);border-radius:8px;padding:9px 11px;font:inherit;font-size:14px;background:var(--background-page);color:var(--foreground-normal);resize:vertical;min-height:44px;', + style: 'width:100%;box-sizing:border-box;border:1px solid #b4c0d2;border-radius:8px;padding:9px 11px;font:inherit;font-size:14px;background:#ffffff;color:#1b2430;resize:vertical;min-height:44px;', value: wert || '', onChange: (e) => onSave(e.target.value), }, wert || ''); @@ -166,12 +166,12 @@ function zielInland(e) { } // Segmentierter Umschalter mit sichtbarem Rahmen: Optionen teilen sich die Breite. function segToggle(value, opts, onSel) { - return h('div', { style: 'display:flex;width:100%;border:1px solid var(--border-normal);border-radius:8px;overflow:hidden;background:var(--background-subdued,#f1f4f9);' }, + return h('div', { style: 'display:flex;width:100%;border:1px solid #b4c0d2;border-radius:8px;overflow:hidden;background:#eef2f8;' }, opts.map((o, i) => h('button', { type: 'button', disabled: o.disabled, onClick: () => { if (!o.disabled) onSel(o.key); }, style: `flex:1;padding:12px 8px;font:inherit;font-size:13px;text-align:center;cursor:${o.disabled ? 'not-allowed' : 'pointer'};border:none;` - + (i > 0 ? 'border-left:1px solid var(--border-normal);' : '') - + (value === o.key ? `background:${ACCENT};color:#fff;font-weight:700;` : 'background:transparent;color:var(--foreground-normal);') + + (i > 0 ? 'border-left:1px solid #b4c0d2;' : '') + + (value === o.key ? `background:${ACCENT};color:#fff;font-weight:700;` : 'background:transparent;color:#1b2430;') + (o.disabled ? 'opacity:.45;' : ''), }, o.label))); } @@ -1369,16 +1369,16 @@ const Board = defineComponent({ function weiteresPanel(o) { const dz = druckIndex.value[String(o.id)]; const nm = empfNamen.value[String(o.id)]; - const feld = 'width:100%;box-sizing:border-box;border:1px solid var(--border-normal);border-radius:8px;padding:9px 11px;font:inherit;font-size:14px;background:var(--background-page);color:var(--foreground-normal);'; - return h('div', { style: 'border:1px solid var(--border-normal);border-radius:10px;overflow:hidden;' }, [ - h('div', { style: 'display:flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:var(--foreground-subdued);padding:9px 14px;border-bottom:1px solid var(--border-subdued);background:var(--background-subdued,#f6f8fb);' }, [icon('tune'), 'Weiteres']), + const feld = 'width:100%;box-sizing:border-box;border:1px solid #b4c0d2;border-radius:8px;padding:9px 11px;font:inherit;font-size:14px;background:#ffffff;color:#1b2430;'; + return h('div', { style: 'border:1px solid #b4c0d2;border-radius:10px;overflow:hidden;' }, [ + h('div', { style: 'display:flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:#566070;padding:9px 14px;border-bottom:1px solid #d2dae6;background:#eef2f8;' }, [icon('tune'), 'Weiteres']), h('div', { style: 'padding:14px;display:flex;flex-direction:column;gap:14px;' }, [ // Druckverlauf: wann gedruckt + erster/letzter Empfänger. h('div', {}, [ - h('div', { style: 'font-size:11.5px;font-weight:500;color:var(--foreground-subdued);text-transform:uppercase;letter-spacing:.03em;margin-bottom:5px;' }, 'Druckverlauf'), + h('div', { style: 'font-size:11.5px;font-weight:500;color:#566070;text-transform:uppercase;letter-spacing:.03em;margin-bottom:5px;' }, 'Druckverlauf'), h('div', { style: 'font-size:14px;line-height:1.6;' }, [ h('div', {}, dz ? `In den Druck: ${dmYhm(dz.erste)}${dz.letzte && dz.letzte.slice(0, 16) !== dz.erste.slice(0, 16) ? ' – ' + dmYhm(dz.letzte) : ''}` : 'Noch nicht gedruckt.'), - nm ? h('div', { style: 'color:var(--foreground-subdued);' }, `Erster: ${nm.erste}${nm.anzahl > 1 ? ` · Letzter: ${nm.letzte}` : ''}`) : null, + nm ? h('div', { style: 'color:#566070;' }, `Erster: ${nm.erste}${nm.anzahl > 1 ? ` · Letzter: ${nm.letzte}` : ''}`) : null, ]), ]), // Verknüpfungen: beschriftete Felder. @@ -1389,13 +1389,13 @@ const Board = defineComponent({ o.customer ? h('div', { style: 'display:flex;align-items:center;gap:8px;' }, [ h('span', { style: 'font-size:14px;' }, `${kundeName(o)}${o.customer.email ? ' · ' + o.customer.email : ''}`), - h('button', { type: 'button', title: 'Kontakt lösen', onClick: () => setOrderCustomer(o, ''), style: 'cursor:pointer;border:1px solid var(--border-normal);background:var(--background-page);border-radius:8px;padding:5px 10px;font:inherit;font-size:13px;color:var(--danger,#c62828);' }, 'lösen'), + h('button', { type: 'button', title: 'Kontakt lösen', onClick: () => setOrderCustomer(o, ''), style: 'cursor:pointer;border:1px solid #b4c0d2;background:#ffffff;border-radius:8px;padding:5px 10px;font:inherit;font-size:13px;color:#c0392b;' }, 'lösen'), ]) : h('input', { placeholder: 'kunde@example.de', style: feld, onChange: (e) => setOrderCustomer(o, e.target.value) }), ]), ]), // Aktionen (abgetrennt). - h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;border-top:1px solid var(--border-subdued);padding-top:14px;' }, [ + h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;border-top:1px solid #d2dae6;padding-top:14px;' }, [ btn(o.keep_contacts ? 'In Kontakte gespeichert' : 'In Kontakte speichern', () => toggleKeepContacts(o), o.keep_contacts ? 'primary' : 'default', o.keep_contacts ? 'how_to_reg' : 'contacts'), btn('Neu generieren', () => regenerieren(o.id), 'danger', 'autorenew'), @@ -1408,10 +1408,10 @@ const Board = defineComponent({ const k = order.production_status || 'eingegangen'; const m = STATUS_META[k] || STATUS_META.eingegangen; // Farbiger Pill, der zugleich das Status-Dropdown ist (ein Element, klarer Status). - return h('div', { style: `display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:6px 12px 6px 14px;background:${m.bg};color:${m.fg};font-weight:500;font-size:13px;flex-shrink:0;` }, [ + return h('div', { style: `display:inline-flex;align-items:center;gap:6px;border-radius:999px;padding:6px 12px 6px 14px;background:${m.bg};color:${m.fg};border:1px solid ${m.bd || '#d2dae6'};font-weight:600;font-size:13px;flex-shrink:0;` }, [ icon(m.icon), h('select', { - style: `border:none;background:transparent;color:${m.fg};font:inherit;font-size:13px;font-weight:500;cursor:pointer;padding:0;`, + style: `border:none;background:transparent;color:${m.fg};font:inherit;font-size:13px;font-weight:600;cursor:pointer;padding:0;`, value: k, onChange: (e) => setStatus(order, e.target.value), }, Object.entries(STATUS_LABEL).map(([kk, v]) => h('option', { value: kk, selected: k === kk }, v))), ]); @@ -1433,16 +1433,16 @@ const Board = defineComponent({ const bezahlt = o.payment_status === 'bezahlt'; const identName = kundeName(o); // ── KOPF (getönt): Auswahl/Griff + Identität + Status ────────────────── - const kopf = h('div', { style: 'display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;padding:14px 16px;background:var(--background-subdued,#f6f8fb);border-bottom:1px solid var(--border-subdued);' }, [ + const kopf = h('div', { style: 'display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;padding:14px 16px;background:#eef2f8;border-bottom:1px solid #d2dae6;' }, [ h('div', { style: 'display:flex;gap:12px;align-items:flex-start;min-width:0;flex:1;' }, [ opts2.dragHandle - ? h('span', { style: 'color:var(--foreground-subdued);cursor:grab;margin-top:3px;flex-shrink:0;', title: 'Ziehen zum Sortieren' }, icon('drag_indicator')) + ? h('span', { style: 'color:#566070;cursor:grab;margin-top:3px;flex-shrink:0;', title: 'Ziehen zum Sortieren' }, icon('drag_indicator')) : h('input', { type: 'checkbox', checked: istGewaehlt(o.id), onClick: (e) => toggleAuswahl(o.id, e), title: 'Für Sammel-Druck auswählen', style: 'width:19px;height:19px;margin-top:3px;cursor:pointer;flex-shrink:0;' }), h('div', { style: 'min-width:0;' }, [ o.order_name ? h('div', { style: 'font-size:12px;font-weight:500;color:#1E50A5;text-transform:uppercase;letter-spacing:.03em;margin-bottom:1px;' }, o.order_name) : null, h('div', { style: 'font-size:20px;font-weight:500;letter-spacing:-.01em;line-height:1.2;' }, identName || `#${o.order_number}`), - h('div', { style: 'font-size:14px;color:var(--foreground-subdued);margin-top:2px;' }, (identName ? `#${o.order_number} · ` : '') + `${o.entries_count || 0} Empfänger`), + h('div', { style: 'font-size:14px;color:#566070;margin-top:2px;' }, (identName ? `#${o.order_number} · ` : '') + `${o.entries_count || 0} Empfänger`), ]), ]), statusSelect(o), @@ -1458,9 +1458,9 @@ const Board = defineComponent({ const send = sendIndex.value[String(o.id)]; const briefOk = !!o.brief_gedruckt || !!(send && send.brief.length); const kuvOk = !!o.kuvert_gedruckt || !!(send && send.umschlag.length); - const statusWort = (ok, ranges) => h('span', { style: `font-weight:500;color:${ok ? 'var(--success,#2e7d32)' : 'var(--danger,#c62828)'};` }, + const statusWort = (ok, ranges) => h('span', { style: `font-weight:500;color:${ok ? '#1b6b2e' : '#c0392b'};` }, ok ? ('gedruckt' + (ranges && ranges.length ? ' · ' + ranges.join(', ') : '')) : 'nicht gedruckt'); - const druckStrip = h('div', { style: 'display:flex;gap:20px;flex-wrap:wrap;padding:10px 12px;background:var(--background-subdued,#f6f8fb);border:1px solid var(--border-normal);border-radius:8px;font-size:14px;' }, [ + const druckStrip = h('div', { style: 'display:flex;gap:20px;flex-wrap:wrap;padding:10px 12px;background:#eef2f8;border:1px solid #b4c0d2;border-radius:8px;font-size:14px;' }, [ h('span', { style: 'display:inline-flex;align-items:center;gap:6px;' }, [icon('description'), 'Brief: ', statusWort(briefOk, send && send.brief)]), o.needs_envelope ? h('span', { style: 'display:inline-flex;align-items:center;gap:6px;' }, [icon('mail'), 'Kuvert: ', statusWort(kuvOk, send && send.umschlag)]) : null, ].filter(Boolean)); @@ -1471,26 +1471,26 @@ const Board = defineComponent({ : null, o.linked_order?.order_number ? chip('Kuverts: #' + o.linked_order.order_number) : null, o.approval_status === 'pending' ? chip('wartet auf Freigabe', 'rgba(230,160,0,.18)', '#8a6d00') : null, - o.approval_status === 'approved' ? chip('Motiv freigegeben', 'rgba(46,125,50,.14)', 'var(--success,#2e7d32)') : null, - o.approval_status === 'changes' ? chip('Änderungswunsch', 'rgba(198,40,40,.14)', 'var(--danger,#c62828)') : null, + o.approval_status === 'approved' ? chip('Motiv freigegeben', 'rgba(46,125,50,.14)', '#1b6b2e') : null, + o.approval_status === 'changes' ? chip('Änderungswunsch', 'rgba(198,40,40,.14)', '#c0392b') : null, ].filter(Boolean); const pillRow = pills.length ? h('div', { style: 'display:flex;gap:7px;flex-wrap:wrap;' }, pills) : null; // ── Sammelversand: Lieferadresse ─────────────────────────────────────── const liefer = (o.shipping_type !== 'einzeln') ? lieferAdresse(o) : null; - const lieferBox = liefer ? h('div', { style: 'padding:11px 13px;background:var(--background-subdued,#f6f8fb);border:1px solid var(--border-normal);border-radius:8px;font-size:14px;line-height:1.55;' }, [ - h('div', { style: 'display:flex;align-items:center;gap:5px;font-weight:500;color:var(--foreground-subdued);font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;margin-bottom:3px;' }, [icon('local_shipping'), 'Versand an · ' + liefer.quelle]), + const lieferBox = liefer ? h('div', { style: 'padding:11px 13px;background:#eef2f8;border:1px solid #b4c0d2;border-radius:8px;font-size:14px;line-height:1.55;' }, [ + h('div', { style: 'display:flex;align-items:center;gap:5px;font-weight:500;color:#566070;font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;margin-bottom:3px;' }, [icon('local_shipping'), 'Versand an · ' + liefer.quelle]), ...liefer.zeilen.map((z) => h('div', {}, z)), ]) : null; // ── Fußzeile: Nummer · Zahlung · Versandtag · Link ───────────────────── const sub = [ h('span', { style: 'font-variant-numeric:tabular-nums;' }, '#' + o.order_number), - h('span', { style: `color:${bezahlt ? 'var(--success,#2e7d32)' : '#8a6d00'};font-weight:500;` }, bezahlt ? 'bezahlt' : (o.payment_status === 'storniert' ? 'storniert' : 'offen')), + h('span', { style: `color:${bezahlt ? '#1b6b2e' : '#8a6d00'};font-weight:500;` }, bezahlt ? 'bezahlt' : (o.payment_status === 'storniert' ? 'storniert' : 'offen')), (Number(o.count_ausland) > 0) ? h('span', {}, `${o.count_inland ?? 0} DE · ${o.count_ausland} Ausland`) : null, o.shipping_day ? h('span', {}, 'Versandtag ' + o.shipping_day.charAt(0).toUpperCase() + o.shipping_day.slice(1)) : null, h('a', { href: `/admin/content/orders/${o.id}`, target: '_blank', rel: 'noopener', style: 'display:inline-flex;align-items:center;gap:3px;color:#1E50A5;text-decoration:none;font-weight:500;' }, [icon('open_in_new'), 'Auftrag öffnen']), ].filter(Boolean); - const subline = h('div', { style: 'display:flex;align-items:center;gap:12px;flex-wrap:wrap;font-size:13px;color:var(--foreground-subdued);' }, - sub.reduce((acc, el, i) => (i === 0 ? [el] : acc.concat(h('span', { style: 'color:var(--border-normal);', 'aria-hidden': 'true' }, '·'), el)), [])); + const subline = h('div', { style: 'display:flex;align-items:center;gap:12px;flex-wrap:wrap;font-size:13px;color:#566070;' }, + sub.reduce((acc, el, i) => (i === 0 ? [el] : acc.concat(h('span', { style: 'color:#b4c0d2;', 'aria-hidden': 'true' }, '·'), el)), [])); // ── BODY ─────────────────────────────────────────────────────────────── const body = h('div', { style: 'padding:14px 16px;display:flex;flex-direction:column;gap:14px;' }, [ specs, druckStrip, pillRow, lieferBox, @@ -1499,7 +1499,7 @@ const Board = defineComponent({ weiteresOffen.value[o.id] ? weiteresPanel(o) : null, subline, ].filter(Boolean)); - return h('div', { key: 'o' + o.id, style: 'border:1px solid var(--border-normal);border-radius:12px;overflow:hidden;background:var(--background-page,#fff);margin-bottom:14px;' }, [kopf, body]); + return h('div', { key: 'o' + o.id, style: 'border:1px solid #b4c0d2;border-radius:12px;overflow:hidden;background:#ffffff;margin-bottom:14px;' }, [kopf, body]); } function requestCard(req) { const istMuster = req.type === 'muster'; @@ -1516,31 +1516,31 @@ const Board = defineComponent({ ['neu', 'in_bearbeitung', 'beantwortet', 'abgelehnt'].map((s) => h('option', { value: s, selected: req.status === s }, s))), ]); const eck = [metaItem(req.product || 'Produkt?'), req.quantity ? metaItem(`Menge ${req.quantity}`) : null].filter(Boolean); - const metaRow = h('div', { style: 'display:flex;gap:11px;align-items:center;flex-wrap:wrap;margin:12px 0;padding:11px 0;border-top:1px solid var(--border-subdued);border-bottom:1px solid var(--border-subdued);' }, - eck.reduce((acc, el, i) => (i === 0 ? [el] : acc.concat(h('span', { style: 'color:var(--border-normal);', 'aria-hidden': 'true' }, '·'), el)), [])); - const nachricht = req.message ? h('div', { style: 'margin:0 0 12px;padding:12px 14px;background:var(--background-subdued,#f1f4f9);border-radius:10px;font-size:14px;line-height:1.6;white-space:pre-wrap;color:var(--foreground-normal);' }, req.message) : null; + const metaRow = h('div', { style: 'display:flex;gap:11px;align-items:center;flex-wrap:wrap;margin:12px 0;padding:11px 0;border-top:1px solid #d2dae6;border-bottom:1px solid #d2dae6;' }, + eck.reduce((acc, el, i) => (i === 0 ? [el] : acc.concat(h('span', { style: 'color:#b4c0d2;', 'aria-hidden': 'true' }, '·'), el)), [])); + const nachricht = req.message ? h('div', { style: 'margin:0 0 12px;padding:12px 14px;background:#eef2f8;border-radius:10px;font-size:14px;line-height:1.6;white-space:pre-wrap;color:#1b2430;' }, req.message) : null; const aktionen = h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;' }, [ // Muster (Druckprodukt) → manueller Druck; individuelles Angebot → kein Druck. istMuster ? btn('In manuellen Druck', () => musterUebernehmen(req), 'primary', 'edit_note') : null, btn('Details', () => openReqInfo(req), 'default', 'person'), ]); - return h('div', { key: 'r' + req.id, style: 'border:1px solid var(--border-normal);border-radius:12px;background:var(--background-page,#fff);padding:16px 18px;margin-bottom:14px;' }, [kopf, metaRow, nachricht, aktionen]); + return h('div', { key: 'r' + req.id, style: 'border:1px solid #b4c0d2;border-radius:12px;background:#ffffff;padding:16px 18px;margin-bottom:14px;' }, [kopf, metaRow, nachricht, aktionen]); } // Charge-Karte: fasst API-Aufträge (Kunde+Typ+Versandtag+Eingangstag) zusammen. function chargeCard(c, opts) { const auf = expandedCharges.value.has(c.key); - let faelligFarbe = 'var(--background-subdued)'; + let faelligFarbe = '#eef2f8'; if (c.faellig) { const tage = Math.ceil((c.faellig.getTime() - Date.now()) / 864e5); - faelligFarbe = tage < 0 ? 'var(--danger-25,rgba(198,40,40,.15))' - : tage <= 7 ? 'var(--warning-25,rgba(230,160,0,.18))' : 'var(--success-25,rgba(46,125,50,.12))'; + faelligFarbe = tage < 0 ? '#fbe3e0' + : tage <= 7 ? '#fbeccb' : '#dff2e2'; } const kopf = h('div', { style: 'display:flex;align-items:center;gap:10px;flex-wrap:wrap;' }, [ h('input', { type: 'checkbox', checked: chargeGewaehlt(c), onChange: () => toggleCharge(c), title: 'Ganze Charge auswählen', style: 'width:16px;height:16px;cursor:pointer;flex-shrink:0;' }), h('button', { type: 'button', onClick: () => toggleExpand(c.key), - style: 'cursor:pointer;border:none;background:transparent;color:var(--foreground-subdued);display:inline-flex;align-items:center;', title: 'Aufklappen' }, icon(auf ? 'expand_more' : 'chevron_right')), + style: 'cursor:pointer;border:none;background:transparent;color:#566070;display:inline-flex;align-items:center;', title: 'Aufklappen' }, icon(auf ? 'expand_more' : 'chevron_right')), h('div', { style: 'display:flex;align-items:center;gap:7px;font-weight:500;font-size:16px;' }, [icon('inbox'), `${c.kundeName} · ${c.produkt}`]), chip(`${c.orders.length} Aufträge`), c.versandtag ? chip('Versandtag ' + c.versandtag.charAt(0).toUpperCase() + c.versandtag.slice(1)) : null, @@ -1560,7 +1560,7 @@ const Board = defineComponent({ ]); const body = auf ? h('div', { style: 'margin-top:12px;display:flex;flex-direction:column;gap:2px;' }, c.orders.map((o) => orderCard(o, opts))) : null; const chargeNotiz = notizFeld(chargeNotizen.value[c.key], (v) => setChargeNotiz(c.key, v), 'Notiz zur Charge …'); - return h('div', { key: 'c' + c.key, style: 'border:1px solid var(--border-normal);border-radius:12px;background:var(--background-page,#fff);padding:16px 18px;margin-bottom:14px;' }, [kopf, chargeSpecs, chargeNotiz, body]); + return h('div', { key: 'c' + c.key, style: 'border:1px solid #b4c0d2;border-radius:12px;background:#ffffff;padding:16px 18px;margin-bottom:14px;' }, [kopf, chargeSpecs, chargeNotiz, body]); } // Aufträge einer Ansicht rendern: bei aktiver Suche als EINZELaufträge (damit @@ -1590,7 +1590,7 @@ const Board = defineComponent({ ]; // Große, eindeutige Auswahlknöpfe: aktiv = blau/weiß, sonst weiß mit Rahmen. const typWahl = h('div', {}, [ - h('div', { style: 'font-size:13px;font-weight:700;color:var(--foreground-normal);margin-bottom:8px;' }, '1. Was möchten Sie?'), + h('div', { style: 'font-size:13px;font-weight:700;color:#1b2430;margin-bottom:8px;' }, '1. Was möchten Sie?'), h('div', { style: 'display:flex;gap:10px;flex-wrap:wrap;' }, TYPEN.map((t) => { const aktiv = sucheTyp.value === t.key; return h('button', { type: 'button', onClick: () => { sucheTyp.value = t.key; }, @@ -1601,7 +1601,7 @@ const Board = defineComponent({ ]); // Großes, unverkennbar weißes Suchfeld. const feld = h('div', { style: 'margin-top:18px;' }, [ - h('div', { style: 'font-size:13px;font-weight:700;color:var(--foreground-normal);margin-bottom:8px;' }, '2. Empfänger suchen'), + h('div', { style: 'font-size:13px;font-weight:700;color:#1b2430;margin-bottom:8px;' }, '2. Empfänger suchen'), h('input', { type: 'search', placeholder: 'Name, Straße, Ort oder Auftragsnummer eingeben …', style: 'width:100%;box-sizing:border-box;background:#fff;color:#111;border:2px solid #cdd6e2;border-radius:10px;' + 'font:inherit;font-size:22px;padding:16px 20px;outline:none;box-shadow:0 1px 3px rgba(0,0,0,.08);', @@ -1628,10 +1628,10 @@ const Board = defineComponent({ return h('div', { key: `s${o.id}-${e.nr}`, style: CARD + 'margin-bottom:8px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;' }, [ h('div', { style: 'min-width:0;' }, [ // Vollständige Anschrift zuerst (erste Zeile = Name, hervorgehoben). - ...adrLines.map((z, i) => h('div', { style: i === 0 ? 'font-weight:700;font-size:16px;' : 'font-size:14px;color:var(--foreground-normal);' }, z)), + ...adrLines.map((z, i) => h('div', { style: i === 0 ? 'font-weight:700;font-size:16px;' : 'font-size:14px;color:#1b2430;' }, z)), // Darunter die Auftragsnummer (+ Position bei mehreren Empfängern). h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;margin-top:5px;align-items:center;' }, [ - h('span', { style: 'font-size:13px;color:var(--foreground-subdued);' }, `Auftrag #${o.order_number}`), + h('span', { style: 'font-size:13px;color:#566070;' }, `Auftrag #${o.order_number}`), gesamt > 1 ? chip(`Nr. ${e.nr} von ${gesamt}`) : null, ]), ]), @@ -1661,7 +1661,7 @@ const Board = defineComponent({ if (!baum.length) return [leiste, subdued('Keine offenen Übermittlungen.')]; - const pfeil = (offen) => h('span', { style: 'display:inline-block;width:14px;font-size:12px;color:var(--foreground-subdued);' }, offen ? '▾' : '▸'); + const pfeil = (offen) => h('span', { style: 'display:inline-block;width:14px;font-size:12px;color:#566070;' }, offen ? '▾' : '▸'); const gruppenHaken = (subs) => h('input', { type: 'checkbox', checked: batchGruppeGewaehlt(subs), onClick: (e) => { e.stopPropagation(); batchGruppeToggle(subs); }, style: 'width:16px;height:16px;flex-shrink:0;' }); const zeile = (s) => { @@ -1677,7 +1677,7 @@ const Board = defineComponent({ ]), h('div', { style: 'display:flex;gap:8px;align-items:center;flex-wrap:wrap;' }, [ chip(istText ? '✍ Text' : '📄 Druck-PDF'), - s.versendet ? chip('✓ versendet', 'var(--success-25,rgba(46,125,50,.15))') : null, + s.versendet ? chip('✓ versendet', '#dff2e2') : null, istText ? btn('✍ Schreibvorlage', () => batchSchreibvorlage(s)) : null, ]), ]); @@ -1720,18 +1720,18 @@ const Board = defineComponent({ bestandMsg.value = `${row.bezeichnung}: ${delta >= 0 ? '+' : ''}${delta} → ${neu} ${row.einheit || ''}`; setTimeout(() => { if (bestandMsg.value.startsWith(row.bezeichnung)) bestandMsg.value = ''; }, 3000); } - const klLabel = (t) => h('span', { style: 'font-size:11px;color:var(--foreground-subdued);' }, t); + const klLabel = (t) => h('span', { style: 'font-size:11px;color:#566070;' }, t); function bestandZeile(b) { const unter = (Number(b.bestand) || 0) < (Number(b.mindestbestand) || 0); if (!(b.id in bestandEingabe)) bestandEingabe[b.id] = ''; - return h('div', { key: 'inv' + b.id, style: `display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:6px 8px;border-radius:8px;margin-bottom:4px;${unter ? 'background:var(--danger-25,rgba(198,40,40,.08));' : ''}` }, [ + return h('div', { key: 'inv' + b.id, style: `display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:6px 8px;border-radius:8px;margin-bottom:4px;${unter ? 'background:#fbe3e0;' : ''}` }, [ h('div', { style: 'flex:1 1 180px;min-width:150px;font-size:14px;' }, [ h('span', { style: 'font-weight:600;' }, b.bezeichnung || b.format), - unter ? h('span', { style: 'margin-left:8px;color:var(--danger,#c62828);font-weight:700;font-size:12px;' }, '• nachbestellen') : null, + unter ? h('span', { style: 'margin-left:8px;color:#c0392b;font-weight:700;font-size:12px;' }, '• nachbestellen') : null, ]), h('div', { style: 'display:flex;align-items:center;gap:4px;' }, [klLabel('Bestand'), h('input', { type: 'number', value: b.bestand, style: 'width:84px;' + S_INPUT, onChange: (e) => bestandPatch(b, { bestand: Math.round(Number(e.target.value) || 0) }) }), - h('span', { style: 'font-size:12px;color:var(--foreground-subdued);' }, b.einheit || '')]), + h('span', { style: 'font-size:12px;color:#566070;' }, b.einheit || '')]), h('div', { style: 'display:flex;align-items:center;gap:4px;' }, [klLabel('Mindest'), h('input', { type: 'number', value: b.mindestbestand, style: 'width:70px;' + S_INPUT, onChange: (e) => bestandPatch(b, { mindestbestand: Math.round(Number(e.target.value) || 0) }) })]), h('div', { style: 'display:flex;align-items:center;gap:4px;' }, [ @@ -1750,14 +1750,14 @@ const Board = defineComponent({ const items = rows.filter((b) => b.kategorie === k); if (!items.length) return null; return h('div', { style: 'margin-bottom:8px;' }, [ - h('div', { style: 'font-size:12px;font-weight:700;color:var(--foreground-subdued);text-transform:uppercase;letter-spacing:.03em;margin:6px 0 2px;' }, kl), + h('div', { style: 'font-size:12px;font-weight:700;color:#566070;text-transform:uppercase;letter-spacing:.03em;margin:6px 0 2px;' }, kl), ...items.map(bestandZeile), ]); }); return h('div', { key: 'st' + s.id, style: CARD + 'margin-bottom:16px;' }, [ h('div', { style: 'display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;flex-wrap:wrap;gap:8px;' }, [ h('div', { style: 'display:flex;align-items:center;gap:7px;font-weight:500;font-size:16px;' }, [icon('store'), s.name]), - unter ? chip(`⚠ ${unter}× nachbestellen`, 'var(--danger-25,rgba(198,40,40,.15))') : chip('✓ Bestand ok', 'var(--success-25,rgba(46,125,50,.15))'), + unter ? chip(`⚠ ${unter}× nachbestellen`, '#fbe3e0') : chip('✓ Bestand ok', '#dff2e2'), ]), rows.length ? h('div', {}, katBloecke) : subdued('Keine Materialzeilen an diesem Standort.'), ]); @@ -1797,7 +1797,7 @@ const Board = defineComponent({ h('div', { style: 'display:flex;align-items:center;gap:8px;flex-wrap:wrap;' }, [ h('span', { style: `font-weight:700;font-size:14px;color:${ACCENT};` }, fg.label), chip(`${fg.jobs.length} Job(s)`), - laeuft ? chip('▶ liegt ein – wird gedruckt', 'var(--success-25,rgba(46,125,50,.15))') + laeuft ? chip('▶ liegt ein – wird gedruckt', '#dff2e2') : (aktiv ? chip('⏸ wartet (anderes Format liegt ein)') : null), ]), laeuft @@ -1845,10 +1845,10 @@ const Board = defineComponent({ return h('div', { onClick: (e) => { if (e.target === e.currentTarget) close(); }, style: 'position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1000;display:flex;align-items:flex-start;justify-content:center;padding:5vh 16px;overflow:auto;', - }, [h('div', { style: `background:var(--background-page,#fff);border:1px solid var(--border-subdued);border-radius:12px;width:${breite || '620px'};max-width:100%;box-shadow:0 20px 60px rgba(0,0,0,.35);` }, inhalt)]); + }, [h('div', { style: `background:#ffffff;border:1px solid #d2dae6;border-radius:12px;width:${breite || '620px'};max-width:100%;box-shadow:0 20px 60px rgba(0,0,0,.35);` }, inhalt)]); } function modalKopf(titel, close) { - return h('div', { style: 'display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid var(--border-subdued);' }, [ + return h('div', { style: 'display:flex;justify-content:space-between;align-items:center;padding:16px 20px;border-bottom:1px solid #d2dae6;' }, [ h('div', { style: 'font-weight:700;font-size:16px;' }, titel), btn('✕', close), ]); @@ -1856,9 +1856,9 @@ const Board = defineComponent({ function feldGrid(sec, secKey) { return h('div', { style: 'display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:12px 0;' }, PARAM_FELDER.map(([k, lbl]) => h('div', { style: S_FELD + 'display:flex;flex-direction:column;' }, [ - h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--foreground-subdued);margin-bottom:2px;' }, lbl), + h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:#566070;margin-bottom:2px;' }, lbl), h('input', { type: 'number', step: '0.01', value: sec[k], - style: 'border:none;background:transparent;color:var(--foreground-normal);font:inherit;font-size:15px;font-weight:600;width:100%;padding:0;outline:none;', + style: 'border:none;background:transparent;color:#1b2430;font:inherit;font-size:15px;font-weight:600;width:100%;padding:0;outline:none;', onInput: (e) => { druck[secKey][k] = parseFloat(e.target.value) || 0; } }), ]))); } @@ -1871,20 +1871,20 @@ const Board = defineComponent({ h('input', { type: 'checkbox', checked: sec.enabled, onChange: (e) => { druck[secKey].enabled = e.target.checked; }, style: 'width:16px;height:16px;' }), `${ikon} ${titel}`, ]), - sec.done ? chip('✓ bereits gedruckt', 'var(--success-25,rgba(46,125,50,.15))') : null, + sec.done ? chip('✓ bereits gedruckt', '#dff2e2') : null, ]), h('select', { style: S_SELECT + 'width:100%;margin-bottom:6px;', value: sec.tplId, onChange: (e) => druckTplWechsel(secKey, e.target.value) }, opts.map((t) => h('option', { value: t.id, selected: String(sec.tplId) === String(t.id) }, t.name))), feldGrid(sec, secKey), h('div', { style: S_FELD + 'display:flex;flex-direction:column;gap:4px;' }, [ - h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--foreground-subdued);' }, 'Zu druckende Nummern'), + h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:#566070;' }, 'Zu druckende Nummern'), druck.intN > 0 ? h('div', { style: 'display:flex;gap:6px;flex-wrap:wrap;margin-bottom:6px;' }, [ btn(`Alle (${druck.deN + druck.intN})`, () => { druck[secKey].numbers = `1-${Math.max(1, druck.deN + druck.intN)}`; }), druck.deN > 0 ? btn(`🇩🇪 nur Deutschland (${druck.deN})`, () => { druck[secKey].numbers = druck.deNums; }) : null, btn(`🌍 nur Welt (${druck.intN})`, () => { druck[secKey].numbers = druck.intNums; }), ]) : null, h('input', { value: sec.numbers, placeholder: 'z. B. 1,4,8 oder 1-9 oder 1-3,5,8', - style: 'border:none;background:transparent;color:var(--foreground-normal);font:inherit;font-size:14px;width:100%;padding:0;outline:none;', + style: 'border:none;background:transparent;color:#1b2430;font:inherit;font-size:14px;width:100%;padding:0;outline:none;', onInput: (e) => { druck[secKey].numbers = e.target.value; } }), ]), ]); @@ -1894,7 +1894,7 @@ const Board = defineComponent({ const busy = druck.machine != null && maschineBusy(druck.machine); const body = h('div', { style: 'padding:18px 20px;' }, [ h('div', { style: 'display:flex;flex-direction:column;gap:4px;margin-bottom:14px;' }, [ - h('label', { style: 'font-size:12px;color:var(--foreground-subdued);' }, 'Maschine'), + h('label', { style: 'font-size:12px;color:#566070;' }, 'Maschine'), aktiveMaschinen.value.length ? h('select', { style: S_SELECT + 'width:100%;', value: druck.machine, onChange: (e) => { druck.machine = e.target.value; if (maschineBusy(e.target.value)) druck.mode = 'queue'; } }, aktiveMaschinen.value.map((m) => h('option', { value: m.id, selected: String(druck.machine) === String(m.id) }, `${m.name}${maschineBusy(m.id) ? ' (druckt)' : ''}`))) @@ -1917,10 +1917,10 @@ const Board = defineComponent({ ], (k) => { druck.mode = k; }), busy ? subdued('Maschine druckt gerade → nur Warteschlange.', 'margin-top:6px;') : null, ]), - druck.err ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;margin-top:8px;' }, druck.err) : null, + druck.err ? h('div', { style: 'color:#c0392b;font-size:13px;margin-top:8px;' }, druck.err) : null, druck.msg ? subdued(druck.msg, 'margin-top:8px;') : null, ]); - const foot = h('div', { style: 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid var(--border-subdued);' }, [ + const foot = h('div', { style: 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid #d2dae6;' }, [ btn('Abbrechen', () => { druck.open = false; }), btn('In Produktion geben', submitDruck, 'primary'), ]); @@ -1940,12 +1940,12 @@ const Board = defineComponent({ g.aktiv ? h('div', {}, [ h('div', { style: 'display:grid;grid-template-columns:1fr 1fr;gap:10px;' }, [ h('div', {}, [ - h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Template'), + h('label', { style: 'font-size:11px;color:#566070;' }, 'Template'), h('select', { style: S_SELECT + 'width:100%;', value: g.template, onChange: (e) => bulkTplWechsel(g, e.target.value) }, tplOpts.length ? tplOpts.map((t) => h('option', { value: t.id, selected: String(g.template) === String(t.id) }, t.name)) : [h('option', { value: '' }, 'kein Template')]), ]), h('div', {}, [ - h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Maschine'), + h('label', { style: 'font-size:11px;color:#566070;' }, 'Maschine'), h('select', { style: S_SELECT + 'width:100%;', value: g.machine, onChange: (e) => { g.machine = e.target.value; } }, aktiveMaschinen.value.length ? aktiveMaschinen.value.map((mm) => h('option', { value: mm.id, selected: String(g.machine) === String(mm.id) }, mm.name)) : [h('option', { value: '' }, 'keine Maschine')]), ]), @@ -1953,7 +1953,7 @@ const Board = defineComponent({ // Maße/Position wie beim normalen Druck editierbar (übersteuert das Template). h('div', { style: 'display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin-top:10px;' }, PARAM_FELDER.map(([k, lbl]) => h('div', {}, [ - h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--foreground-subdued);' }, lbl), + h('label', { style: 'font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:#566070;' }, lbl), h('input', { type: 'number', step: '0.01', value: g[k], style: S_INPUT + 'width:100%;', onInput: (e) => { g[k] = e.target.value; } }), ]))), @@ -1969,10 +1969,10 @@ const Board = defineComponent({ { key: 'queue', label: '⏳ Warteschlange' }, ], (k) => { bulk.mode = k; }), ]), - bulk.err ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;margin-top:8px;' }, bulk.err) : null, + bulk.err ? h('div', { style: 'color:#c0392b;font-size:13px;margin-top:8px;' }, bulk.err) : null, bulk.msg ? subdued(bulk.msg, 'margin-top:8px;') : null, ]); - const foot = h('div', { style: 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid var(--border-subdued);' }, [ + const foot = h('div', { style: 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid #d2dae6;' }, [ btn('Abbrechen', () => { bulk.open = false; }), btn('In Produktion geben', submitBulk, 'primary'), ]); @@ -1985,7 +1985,7 @@ const Board = defineComponent({ const body = h('div', { style: 'padding:18px 20px;display:flex;flex-direction:column;gap:12px;' }, [ // Vorlage wählen (benannte Mustertexte + Du/Sie). Platzhalter werden gefüllt. h('div', { style: 'display:flex;gap:10px;align-items:center;flex-wrap:wrap;' }, [ - h('label', { style: 'font-size:12px;color:var(--foreground-subdued);font-weight:600;' }, 'Mustertext:'), + h('label', { style: 'font-size:12px;color:#566070;font-weight:600;' }, 'Mustertext:'), h('select', { style: S_SELECT + 'flex:1;min-width:220px;', value: String(manuell.vorlageId), onChange: (e) => musterVorlage(e.target.value) }, [ ...musterListe.value.map((m) => h('option', { value: String(m.id), selected: String(manuell.vorlageId) === String(m.id) }, m.label || `Text ${m.id}`)), h('option', { value: 'sie', selected: manuell.vorlageId === 'sie' }, 'Standard Sie-Form'), @@ -1995,7 +1995,7 @@ const Board = defineComponent({ ]), h('textarea', { style: S_INPUT + 'width:100%;min-height:200px;font-family:var(--family-monospace,monospace);', value: manuell.text, onInput: (e) => { manuell.text = e.target.value; } }), // Kuvert automatisch mit der Adresse aus der Anfrage. - h('div', { style: 'display:flex;gap:12px;align-items:center;flex-wrap:wrap;background:var(--background-subdued,#f1f4f9);border-radius:8px;padding:10px 12px;' }, [ + h('div', { style: 'display:flex;gap:12px;align-items:center;flex-wrap:wrap;background:#eef2f8;border-radius:8px;padding:10px 12px;' }, [ h('label', { style: 'display:flex;align-items:center;gap:8px;font-size:14px;cursor:pointer;font-weight:600;' }, [ h('input', { type: 'checkbox', checked: manuell.kuvert, onChange: (e) => { manuell.kuvert = e.target.checked; }, style: 'width:16px;height:16px;' }), '✉ Adresse aufs Kuvert', @@ -2006,24 +2006,24 @@ const Board = defineComponent({ manuell.kuvert ? subdued('→ ' + (musterAdresse().replace(/\n/g, ', ') || 'keine Adresse')) : null, ]), h('div', { style: 'display:grid;grid-template-columns:repeat(4,1fr);gap:8px;' }, [ - h('div', {}, [h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Schrift'), + h('div', {}, [h('label', { style: 'font-size:11px;color:#566070;' }, 'Schrift'), h('select', { style: S_SELECT + 'width:100%;', value: manuell.font, onChange: (e) => { manuell.font = e.target.value; } }, ['tilda', 'alva', 'ellie'].map((f) => h('option', { value: f, selected: manuell.font === f }, f)))]), - h('div', {}, [h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Format'), + h('div', {}, [h('label', { style: 'font-size:11px;color:#566070;' }, 'Format'), h('select', { style: S_SELECT + 'width:100%;', value: manuell.format, onChange: (e) => { manuell.format = e.target.value; } }, [['a4', 'A4'], ['a5p', 'A5 hoch'], ['a5l', 'A5 quer'], ['dinlang_karte', 'DIN lang'], ['a6_hoch', 'A6 hoch'], ['a6_quer', 'A6 quer']].map(([v, l]) => h('option', { value: v, selected: manuell.format === v }, l)))]), - h('div', {}, [h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Template'), + h('div', {}, [h('label', { style: 'font-size:11px;color:#566070;' }, 'Template'), h('select', { style: S_SELECT + 'width:100%;', value: manuell.template, onChange: (e) => { manuell.template = e.target.value; } }, briefTpls.map((t) => h('option', { value: t.id, selected: String(manuell.template) === String(t.id) }, t.name)))]), - h('div', {}, [h('label', { style: 'font-size:11px;color:var(--foreground-subdued);' }, 'Maschine'), + h('div', {}, [h('label', { style: 'font-size:11px;color:#566070;' }, 'Maschine'), h('select', { style: S_SELECT + 'width:100%;', value: manuell.machine, onChange: (e) => { manuell.machine = e.target.value; } }, aktiveMaschinen.value.map((m) => h('option', { value: m.id, selected: String(manuell.machine) === String(m.id) }, m.name)))]), ]), segToggle(manuell.mode, [ { key: 'direct', label: '⚡ Direktdruck' }, { key: 'queue', label: '⏳ Warteschlange' }, ], (k) => { manuell.mode = k; }), - manuell.err ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;' }, manuell.err) : null, + manuell.err ? h('div', { style: 'color:#c0392b;font-size:13px;' }, manuell.err) : null, manuell.msg ? subdued(manuell.msg) : null, ]); - const foot = h('div', { style: 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid var(--border-subdued);' }, [ + const foot = h('div', { style: 'display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid #d2dae6;' }, [ btn('Abbrechen', () => { manuell.open = false; }), btn('Erzeugen & drucken', submitMuster, 'primary'), ]); @@ -2039,9 +2039,9 @@ const Board = defineComponent({ : h('div', { style: 'display:flex;flex-direction:column;gap:6px;max-height:62vh;overflow:auto;' }, empfTreffer.value.length ? empfTreffer.value.map((r) => h('div', { onClick: istOrder ? () => previewEntry(r.nr, empf.rows.findIndex((x) => x.nr === r.nr)) : undefined, - style: 'display:flex;gap:12px;align-items:baseline;border:1px solid var(--border-subdued);border-radius:8px;padding:12px 14px;' + style: 'display:flex;gap:12px;align-items:baseline;border:1px solid #d2dae6;border-radius:8px;padding:12px 14px;' + `${istOrder ? 'cursor:pointer;' : ''}` - + (istOrder && empf.selected === r.nr ? `border-color:${ACCENT};background:rgba(30,80,165,.07);` : 'background:var(--background-page);'), + + (istOrder && empf.selected === r.nr ? `border-color:${ACCENT};background:rgba(30,80,165,.07);` : 'background:#ffffff;'), }, [ h('span', { style: `min-width:40px;font-weight:700;color:${ACCENT};font-family:var(--family-monospace,monospace);` }, `#${r.nr}`), h('div', { style: 'flex:1;' }, [h('div', {}, r.zeile || '—'), r.extra ? subdued(r.extra, 'margin-top:2px;') : null]), @@ -2053,22 +2053,22 @@ const Board = defineComponent({ // quelle: Array [{url,label}] (Schriftstück, evtl. mehrseitig) oder einzelne URL (Kuvert). const bilder = Array.isArray(quelle) ? quelle : (quelle ? [{ url: quelle, label: '' }] : []); return h('div', { style: 'display:flex;flex-direction:column;gap:6px;' }, [ - h('div', { style: 'font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--foreground-subdued);' }, + h('div', { style: 'font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:#566070;' }, titel + (bilder.length > 1 ? ` · ${bilder.length} Seiten` : '')), ...(bilder.length ? bilder.map((b) => h('div', { onClick: () => { empf.lb = b.url; empf.lbTitel = titel + (b.label ? ' · ' + b.label : ''); }, - style: 'position:relative;border:1px solid var(--border-subdued);border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;min-height:150px;padding:8px;cursor:zoom-in;', + style: 'position:relative;border:1px solid #d2dae6;border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;min-height:150px;padding:8px;cursor:zoom-in;', }, [ - b.label ? h('div', { style: 'position:absolute;top:4px;left:6px;font-size:10px;color:var(--foreground-subdued);background:var(--background-page);padding:0 4px;border-radius:4px;' }, b.label) : null, + b.label ? h('div', { style: 'position:absolute;top:4px;left:6px;font-size:10px;color:#566070;background:#ffffff;padding:0 4px;border-radius:4px;' }, b.label) : null, h('img', { src: b.url, style: 'max-width:100%;max-height:30vh;object-fit:contain;' }), - ])) : [h('div', { style: 'border:1px solid var(--border-subdued);border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;min-height:150px;padding:8px;' }, subdued('—'))]), + ])) : [h('div', { style: 'border:1px solid #d2dae6;border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;min-height:150px;padding:8px;' }, subdued('—'))]), ]); }; const vorschau = istOrder ? h('div', { style: 'flex:0 0 30%;min-width:220px;display:flex;flex-direction:column;gap:14px;' }, empf.selected == null ? [subdued('Empfänger anklicken → Vorschau (Klick aufs Bild = groß).')] : empf.pLoad ? [subdued('Vorschau wird geladen …')] : [ - empf.perr ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;' }, empf.perr) : null, + empf.perr ? h('div', { style: 'color:#c0392b;font-size:13px;' }, empf.perr) : null, vorschauBox('📄 Schriftstück', empf.pl), vorschauBox('✉ Kuvert', empf.pe), ]) : null; @@ -2094,8 +2094,8 @@ const Board = defineComponent({ const istPdf = (dateien.pvType || '').includes('pdf'); const istBild = (dateien.pvType || '').startsWith('image/'); const vorschauArea = dateien.pvLaden ? subdued('Vorschau wird geladen …', 'margin-top:12px;') - : dateien.pvErr ? h('div', { style: 'color:var(--danger,#c62828);font-size:13px;margin-top:12px;' }, dateien.pvErr) - : dateien.pvUrl ? h('div', { style: 'margin-top:14px;border:1px solid var(--border-subdued);border-radius:8px;overflow:hidden;background:#fff;' }, [ + : dateien.pvErr ? h('div', { style: 'color:#c0392b;font-size:13px;margin-top:12px;' }, dateien.pvErr) + : dateien.pvUrl ? h('div', { style: 'margin-top:14px;border:1px solid #d2dae6;border-radius:8px;overflow:hidden;background:#fff;' }, [ istPdf ? h('iframe', { src: dateien.pvUrl, style: 'width:100%;height:70vh;border:none;display:block;' }) : istBild ? h('img', { src: dateien.pvUrl, style: 'display:block;max-width:100%;max-height:70vh;margin:0 auto;' }) : h('div', { style: 'padding:16px;display:flex;flex-direction:column;gap:10px;align-items:flex-start;' }, [ @@ -2133,11 +2133,11 @@ const Board = defineComponent({ type: 'button', onClick: () => { if (tab.value === 'suche' && t.key !== 'suche') { clearTimeout(sucheTimer); sucheText.value = ''; } tab.value = t.key; }, style: 'display:flex;justify-content:space-between;align-items:center;gap:10px;width:100%;text-align:left;' + 'cursor:pointer;border:none;border-radius:8px;padding:11px 13px;margin-bottom:3px;font:inherit;font-size:14px;' - + (aktiv ? `background:${ACCENT};color:#fff;font-weight:500;` : 'background:transparent;color:var(--foreground-normal);'), + + (aktiv ? `background:${ACCENT};color:#fff;font-weight:500;` : 'background:transparent;color:#1b2430;'), }, [ h('span', { style: 'display:inline-flex;align-items:center;gap:9px;min-width:0;' }, [icon(t.icon), h('span', {}, t.label)]), h('span', { style: 'font-size:12px;font-weight:500;min-width:20px;text-align:center;border-radius:999px;padding:1px 8px;' - + (aktiv ? 'background:rgba(255,255,255,.22);color:#fff;' : 'background:var(--background-subdued);color:var(--foreground-subdued);') }, String(tabCount(t.key))), + + (aktiv ? 'background:rgba(255,255,255,.22);color:#fff;' : 'background:#eef2f8;color:#566070;') }, String(tabCount(t.key))), ]); })); @@ -2168,11 +2168,11 @@ const Board = defineComponent({ h('button', { type: 'button', onClick: auswahlLeeren, style: 'cursor:pointer;border:1px solid rgba(255,255,255,.6);background:transparent;color:#fff;border-radius:7px;padding:6px 14px;font:inherit;font-size:13px;' }, 'Auswahl aufheben'), ]) : null; - const inhalt = h('div', { style: 'padding:24px 28px;min-height:100%;background:var(--background-subdued,#f1f4f9);' }, [ + const inhalt = h('div', { style: 'padding:24px 28px;min-height:100%;background:#eef2f8;' }, [ kopfzeile, bulkBar, - meldung.value ? h('div', { style: 'background:var(--success-25,rgba(46,125,50,.15));color:var(--success,#2e7d32);padding:9px 14px;border-radius:8px;margin-bottom:12px;font-size:13px;' }, meldung.value) : null, - fehler.value ? h('div', { style: 'background:var(--danger-25,rgba(198,40,40,.12));color:var(--danger,#c62828);padding:9px 14px;border-radius:8px;margin-bottom:12px;font-size:13px;' }, fehler.value) : null, + meldung.value ? h('div', { style: 'background:#dff2e2;color:#1b6b2e;padding:9px 14px;border-radius:8px;margin-bottom:12px;font-size:13px;' }, meldung.value) : null, + fehler.value ? h('div', { style: 'background:#fbe3e0;color:#c0392b;padding:9px 14px;border-radius:8px;margin-bottom:12px;font-size:13px;' }, fehler.value) : null, loading.value ? subdued('Lädt …') : h('div', { style: 'display:flex;flex-direction:column;gap:2px;' }, tabInhalt()), ]); diff --git a/extensions/directus-extension-skrift-uebersicht/dist/index.js b/extensions/directus-extension-skrift-uebersicht/dist/index.js index a2fdc72..b815841 100644 --- a/extensions/directus-extension-skrift-uebersicht/dist/index.js +++ b/extensions/directus-extension-skrift-uebersicht/dist/index.js @@ -19,12 +19,12 @@ const STATUS_LABEL = { versandfertig: 'Versandfertig', versendet: 'Versendet', storniert: 'Storniert', }; const STATUS_META = { - eingegangen: { bg: 'var(--background-subdued,#eef1f6)', fg: 'var(--foreground-subdued)', icon: 'inbox' }, - im_druck: { bg: 'rgba(30,80,165,.12)', fg: '#1E50A5', icon: 'print' }, - kuvertieren: { bg: 'rgba(106,63,208,.12)', fg: '#6a3fd0', icon: 'mail' }, - versandfertig: { bg: 'rgba(230,160,0,.16)', fg: '#8a6d00', icon: 'inventory_2' }, - versendet: { bg: 'rgba(46,125,50,.14)', fg: 'var(--success,#2e7d32)', icon: 'local_shipping' }, - storniert: { bg: 'rgba(198,40,40,.12)', fg: 'var(--danger,#c62828)', icon: 'cancel' }, + eingegangen: { bg: '#eef2f8', fg: '#566070', bd: '#d2dae6', icon: 'inbox' }, + im_druck: { bg: '#e3ecfa', fg: '#1E50A5', bd: '#bcd0ef', icon: 'print' }, + kuvertieren: { bg: '#ece4fb', fg: '#5b32b8', bd: '#d3c4f2', icon: 'mail' }, + versandfertig: { bg: '#fbeccb', fg: '#8a5a00', bd: '#f0d79a', icon: 'inventory_2' }, + versendet: { bg: '#e3f4e6', fg: '#1b6b2e', bd: '#bfe2c6', icon: 'local_shipping' }, + storniert: { bg: '#fbe3e0', fg: '#c0392b', bd: '#f3c6bf', icon: 'cancel' }, }; const AKTIV_STATUS = ['im_druck', 'kuvertieren', 'versandfertig']; const FORMAT_LABEL = { a4: 'A4', a5p: 'A5 hoch', a5l: 'A5 quer', dinlang_karte: 'DIN lang', a6_hoch: 'A6 hoch', a6_quer: 'A6 quer', dinlang: 'DIN Lang', c6: 'C6', c4: 'C4' }; @@ -112,7 +112,7 @@ const Board = { const ent = await api.get('/items/order_entries', { params: { limit: -1, sort: ['order', 'letter_number'], filter: { order: { production_status: { _in: AKTIV_STATUS } } }, - fields: 'order,letter_number,first_name,last_name,company,city,free_text', + fields: 'order,letter_number,first_name,last_name,city,free_text', } }); const idx = {}; for (const e of (ent.data?.data || [])) { @@ -131,7 +131,7 @@ const Board = { const ent = await api.get('/items/order_entries', { params: { limit: -1, sort: ['order', 'letter_number'], filter: { order: { production_status: { _in: AKTIV_STATUS } } }, - fields: 'order,letter_number,salutation,first_name,last_name,company,street,house_no,zip,city,country,free_text', + fields: 'order,letter_number,salutation,first_name,last_name,street,house_no,zip,city,country,free_text', } }); const flach = []; const cnt = {}; for (const e of (ent.data?.data || [])) { @@ -234,32 +234,32 @@ const Board = { // ── Render-Helfer ───────────────────────────────────────────────────────── const statusPillCtrl = (k0, onCh) => { const k = k0 || 'eingegangen'; const m = STATUS_META[k] || STATUS_META.eingegangen; - return h('div', { style: `display:inline-flex;align-items:center;gap:5px;border-radius:8px;padding:5px 8px 5px 10px;background:${m.bg};color:${m.fg};font-weight:500;font-size:13px;` }, [ + return h('div', { style: `display:inline-flex;align-items:center;gap:5px;border-radius:8px;padding:5px 8px 5px 10px;background:${m.bg};color:${m.fg};border:1px solid ${m.bd || '#d2dae6'};font-weight:600;font-size:13px;` }, [ icon(m.icon), h('select', { style: `border:none;background:transparent;color:${m.fg};font:inherit;font-size:13px;font-weight:500;cursor:pointer;`, value: k, onChange: (e) => onCh(e.target.value) }, Object.entries(STATUS_LABEL).map(([kk, v]) => h('option', { value: kk, selected: k === kk }, v))), ]); }; const statusPill = (o) => statusPillCtrl(o.production_status, (v) => setStatus(o, v)); - const druckBadge = (ok, text) => h('span', { style: `display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:500;padding:2px 8px;border-radius:999px;background:${ok ? 'rgba(46,125,50,.14)' : 'rgba(198,40,40,.12)'};color:${ok ? 'var(--success,#2e7d32)' : 'var(--danger,#c62828)'};` }, [icon(ok ? 'check' : 'close'), text]); - const th = (t, extra) => h('th', { style: `text-align:left;font-size:12px;font-weight:500;color:var(--foreground-subdued);text-transform:uppercase;letter-spacing:.03em;padding:10px 12px;border-bottom:1px solid var(--border-normal);white-space:nowrap;${extra || ''}` }, t); - const td = (kids, extra) => h('td', { style: `padding:11px 12px;border-bottom:1px solid var(--border-subdued);font-size:14px;vertical-align:top;${extra || ''}` }, kids); + const druckBadge = (ok, text) => h('span', { style: `display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:500;padding:2px 8px;border-radius:999px;background:${ok ? 'rgba(46,125,50,.14)' : 'rgba(198,40,40,.12)'};color:${ok ? '#1b6b2e' : '#c0392b'};` }, [icon(ok ? 'check' : 'close'), text]); + const th = (t, extra) => h('th', { style: `text-align:left;font-size:12px;font-weight:500;color:#566070;text-transform:uppercase;letter-spacing:.03em;padding:10px 12px;border-bottom:1px solid #b4c0d2;white-space:nowrap;${extra || ''}` }, t); + const td = (kids, extra) => h('td', { style: `padding:11px 12px;border-bottom:1px solid #d2dae6;font-size:14px;vertical-align:top;${extra || ''}` }, kids); function aufgabe(o) { const einzeln = o.shipping_type === 'einzeln'; switch (o.production_status) { - case 'eingegangen': return { t: 'Wartet auf Druck', c: 'var(--foreground-subdued)', i: 'hourglass_empty' }; + case 'eingegangen': return { t: 'Wartet auf Druck', c: '#566070', i: 'hourglass_empty' }; case 'im_druck': return { t: 'Im Druck', c: '#1E50A5', i: 'print' }; case 'kuvertieren': return { t: (o.needs_envelope ? 'Kuvertieren' : 'Vorbereiten') + ' + frankieren', c: '#6a3fd0', i: 'mail' }; case 'versandfertig': return { t: einzeln ? 'Einzelversand' : 'Sammelversand', c: '#8a6d00', i: 'local_shipping' }; - default: return { t: STATUS_LABEL[o.production_status] || '', c: 'var(--foreground-subdued)', i: 'info' }; + default: return { t: STATUS_LABEL[o.production_status] || '', c: '#566070', i: 'info' }; } } // Nur-Lese-Anzeige für Mitarbeiter: Versandart darf hier nicht geändert werden. function versandToggle(o) { const einzeln = o.shipping_type === 'einzeln'; return h('span', { title: 'Versandart (nur Ansicht)', - style: 'border:1px solid var(--border-subdued);background:var(--background-subdued,#f2f4f8);border-radius:999px;padding:4px 11px;font-size:12.5px;font-weight:500;display:inline-flex;align-items:center;gap:5px;color:var(--foreground-normal);' }, + style: 'border:1px solid #d2dae6;background:#eef2f8;border-radius:999px;padding:4px 11px;font-size:12.5px;font-weight:500;display:inline-flex;align-items:center;gap:5px;color:#1b2430;' }, [icon(einzeln ? 'person' : 'groups'), einzeln ? 'Einzeln' : 'Sammel']); } // Nur-Lese-Anzeige für Mitarbeiter: Versanddatum darf hier nicht geändert werden. @@ -267,16 +267,16 @@ const Board = { const faellig = o.versanddatum && o.versanddatum <= new Date().toISOString().slice(0, 10); const txt = o.versanddatum ? o.versanddatum : 'schnellstmöglich'; return h('span', { title: 'Versanddatum (nur Ansicht)', - style: 'display:inline-flex;align-items:center;gap:5px;font-size:13px;color:' + (faellig ? 'var(--danger,#c62828)' : 'var(--foreground-normal)') + ';font-weight:' + (faellig ? '600' : '400') + ';' }, + style: 'display:inline-flex;align-items:center;gap:5px;font-size:13px;color:' + (faellig ? '#c0392b' : '#1b2430') + ';font-weight:' + (faellig ? '600' : '400') + ';' }, [icon('event'), txt]); } // Ein Ablauf-Schritt: nicht nötig (✗, grau) · erledigt (✓, grün) · offen (amber). function stepPill(labelTxt, benoetigt, erledigt) { - let bg, fg, ic, zustand; - if (!benoetigt) { bg = 'var(--background-subdued,#eef1f6)'; fg = 'var(--foreground-subdued)'; ic = 'close'; zustand = 'nicht nötig'; } - else if (erledigt) { bg = 'rgba(46,125,50,.14)'; fg = 'var(--success,#2e7d32)'; ic = 'check'; zustand = 'erledigt'; } - else { bg = 'rgba(230,160,0,.2)'; fg = '#8a6d00'; ic = 'radio_button_unchecked'; zustand = 'offen'; } - return h('span', { title: `${labelTxt}: ${zustand}`, style: `display:inline-flex;align-items:center;gap:4px;font-size:11.5px;font-weight:500;padding:3px 8px;border-radius:999px;background:${bg};color:${fg};white-space:nowrap;` }, [icon(ic), labelTxt]); + let bg, fg, bd, ic, zustand; + if (!benoetigt) { bg = '#eef2f8'; fg = '#566070'; bd = '#d2dae6'; ic = 'close'; zustand = 'nicht nötig'; } + else if (erledigt) { bg = '#e3f4e6'; fg = '#1b6b2e'; bd = '#bfe2c6'; ic = 'check'; zustand = 'erledigt'; } + else { bg = '#fbeccb'; fg = '#8a5a00'; bd = '#f0d79a'; ic = 'radio_button_unchecked'; zustand = 'offen'; } + return h('span', { title: `${labelTxt}: ${zustand}`, style: `display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;padding:3px 9px;border-radius:999px;background:${bg};color:${fg};border:1px solid ${bd};white-space:nowrap;` }, [icon(ic), labelTxt]); } function ablaufStrip(o) { const fertig = ['versandfertig', 'versendet'].includes(o.production_status); @@ -294,14 +294,14 @@ const Board = { function zeile(o, indent) { const e = entriesByOrder.value[String(o.id)]; return h('tr', { key: 'o' + o.id }, [ - td(h('div', { style: `line-height:1.45;${indent ? 'padding-left:18px;border-left:2px solid var(--border-subdued);' : ''}` }, [ + td(h('div', { style: `line-height:1.45;${indent ? 'padding-left:18px;border-left:2px solid #d2dae6;' : ''}` }, [ h('div', { style: 'font-weight:500;' }, empfKurz(e?.erster) || '—'), - (e && e.anzahl > 1) ? h('div', { style: 'font-size:12.5px;color:var(--foreground-subdued);' }, '… ' + empfKurz(e.letzter)) : null, + (e && e.anzahl > 1) ? h('div', { style: 'font-size:12.5px;color:#566070;' }, '… ' + empfKurz(e.letzter)) : null, ])), td(h('div', { style: 'line-height:1.4;font-size:13px;' }, [ o.order_name ? h('div', { style: 'font-weight:500;color:#1E50A5;' }, o.order_name) : null, h('div', {}, kundeName(o) || `#${o.order_number}`), - h('div', { style: 'color:var(--foreground-subdued);' }, `#${o.order_number} · ${o.entries_count || 0} Empf.`), + h('div', { style: 'color:#566070;' }, `#${o.order_number} · ${o.entries_count || 0} Empf.`), ])), td(h('span', {}, o.format?.name || FORMAT_LABEL[o.format?.key] || o.format?.key || '—')), td(ablaufStrip(o)), @@ -344,17 +344,17 @@ const Board = { return h('tr', { key: 'c' + c.key }, [ td(h('div', { style: 'line-height:1.45;' }, [ h('div', { style: 'font-weight:500;' }, empfKurz(first?.erster) || '—'), - sumEmpf > 1 ? h('div', { style: 'font-size:12.5px;color:var(--foreground-subdued);' }, '… ' + (empfKurz(last?.letzter) || '—')) : null, + sumEmpf > 1 ? h('div', { style: 'font-size:12.5px;color:#566070;' }, '… ' + (empfKurz(last?.letzter) || '—')) : null, ])), td(h('div', { style: 'line-height:1.4;font-size:13px;' }, [ h('div', { style: 'font-weight:500;display:inline-flex;align-items:center;gap:6px;cursor:pointer;', title: auf ? 'Zuklappen' : 'Teil-Aufträge zeigen', onClick: () => { expandedCharges[c.key] = !auf; } }, [icon(auf ? 'expand_more' : 'chevron_right'), icon('inbox'), c.kundeName]), - h('div', { style: 'color:var(--foreground-subdued);' }, `${c.produkt} · ${c.orders.length} Aufträge · ${sumEmpf} Empf.`), + h('div', { style: 'color:#566070;' }, `${c.produkt} · ${c.orders.length} Aufträge · ${sumEmpf} Empf.`), ])), td(h('span', {}, fmts.join(', ') || '—')), td(ablaufStripAgg(c.orders)), - td(h('span', { title: 'Versandart (nur Ansicht)', style: 'border:1px solid var(--border-subdued);background:var(--background-subdued,#f2f4f8);border-radius:999px;padding:4px 11px;font-size:12.5px;font-weight:500;display:inline-flex;align-items:center;gap:5px;color:var(--foreground-normal);' }, [icon(vIc), vTxt])), - td(h('span', { title: 'Versanddatum (nur Ansicht)', style: 'display:inline-flex;align-items:center;gap:5px;font-size:13px;color:' + (dFaellig ? 'var(--danger,#c62828)' : 'var(--foreground-normal)') + ';font-weight:' + (dFaellig ? '600' : '400') + ';' }, [icon('event'), dTxt])), + td(h('span', { title: 'Versandart (nur Ansicht)', style: 'border:1px solid #d2dae6;background:#eef2f8;border-radius:999px;padding:4px 11px;font-size:12.5px;font-weight:500;display:inline-flex;align-items:center;gap:5px;color:#1b2430;' }, [icon(vIc), vTxt])), + td(h('span', { title: 'Versanddatum (nur Ansicht)', style: 'display:inline-flex;align-items:center;gap:5px;font-size:13px;color:' + (dFaellig ? '#c0392b' : '#1b2430') + ';font-weight:' + (dFaellig ? '600' : '400') + ';' }, [icon('event'), dTxt])), td(statusPillCtrl(stat, (v) => setChargeStatus(c, v))), ]); } @@ -369,30 +369,30 @@ const Board = { return rows; } const kopfRow = () => h('thead', {}, h('tr', {}, [th('Empfänger (erster · letzter)'), th('Auftrag'), th('Format'), th('Ablauf'), th('Versand'), th('Versanddatum'), th('Status')])); - const tabelle = (list) => h('div', { style: 'border:1px solid var(--border-normal);border-radius:12px;overflow:auto;background:var(--background-page,#fff);' }, + const tabelle = (list) => h('div', { style: 'border:1px solid #b4c0d2;border-radius:12px;overflow:auto;background:#ffffff;' }, [h('table', { style: 'width:100%;border-collapse:collapse;' }, [kopfRow(), h('tbody', {}, gruppenZeilen(list))])]); const sektionKopf = (label, m, n) => h('div', { style: 'display:flex;align-items:center;gap:10px;margin-bottom:10px;' }, [ h('span', { style: `display:inline-flex;align-items:center;gap:6px;font-size:16px;font-weight:500;color:${m.fg};` }, [icon(m.icon), label]), - h('span', { style: 'font-size:13px;color:var(--foreground-subdued);' }, `${n} Auftrag/Aufträge`), + h('span', { style: 'font-size:13px;color:#566070;' }, `${n} Auftrag/Aufträge`), ]); function maschinenPanel() { const qf = queuedByFormat.value; const formate = Object.keys(qf); - return h('div', { style: 'border:1px solid var(--border-normal);border-radius:12px;background:var(--background-page,#fff);margin-bottom:18px;overflow:hidden;' }, [ - h('div', { style: 'display:flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:var(--foreground-subdued);padding:10px 14px;border-bottom:1px solid var(--border-subdued);background:var(--background-subdued,#f6f8fb);' }, [icon('print'), 'Maschinen · Format einlegen und starten']), + return h('div', { style: 'border:1px solid #b4c0d2;border-radius:12px;background:#ffffff;margin-bottom:18px;overflow:hidden;' }, [ + h('div', { style: 'display:flex;align-items:center;gap:6px;font-size:13px;font-weight:500;color:#566070;padding:10px 14px;border-bottom:1px solid #d2dae6;background:#eef2f8;' }, [icon('print'), 'Maschinen · Format einlegen und starten']), h('div', { style: 'padding:14px;display:flex;flex-direction:column;gap:14px;' }, aktiveMaschinen.value.length ? aktiveMaschinen.value.map((m) => h('div', { key: 'm' + m.id, style: 'display:flex;align-items:center;gap:12px;flex-wrap:wrap;' }, [ - h('div', { style: 'font-weight:500;min-width:150px;' }, [m.name, h('span', { style: 'color:var(--foreground-subdued);font-weight:400;font-size:13px;' }, m.current_format ? ` · eingelegt: ${FORMAT_LABEL[m.current_format] || m.current_format}` : ' · kein Format eingelegt')]), + h('div', { style: 'font-weight:500;min-width:150px;' }, [m.name, h('span', { style: 'color:#566070;font-weight:400;font-size:13px;' }, m.current_format ? ` · eingelegt: ${FORMAT_LABEL[m.current_format] || m.current_format}` : ' · kein Format eingelegt')]), ...(formate.length ? formate.map((f) => h('button', { type: 'button', onClick: () => formatStarten(m, f), - style: `cursor:pointer;border-radius:8px;padding:8px 14px;font:inherit;font-size:14px;font-weight:500;display:inline-flex;align-items:center;gap:6px;border:1px solid;${m.current_format === f ? 'border-color:#1E50A5;background:#1E50A5;color:#fff;' : 'border-color:var(--border-normal);background:var(--background-page,#fff);color:var(--foreground-normal);'}`, + style: `cursor:pointer;border-radius:8px;padding:8px 14px;font:inherit;font-size:14px;font-weight:500;display:inline-flex;align-items:center;gap:6px;border:1px solid;${m.current_format === f ? 'border-color:#1E50A5;background:#1E50A5;color:#fff;' : 'border-color:#b4c0d2;background:#ffffff;color:#1b2430;'}`, }, [icon('play_arrow'), `${qf[f].label} (${qf[f].n})`])) - : [h('span', { style: 'color:var(--foreground-subdued);font-size:13px;' }, 'Keine Jobs in der Warteschlange.')]), - ])) : [h('span', { style: 'color:var(--foreground-subdued);font-size:13px;' }, 'Keine aktive Maschine.')]), + : [h('span', { style: 'color:#566070;font-size:13px;' }, 'Keine Jobs in der Warteschlange.')]), + ])) : [h('span', { style: 'color:#566070;font-size:13px;' }, 'Keine aktive Maschine.')]), ]); } function uebersichtInhalt() { - if (loading.value) return h('div', { style: 'color:var(--foreground-subdued);' }, 'Lädt …'); + if (loading.value) return h('div', { style: 'color:#566070;' }, 'Lädt …'); const GRUPPEN = [['im_druck', 'Im Druck'], ['kuvertieren', 'Kuvertierung']]; const sek = []; for (const [st, label] of GRUPPEN) { @@ -407,11 +407,11 @@ const Board = { const mit = vf.filter((o) => o.versanddatum).sort((a, b) => String(a.versanddatum).localeCompare(String(b.versanddatum))); sek.push(h('div', { key: 'secvf', style: 'margin-bottom:22px;' }, [ sektionKopf('Versandfertig', STATUS_META.versandfertig, vf.length), - ohne.length ? h('div', { style: 'margin-bottom:12px;' }, [h('div', { style: 'font-size:13px;font-weight:500;color:var(--foreground-subdued);margin-bottom:6px;' }, 'Schnellstmöglich (' + ohne.length + ')'), tabelle(ohne)]) : null, - mit.length ? h('div', {}, [h('div', { style: 'font-size:13px;font-weight:500;color:var(--foreground-subdued);margin-bottom:6px;' }, 'Mit Versanddatum (' + mit.length + ')'), tabelle(mit)]) : null, + ohne.length ? h('div', { style: 'margin-bottom:12px;' }, [h('div', { style: 'font-size:13px;font-weight:500;color:#566070;margin-bottom:6px;' }, 'Schnellstmöglich (' + ohne.length + ')'), tabelle(ohne)]) : null, + mit.length ? h('div', {}, [h('div', { style: 'font-size:13px;font-weight:500;color:#566070;margin-bottom:6px;' }, 'Mit Versanddatum (' + mit.length + ')'), tabelle(mit)]) : null, ].filter(Boolean))); } - return sek.length ? h('div', {}, [maschinenPanel(), ...sek]) : h('div', {}, [maschinenPanel(), h('div', { style: 'padding:28px;text-align:center;color:var(--foreground-subdued);border:1px solid var(--border-normal);border-radius:12px;background:var(--background-page,#fff);' }, 'Keine offenen Aufträge.')]); + return sek.length ? h('div', {}, [maschinenPanel(), ...sek]) : h('div', {}, [maschinenPanel(), h('div', { style: 'padding:28px;text-align:center;color:#566070;border:1px solid #b4c0d2;border-radius:12px;background:#ffffff;' }, 'Keine offenen Aufträge.')]); } function sucheInhalt() { @@ -421,22 +421,22 @@ const Board = { h('div', { style: 'display:flex;gap:10px;flex-wrap:wrap;' }, TYPEN.map(([k, l, ic]) => { const aktiv = sucheTyp.value === k; return h('button', { type: 'button', onClick: () => { sucheTyp.value = k; }, - style: `cursor:pointer;border-radius:10px;padding:13px 20px;font:inherit;font-size:16px;font-weight:500;display:inline-flex;align-items:center;gap:8px;border:2px solid;${aktiv ? 'background:#1E50A5;color:#fff;border-color:#1E50A5;' : 'background:var(--background-page,#fff);color:var(--foreground-normal);border-color:var(--border-normal);'}` }, [icon(ic), l]); + style: `cursor:pointer;border-radius:10px;padding:13px 20px;font:inherit;font-size:16px;font-weight:500;display:inline-flex;align-items:center;gap:8px;border:2px solid;${aktiv ? 'background:#1E50A5;color:#fff;border-color:#1E50A5;' : 'background:#ffffff;color:#1b2430;border-color:#b4c0d2;'}` }, [icon(ic), l]); })), ]); const feld = h('div', { style: 'margin-top:18px;' }, [ h('div', { style: 'font-size:14px;font-weight:500;margin-bottom:8px;' }, '2. Empfänger suchen'), h('input', { type: 'search', placeholder: 'Name, Straße, Ort oder Auftragsnummer …', - style: 'width:100%;box-sizing:border-box;background:var(--background-page);color:var(--foreground-normal);border:2px solid var(--border-normal);border-radius:12px;font:inherit;font-size:22px;padding:16px 20px;outline:none;', + style: 'width:100%;box-sizing:border-box;background:#ffffff;color:#1b2430;border:2px solid #b4c0d2;border-radius:12px;font:inherit;font-size:22px;padding:16px 20px;outline:none;', onInput: (e) => sucheSetzen(e.target.value) }), ]); const rahmen = (kinder) => h('div', {}, [ - h('div', { style: 'background:var(--background-page,#fff);border:1px solid var(--border-normal);border-radius:12px;padding:20px 22px;margin-bottom:16px;' }, [typWahl, feld]), + h('div', { style: 'background:#ffffff;border:1px solid #b4c0d2;border-radius:12px;padding:20px 22px;margin-bottom:16px;' }, [typWahl, feld]), kinder, ]); - if (!sucheQuery.value.trim()) return rahmen(h('div', { style: 'color:var(--foreground-subdued);' }, 'Suchbegriff eingeben – durchsucht die offenen Aufträge.')); + if (!sucheQuery.value.trim()) return rahmen(h('div', { style: 'color:#566070;' }, 'Suchbegriff eingeben – durchsucht die offenen Aufträge.')); const treffer = sucheTreffer.value; - if (!treffer.length) return rahmen(h('div', { style: 'color:var(--foreground-subdued);' }, 'Keine Treffer.')); + if (!treffer.length) return rahmen(h('div', { style: 'color:#566070;' }, 'Keine Treffer.')); const trefferZeile = ({ e, o }) => { const gesamt = entriesByOrder.value[String(o.id)]?.anzahl || 1; const adrLines = (e.adr && e.adr.length) ? e.adr : [e.name || '—']; @@ -444,15 +444,15 @@ const Board = { const aktion = sucheTyp.value === 'objekt' ? h('a', { href: `/admin/content/orders/${o.id}`, target: '_blank', rel: 'noopener', style: 'display:inline-flex;align-items:center;gap:6px;background:#1E50A5;color:#fff;border-radius:8px;padding:9px 16px;font-size:14px;font-weight:500;text-decoration:none;' }, [icon('open_in_new'), 'Auftrag öffnen']) : (sucheTyp.value === 'umschlag' && !kannKuvert) - ? h('span', { style: 'color:var(--foreground-subdued);font-size:14px;' }, 'Kein Kuvert') + ? h('span', { style: 'color:#566070;font-size:14px;' }, 'Kein Kuvert') : h('button', { type: 'button', onClick: () => schnelldruck(o, e.nr, sucheTyp.value), style: 'cursor:pointer;display:inline-flex;align-items:center;gap:6px;background:#1E50A5;color:#fff;border:none;border-radius:8px;padding:10px 18px;font:inherit;font-size:15px;font-weight:500;' }, [icon('print'), 'In Warteschlange']); - return h('div', { key: `s${o.id}-${e.nr}`, style: 'border:1px solid var(--border-normal);border-radius:12px;background:var(--background-page,#fff);padding:14px 16px;margin-bottom:8px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;' }, [ + return h('div', { key: `s${o.id}-${e.nr}`, style: 'border:1px solid #b4c0d2;border-radius:12px;background:#ffffff;padding:14px 16px;margin-bottom:8px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;' }, [ h('div', { style: 'min-width:0;' }, [ - ...adrLines.map((z, i) => h('div', { style: i === 0 ? 'font-weight:500;font-size:16px;' : 'font-size:14px;color:var(--foreground-normal);' }, z)), - h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;margin-top:5px;align-items:center;font-size:13px;color:var(--foreground-subdued);' }, [ + ...adrLines.map((z, i) => h('div', { style: i === 0 ? 'font-weight:500;font-size:16px;' : 'font-size:14px;color:#1b2430;' }, z)), + h('div', { style: 'display:flex;gap:8px;flex-wrap:wrap;margin-top:5px;align-items:center;font-size:13px;color:#566070;' }, [ h('span', {}, `Auftrag #${o.order_number}`), - gesamt > 1 ? h('span', { style: 'background:var(--background-subdued);border-radius:999px;padding:2px 9px;' }, `Nr. ${e.nr} von ${gesamt}`) : null, + gesamt > 1 ? h('span', { style: 'background:#eef2f8;border-radius:999px;padding:2px 9px;' }, `Nr. ${e.nr} von ${gesamt}`) : null, h('span', { style: `display:inline-flex;align-items:center;gap:4px;color:${(STATUS_META[o.production_status] || STATUS_META.eingegangen).fg};` }, [icon((STATUS_META[o.production_status] || STATUS_META.eingegangen).icon), STATUS_LABEL[o.production_status] || '']), ]), ]), @@ -464,7 +464,7 @@ const Board = { const navItem = (key, label, ic) => h('button', { type: 'button', onClick: () => { clearTimeout(sucheTimer); sucheQuery.value = ''; view.value = key; if (key === 'suche') ladeSuche(); }, style: 'display:flex;align-items:center;gap:10px;width:100%;text-align:left;cursor:pointer;border:none;border-radius:8px;padding:11px 13px;margin-bottom:3px;font:inherit;font-size:14px;' - + (view.value === key ? 'background:#1E50A5;color:#fff;font-weight:500;' : 'background:transparent;color:var(--foreground-normal);'), + + (view.value === key ? 'background:#1E50A5;color:#fff;font-weight:500;' : 'background:transparent;color:#1b2430;'), }, [icon(ic), label]); return () => { @@ -474,11 +474,11 @@ const Board = { ]); const inhalt = h('div', { style: 'padding:24px 28px;' }, [ view.value === 'uebersicht' ? h('div', { style: 'display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:18px;' }, [ - h('input', { type: 'search', placeholder: 'Auftrag, Kunde, Empfänger, Format …', style: 'flex:1;min-width:240px;box-sizing:border-box;border:1px solid var(--border-normal);border-radius:10px;padding:11px 14px;font:inherit;font-size:15px;background:var(--background-page);color:var(--foreground-normal);', onInput: (e) => sucheSetzen(e.target.value) }), - h('button', { type: 'button', onClick: () => laden(), style: 'cursor:pointer;border:1px solid var(--border-normal);background:var(--background-page,#fff);border-radius:8px;padding:9px 16px;font:inherit;font-size:14px;font-weight:500;display:inline-flex;align-items:center;gap:6px;' }, [icon('refresh'), 'Aktualisieren']), + h('input', { type: 'search', placeholder: 'Auftrag, Kunde, Empfänger, Format …', style: 'flex:1;min-width:240px;box-sizing:border-box;border:1px solid #b4c0d2;border-radius:10px;padding:11px 14px;font:inherit;font-size:15px;background:#ffffff;color:#1b2430;', onInput: (e) => sucheSetzen(e.target.value) }), + h('button', { type: 'button', onClick: () => laden(), style: 'cursor:pointer;border:1px solid #b4c0d2;background:#ffffff;border-radius:8px;padding:9px 16px;font:inherit;font-size:14px;font-weight:500;display:inline-flex;align-items:center;gap:6px;' }, [icon('refresh'), 'Aktualisieren']), ]) : null, - msg.value ? h('div', { style: 'background:var(--success-25,rgba(46,125,50,.14));color:var(--success,#2e7d32);padding:10px 14px;border-radius:8px;margin-bottom:12px;font-size:14px;' }, msg.value) : null, - err.value ? h('div', { style: 'background:var(--danger-25,rgba(198,40,40,.12));color:var(--danger,#c62828);padding:10px 14px;border-radius:8px;margin-bottom:12px;font-size:14px;' }, err.value) : null, + msg.value ? h('div', { style: 'background:#dff2e2;color:#1b6b2e;padding:10px 14px;border-radius:8px;margin-bottom:12px;font-size:14px;' }, msg.value) : null, + err.value ? h('div', { style: 'background:#fbe3e0;color:#c0392b;padding:10px 14px;border-radius:8px;margin-bottom:12px;font-size:14px;' }, err.value) : null, view.value === 'suche' ? sucheInhalt() : uebersichtInhalt(), ]); return h(resolveComponent('private-view'), { title: view.value === 'suche' ? 'Suche' : 'Übersicht' }, { navigation: () => navi, default: () => inhalt });