Bestellverwaltung radikal ausgebaut: Suche, Zeitraum, Sortierung, PDF, u.v.m.

Auf ausdrücklichen Wunsch ("perfektioniere diese Seite aufs Maximum") die interne
Verwaltungsseite um alles erweitert, was ein echtes kleines Shop-Team im Alltag
braucht, aber vorher fehlte:

- Suchfeld (Bestellnummer/Name/E-Mail), Zeitraum-Filter (Heute/7/30 Tage), vier
  Sortiermodi — alle gleichzeitig mit dem bestehenden Status-Filter kombinierbar.
- CSV-Export der aktuell gefilterten Liste (für Buchhaltung/Steuer, Excel-taugliche
  UTF-8-Kodierung mit BOM).
- Tracking-Nummer direkt in der Bestellkarte editierbar (Enter oder Speichern-Knopf).
- Ein-Klick-Kopieren von E-Mail/Lieferadresse fürs Versandlabel.
- Echte PDF-Rechnung pro Bestellung per Klick (nutzt dieselbe jsPDF-Funktion wie im
  Kundenkonto, keine neue Abhängigkeit).
- Zwei neue Kennzahlen-Kacheln (Bestellungen heute/letzte 7 Tage, Ø Bestellwert) plus
  eine automatisch erscheinende Warn-Kachel für offene Bestellungen, die schon länger
  liegen (Schwelle 3 Tage) — sowohl als Kachel als auch als Warn-Chip direkt an der
  betroffenen Bestellung.
- "🆕 Neu"- und "🔁 Stammkundin"-Kennzeichnung pro Bestellung, neuer Abschnitt "Beste
  Kundinnen" (Umsatz nach wiederkehrender Kundschaft).
- Dezenter Hintergrund-Hinweis ("🔔 X neue Bestellungen"), wenn während des Arbeitens
  neue Bestellungen eingehen — unterbricht die aktuelle Ansicht/Filterung nicht.
- Neuer, deutlich premiumerer Seitenkopf (Farbverlauf-Rand, Funkeln) passend zum Rest
  der Seite.

Alle neuen Funktionen einzeln end-to-end gegen die echte lokale D1-Datenbank getestet
(Suche, Zeitraum, Sortierung, Tracking-Speichern, Kopieren, PDF-Erzeugung, Warn-/Neu-/
Stammkunden-Kennzeichnung) — keine Konsolenfehler, Screenshot-verifiziert.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
qcigano
2026-08-03 21:36:52 +02:00
co-authored by Claude Sonnet 5
parent 7f7abd4d80
commit 9a2c75ebe6
2 changed files with 474 additions and 24 deletions
+112
View File
@@ -2860,7 +2860,50 @@ a:focus-visible, button:focus-visible {
@media print { #vandiy-music-widget { display: none !important; } }
/* Interne Bestellverwaltung (/verwaltung/) — Status-Kacheln, Filterleiste, Auswertungs-Balken. */
/* Hero-Kopf: dieselbe "besondere" Formsprache wie die anderen Premium-Karten der Seite
(wanderndes Verlaufslicht + pulsierender Rand + Funkeln), passend zu einer Seite, die "alles
übertrifft" — nur dezenter/edler gehalten, weil es ein Arbeits-Dashboard ist, kein Verkaufs-
Element. */
.verwaltung-hero {
position: relative;
overflow: hidden;
margin-top: 1.2rem;
padding: 1.8rem 2rem;
border-radius: var(--radius-l);
border: 1.5px solid transparent;
background:
linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
linear-gradient(120deg, #5fd3ec, #9b7fd6, #e3b23c, #5fd3ec) border-box;
background-size: 100% 100%, 300% 100%;
animation: verwaltung-hero-shift 10s ease-in-out infinite;
}
@keyframes verwaltung-hero-shift {
0%, 100% { background-position: 0 0, 0% 50%; }
50% { background-position: 0 0, 100% 50%; }
}
.verwaltung-hero .eyebrow,
.verwaltung-hero h1,
.verwaltung-hero .lead { position: relative; z-index: 1; }
.verwaltung-hero h1 { margin: 0.3rem 0 0.6rem; }
.verwaltung-hero .lead { margin: 0; max-width: 62ch; }
.verwaltung-hero-sparkle { position: absolute; font-size: 1rem; pointer-events: none; z-index: 1; }
.verwaltung-hero-sparkle-1 { top: 1.4rem; right: 2.2rem; animation: account-nav-sparkle-twinkle 2.6s ease-in-out infinite; }
.verwaltung-hero-sparkle-2 { bottom: 1.6rem; right: 5rem; font-size: 0.7rem; animation: account-nav-sparkle-twinkle 3.4s ease-in-out infinite 0.6s; }
@media (prefers-reduced-motion: reduce) { .verwaltung-hero, .verwaltung-hero-sparkle { animation: none; } }
.verwaltung-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.9rem; margin: 1.2rem 0; }
.verwaltung-stat-grid-secondary { margin-top: 0; }
.verwaltung-stat-tile-mini { padding: 0.8rem 1rem; }
.verwaltung-stat-tile-mini .verwaltung-stat-icon { font-size: 1.3rem; }
.verwaltung-stat-tile-mini .verwaltung-stat-value { font-size: 1.4rem; }
#stat-attention-tile { border-color: color-mix(in srgb, var(--c-sale) 50%, transparent); background: color-mix(in srgb, var(--c-sale) 10%, var(--c-anthracite-light)); animation: verwaltung-attention-pulse 2s ease-in-out infinite; }
#stat-attention-tile .verwaltung-stat-value { color: var(--c-sale); }
@keyframes verwaltung-attention-pulse {
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-sale) 30%, transparent); }
50% { box-shadow: 0 0 16px -2px color-mix(in srgb, var(--c-sale) 55%, transparent); }
}
@media (prefers-reduced-motion: reduce) { #stat-attention-tile { animation: none; } }
.verwaltung-stat-tile {
display: flex;
flex-direction: column;
@@ -2904,3 +2947,72 @@ a:focus-visible, button:focus-visible {
.verwaltung-bar-track { height: 9px; border-radius: 999px; background: rgba(244, 241, 247, 0.08); overflow: hidden; }
.verwaltung-bar-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--c-accent), #9b7fd6); transition: width 0.6s var(--ease); }
.verwaltung-bar-fill-land { background: linear-gradient(90deg, #e3b23c, #f6dda0); }
.verwaltung-bar-fill-kunden { background: linear-gradient(90deg, #e3b23c, #9b7fd6); }
/* Hinweis-Banner "neue Bestellungen im Hintergrund entdeckt" — soll auffallen, aber nicht die
Ansicht selbst verändern, solange man nicht aktiv auf "Aktualisieren" klickt. */
.verwaltung-new-banner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
margin: 1rem 0;
padding: 0.8rem 1.1rem;
border-radius: var(--radius-m);
background: color-mix(in srgb, var(--c-accent) 16%, var(--c-anthracite-light));
border: 1.5px solid color-mix(in srgb, var(--c-accent) 45%, transparent);
animation: verwaltung-new-banner-glow 2.2s ease-in-out infinite;
}
@keyframes verwaltung-new-banner-glow {
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-accent) 30%, transparent); }
50% { box-shadow: 0 0 18px -2px color-mix(in srgb, var(--c-accent) 55%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .verwaltung-new-banner { animation: none; } }
/* Werkzeugleiste über der Bestellliste: Suche, Zeitraum, Sortierung, CSV-Export. */
.verwaltung-toolbar { display: flex; gap: 0.7rem; flex-wrap: wrap; align-items: center; margin: 1rem 0; }
.verwaltung-input {
padding: 0.65em 0.9em;
border-radius: var(--radius-s);
border: 1px solid rgba(244, 241, 247, 0.15);
background: var(--c-anthracite);
color: var(--c-text);
font-family: var(--font-body);
font-size: 0.9rem;
}
.verwaltung-input:focus { outline: 2px solid var(--c-accent); outline-offset: 2px; }
#verwaltung-search { flex: 1 1 260px; min-width: 200px; }
.verwaltung-select { cursor: pointer; }
.btn-xs { padding: 0.35em 0.7em; font-size: 0.78rem; white-space: nowrap; }
/* Chips direkt neben der Bestellnummer — "neu"/"Stammkundin"/"braucht Aufmerksamkeit" auf einen
Blick, ohne erst die Karte lesen zu müssen. */
.verwaltung-chip {
display: inline-flex;
align-items: center;
gap: 0.3em;
padding: 0.15em 0.6em;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 700;
margin-left: 0.5em;
vertical-align: middle;
}
.verwaltung-chip-new { background: color-mix(in srgb, var(--c-accent) 28%, transparent); border: 1px solid color-mix(in srgb, var(--c-accent) 55%, transparent); color: #d3f3fb; }
.verwaltung-chip-stamm { background: color-mix(in srgb, #9b7fd6 28%, transparent); border: 1px solid color-mix(in srgb, #9b7fd6 55%, transparent); color: #e4dbfa; }
.verwaltung-chip-attention { background: color-mix(in srgb, var(--c-sale) 28%, transparent); border: 1px solid color-mix(in srgb, var(--c-sale) 55%, transparent); color: #ffd7de; }
/* Bestellkarte, die "Aufmerksamkeit braucht" (offen + schon länger liegen geblieben) — warmer
Rand statt der neutralen Statusfarbe, damit sie in der Liste sofort auffällt. */
.order-card-attention { --status-color: var(--c-sale); }
/* Kopier-/PDF-Zeile: schnelle Aktionen fürs Verpacken/Versenden, ohne erst irgendwo hinklicken
zu müssen. */
.verwaltung-copy-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.7rem 0; }
.verwaltung-copy-hint { color: #7ec8a0; font-weight: 600; }
.verwaltung-order-foot { flex-wrap: wrap; }
.verwaltung-tracking-edit { display: flex; align-items: center; gap: 0.4rem; }
.verwaltung-tracking-input { width: 160px; padding: 0.4em 0.6em; font-size: 0.82rem; }