Verwaltung: alles in eigene, farblich unterschiedliche "Kisten" gepackt
Auf Feedback ("das ist mir zu einfach, ich will das alles in Kisten ist") die komplette
Auswertungsseite umgebaut: jede zusammengehörige Gruppe (Bestellstatus, Kennzahlen, Alle
Bestellungen, Bestseller je Kategorie, Herkunft der Bestellungen, Stammkundschaft) steckt
jetzt in einer eigenen, klar abgegrenzten Box mit eigenem Icon-Abzeichen, eigener
Akzentfarbe (Cyan/Lila/Gold/Grün/Pink) und dezent pulsierendem Glanzrand — statt lose auf
der Seite zu stehen.
Genauso wichtig: die Leerzustände (bevor die erste echte Bestellung eingeht) sehen jetzt
nicht mehr trostlos aus — großes Icon + freundlicher Text statt nacktem Fließtext, jeweils
passend zur Box (📭 Bestellungen, 🧶 Bestseller, 🗺️ Herkunft, 💌 Stammkundschaft). Mit
echtem Screenshot-Vergleich (befüllt UND leer, per fetch-Mock simuliert) verifiziert.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
af729ba571
commit
e2b89483c2
+161
-100
@@ -62,58 +62,76 @@ const lang: Locale = "de";
|
|||||||
<div id="verwaltung-content" style="display:none;">
|
<div id="verwaltung-content" style="display:none;">
|
||||||
<section class="section-tight">
|
<section class="section-tight">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="verwaltung-stat-grid">
|
{/* Jede zusammengehörige Gruppe bekommt jetzt ihre eigene, farblich eigenständige "Kiste"
|
||||||
<button type="button" class="card verwaltung-stat-tile" data-filter="offen">
|
(siehe .verwaltung-box in global.css) — statt loser Kacheln/Absätze auf der Seite. */}
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">🆕</span>
|
<div class="verwaltung-box" style="--box-color: var(--c-accent);">
|
||||||
<span class="verwaltung-stat-value" id="stat-offen">0</span>
|
<div class="verwaltung-box-head">
|
||||||
<span class="verwaltung-stat-label">Offen</span>
|
<span class="verwaltung-box-icon" aria-hidden="true">📊</span>
|
||||||
</button>
|
<h2>Bestellstatus</h2>
|
||||||
<button type="button" class="card verwaltung-stat-tile" data-filter="inBearbeitung">
|
</div>
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">⚙️</span>
|
<div class="verwaltung-box-body">
|
||||||
<span class="verwaltung-stat-value" id="stat-inBearbeitung">0</span>
|
<div class="verwaltung-stat-grid">
|
||||||
<span class="verwaltung-stat-label">In Bearbeitung</span>
|
<button type="button" class="card verwaltung-stat-tile" data-filter="offen">
|
||||||
</button>
|
<span class="verwaltung-stat-icon" aria-hidden="true">🆕</span>
|
||||||
<button type="button" class="card verwaltung-stat-tile" data-filter="versendet">
|
<span class="verwaltung-stat-value" id="stat-offen">0</span>
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">🚚</span>
|
<span class="verwaltung-stat-label">Offen</span>
|
||||||
<span class="verwaltung-stat-value" id="stat-versendet">0</span>
|
</button>
|
||||||
<span class="verwaltung-stat-label">Versendet</span>
|
<button type="button" class="card verwaltung-stat-tile" data-filter="inBearbeitung">
|
||||||
</button>
|
<span class="verwaltung-stat-icon" aria-hidden="true">⚙️</span>
|
||||||
<button type="button" class="card verwaltung-stat-tile" data-filter="abgeschlossen">
|
<span class="verwaltung-stat-value" id="stat-inBearbeitung">0</span>
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">✅</span>
|
<span class="verwaltung-stat-label">In Bearbeitung</span>
|
||||||
<span class="verwaltung-stat-value" id="stat-abgeschlossen">0</span>
|
</button>
|
||||||
<span class="verwaltung-stat-label">Abgeschlossen</span>
|
<button type="button" class="card verwaltung-stat-tile" data-filter="versendet">
|
||||||
</button>
|
<span class="verwaltung-stat-icon" aria-hidden="true">🚚</span>
|
||||||
<div class="card verwaltung-stat-tile verwaltung-stat-tile-highlight">
|
<span class="verwaltung-stat-value" id="stat-versendet">0</span>
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">💶</span>
|
<span class="verwaltung-stat-label">Versendet</span>
|
||||||
<span class="verwaltung-stat-value" id="stat-umsatz">–</span>
|
</button>
|
||||||
<span class="verwaltung-stat-label" id="stat-umsatz-label">Gesamtumsatz</span>
|
<button type="button" class="card verwaltung-stat-tile" data-filter="abgeschlossen">
|
||||||
|
<span class="verwaltung-stat-icon" aria-hidden="true">✅</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-abgeschlossen">0</span>
|
||||||
|
<span class="verwaltung-stat-label">Abgeschlossen</span>
|
||||||
|
</button>
|
||||||
|
<div class="card verwaltung-stat-tile verwaltung-stat-tile-highlight">
|
||||||
|
<span class="verwaltung-stat-icon" aria-hidden="true">💶</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-umsatz">–</span>
|
||||||
|
<span class="verwaltung-stat-label" id="stat-umsatz-label">Gesamtumsatz</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Zweite Kennzahlen-Reihe — Dinge, die im ersten Entwurf fehlten, aber im Alltag sehr
|
{/* Zweite Kennzahlen-Kiste — Dinge, die im ersten Entwurf fehlten, aber im Alltag sehr
|
||||||
wichtig sind: wie viel kommt gerade neu rein, und wie hoch ist der durchschnittliche
|
wichtig sind: wie viel kommt gerade neu rein, und wie hoch ist der durchschnittliche
|
||||||
Bestellwert (wichtig für Preis-/Werbeentscheidungen). "Heute"/"7 Tage" sind zusätzlich
|
Bestellwert (wichtig für Preis-/Werbeentscheidungen). "Heute"/"7 Tage" sind zusätzlich
|
||||||
anklickbar und setzen direkt den Zeitraum-Filter unten. */}
|
anklickbar und setzen direkt den Zeitraum-Filter unten. */}
|
||||||
<div class="verwaltung-stat-grid verwaltung-stat-grid-secondary">
|
<div class="verwaltung-box" style="--box-color: #9b7fd6;">
|
||||||
<button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="heute">
|
<div class="verwaltung-box-head">
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">📅</span>
|
<span class="verwaltung-box-icon" aria-hidden="true">📈</span>
|
||||||
<span class="verwaltung-stat-value" id="stat-heute">0</span>
|
<h2>Kennzahlen</h2>
|
||||||
<span class="verwaltung-stat-label">Bestellungen heute</span>
|
|
||||||
</button>
|
|
||||||
<button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="7tage">
|
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">🗓️</span>
|
|
||||||
<span class="verwaltung-stat-value" id="stat-7tage">0</span>
|
|
||||||
<span class="verwaltung-stat-label">Letzte 7 Tage</span>
|
|
||||||
</button>
|
|
||||||
<div class="card verwaltung-stat-tile verwaltung-stat-tile-mini">
|
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">📈</span>
|
|
||||||
<span class="verwaltung-stat-value" id="stat-avg">–</span>
|
|
||||||
<span class="verwaltung-stat-label">Ø Bestellwert</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card verwaltung-stat-tile verwaltung-stat-tile-mini" id="stat-attention-tile" style="display:none;">
|
<div class="verwaltung-box-body">
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">⚠️</span>
|
<div class="verwaltung-stat-grid verwaltung-stat-grid-secondary">
|
||||||
<span class="verwaltung-stat-value" id="stat-attention">0</span>
|
<button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="heute">
|
||||||
<span class="verwaltung-stat-label">Brauchen Aufmerksamkeit</span>
|
<span class="verwaltung-stat-icon" aria-hidden="true">📅</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-heute">0</span>
|
||||||
|
<span class="verwaltung-stat-label">Bestellungen heute</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="7tage">
|
||||||
|
<span class="verwaltung-stat-icon" aria-hidden="true">🗓️</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-7tage">0</span>
|
||||||
|
<span class="verwaltung-stat-label">Letzte 7 Tage</span>
|
||||||
|
</button>
|
||||||
|
<div class="card verwaltung-stat-tile verwaltung-stat-tile-mini">
|
||||||
|
<span class="verwaltung-stat-icon" aria-hidden="true">📈</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-avg">–</span>
|
||||||
|
<span class="verwaltung-stat-label">Ø Bestellwert</span>
|
||||||
|
</div>
|
||||||
|
<div class="card verwaltung-stat-tile verwaltung-stat-tile-mini" id="stat-attention-tile" style="display:none;">
|
||||||
|
<span class="verwaltung-stat-icon" aria-hidden="true">⚠️</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-attention">0</span>
|
||||||
|
<span class="verwaltung-stat-label">Brauchen Aufmerksamkeit</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -121,68 +139,108 @@ const lang: Locale = "de";
|
|||||||
|
|
||||||
<section class="section-tight">
|
<section class="section-tight">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>📦 Alle Bestellungen</h2>
|
<div class="verwaltung-box" style="--box-color: var(--c-accent);">
|
||||||
|
<div class="verwaltung-box-head">
|
||||||
|
<span class="verwaltung-box-icon" aria-hidden="true">📦</span>
|
||||||
|
<h2>Alle Bestellungen</h2>
|
||||||
|
</div>
|
||||||
|
<div class="verwaltung-box-body">
|
||||||
|
<div class="verwaltung-new-banner" id="verwaltung-new-banner" style="display:none;">
|
||||||
|
<span>🔔 <strong id="verwaltung-new-count"></strong> neue Bestellung(en) seit dem letzten Laden</span>
|
||||||
|
<button type="button" class="btn btn-primary btn-sm" id="verwaltung-new-refresh-btn">Jetzt aktualisieren</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="verwaltung-new-banner" id="verwaltung-new-banner" style="display:none;">
|
<div class="verwaltung-toolbar">
|
||||||
<span>🔔 <strong id="verwaltung-new-count"></strong> neue Bestellung(en) seit dem letzten Laden</span>
|
<input type="search" id="verwaltung-search" class="verwaltung-input" placeholder="🔍 Suche nach Bestellnummer, Name oder E-Mail …" />
|
||||||
<button type="button" class="btn btn-primary btn-sm" id="verwaltung-new-refresh-btn">Jetzt aktualisieren</button>
|
<select id="verwaltung-zeitraum" class="verwaltung-input verwaltung-select">
|
||||||
|
<option value="alle">Alle Zeiträume</option>
|
||||||
|
<option value="heute">Heute</option>
|
||||||
|
<option value="7tage">Letzte 7 Tage</option>
|
||||||
|
<option value="30tage">Letzte 30 Tage</option>
|
||||||
|
</select>
|
||||||
|
<select id="verwaltung-sort" class="verwaltung-input verwaltung-select">
|
||||||
|
<option value="neu">Neueste zuerst</option>
|
||||||
|
<option value="alt">Älteste zuerst</option>
|
||||||
|
<option value="wert-ab">Höchster Wert zuerst</option>
|
||||||
|
<option value="wert-auf">Niedrigster Wert zuerst</option>
|
||||||
|
</select>
|
||||||
|
<button type="button" class="btn btn-outline btn-sm" id="verwaltung-csv-btn">📄 CSV-Export</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="verwaltung-filter" aria-label="Nach Status filtern">
|
||||||
|
<button type="button" class="verwaltung-filter-btn is-active" data-filter="alle">Alle (<span id="filter-count-alle">0</span>)</button>
|
||||||
|
<button type="button" class="verwaltung-filter-btn" data-filter="offen">Offen (<span id="filter-count-offen">0</span>)</button>
|
||||||
|
<button type="button" class="verwaltung-filter-btn" data-filter="inBearbeitung">In Bearbeitung (<span id="filter-count-inBearbeitung">0</span>)</button>
|
||||||
|
<button type="button" class="verwaltung-filter-btn" data-filter="versendet">Versendet (<span id="filter-count-versendet">0</span>)</button>
|
||||||
|
<button type="button" class="verwaltung-filter-btn" data-filter="abgeschlossen">Abgeschlossen (<span id="filter-count-abgeschlossen">0</span>)</button>
|
||||||
|
<button type="button" class="verwaltung-filter-btn" data-filter="storniert">Storniert (<span id="filter-count-storniert">0</span>)</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="verwaltung-box-empty" id="verwaltung-empty" style="display:none;">
|
||||||
|
<span class="verwaltung-box-empty-icon" aria-hidden="true">📭</span>
|
||||||
|
<p>Noch keine Bestellungen eingegangen.</p>
|
||||||
|
<p class="small">Sobald die erste Bestellung im Checkout abgeschickt wird, erscheint sie sofort hier.</p>
|
||||||
|
</div>
|
||||||
|
<p class="small" id="verwaltung-no-match" style="display:none;">Keine Bestellung passt zur aktuellen Suche/Filterung.</p>
|
||||||
|
<div class="order-list" id="verwaltung-order-list"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="verwaltung-toolbar">
|
|
||||||
<input type="search" id="verwaltung-search" class="verwaltung-input" placeholder="🔍 Suche nach Bestellnummer, Name oder E-Mail …" />
|
|
||||||
<select id="verwaltung-zeitraum" class="verwaltung-input verwaltung-select">
|
|
||||||
<option value="alle">Alle Zeiträume</option>
|
|
||||||
<option value="heute">Heute</option>
|
|
||||||
<option value="7tage">Letzte 7 Tage</option>
|
|
||||||
<option value="30tage">Letzte 30 Tage</option>
|
|
||||||
</select>
|
|
||||||
<select id="verwaltung-sort" class="verwaltung-input verwaltung-select">
|
|
||||||
<option value="neu">Neueste zuerst</option>
|
|
||||||
<option value="alt">Älteste zuerst</option>
|
|
||||||
<option value="wert-ab">Höchster Wert zuerst</option>
|
|
||||||
<option value="wert-auf">Niedrigster Wert zuerst</option>
|
|
||||||
</select>
|
|
||||||
<button type="button" class="btn btn-outline btn-sm" id="verwaltung-csv-btn">📄 CSV-Export</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav class="verwaltung-filter" aria-label="Nach Status filtern">
|
|
||||||
<button type="button" class="verwaltung-filter-btn is-active" data-filter="alle">Alle (<span id="filter-count-alle">0</span>)</button>
|
|
||||||
<button type="button" class="verwaltung-filter-btn" data-filter="offen">Offen (<span id="filter-count-offen">0</span>)</button>
|
|
||||||
<button type="button" class="verwaltung-filter-btn" data-filter="inBearbeitung">In Bearbeitung (<span id="filter-count-inBearbeitung">0</span>)</button>
|
|
||||||
<button type="button" class="verwaltung-filter-btn" data-filter="versendet">Versendet (<span id="filter-count-versendet">0</span>)</button>
|
|
||||||
<button type="button" class="verwaltung-filter-btn" data-filter="abgeschlossen">Abgeschlossen (<span id="filter-count-abgeschlossen">0</span>)</button>
|
|
||||||
<button type="button" class="verwaltung-filter-btn" data-filter="storniert">Storniert (<span id="filter-count-storniert">0</span>)</button>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<p class="small" id="verwaltung-empty" style="display:none;">Noch keine Bestellungen eingegangen.</p>
|
|
||||||
<p class="small" id="verwaltung-no-match" style="display:none;">Keine Bestellung passt zur aktuellen Suche/Filterung.</p>
|
|
||||||
<div class="order-list" id="verwaltung-order-list"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="section-tight" id="verwaltung-auswertung-section">
|
<section class="section-tight" id="verwaltung-auswertung-section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>🏆 Meistverkaufte Produkte je Kategorie</h2>
|
<div class="verwaltung-box" style="--box-color: #e3b23c;">
|
||||||
<p class="small" id="verwaltung-kat-empty" style="display:none;">Noch keine ausgewerteten Verkäufe (stornierte Bestellungen zählen nicht mit).</p>
|
<div class="verwaltung-box-head">
|
||||||
<div class="verwaltung-auswertung-grid" id="verwaltung-kat-grid"></div>
|
<span class="verwaltung-box-icon" aria-hidden="true">🏆</span>
|
||||||
</div>
|
<h2>Bestseller je Kategorie</h2>
|
||||||
</section>
|
</div>
|
||||||
|
<div class="verwaltung-box-body">
|
||||||
<section class="section-tight">
|
<div class="verwaltung-box-empty" id="verwaltung-kat-empty" style="display:none;">
|
||||||
<div class="container">
|
<span class="verwaltung-box-empty-icon" aria-hidden="true">🧶</span>
|
||||||
<h2>🌍 Bestellungen nach Land</h2>
|
<p>Noch keine ausgewerteten Verkäufe.</p>
|
||||||
<div class="card verwaltung-kat-card">
|
<p class="small">Hier siehst du bald, welche Produkte je Kategorie am besten laufen (stornierte Bestellungen zählen nicht mit).</p>
|
||||||
<div class="verwaltung-bar-list" id="verwaltung-land-list"></div>
|
</div>
|
||||||
|
<div class="verwaltung-auswertung-grid" id="verwaltung-kat-grid"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="section-tight">
|
<section class="section-tight">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>👑 Beste Kundinnen</h2>
|
<div class="verwaltung-box" style="--box-color: #6ecb8f;">
|
||||||
<p class="small" id="verwaltung-kunden-empty" style="display:none;">Noch keine wiederkehrende Kundschaft.</p>
|
<div class="verwaltung-box-head">
|
||||||
<div class="card verwaltung-kat-card" id="verwaltung-kunden-card" style="display:none;">
|
<span class="verwaltung-box-icon" aria-hidden="true">🌍</span>
|
||||||
<div class="verwaltung-bar-list" id="verwaltung-kunden-list"></div>
|
<h2>Herkunft der Bestellungen</h2>
|
||||||
|
</div>
|
||||||
|
<div class="verwaltung-box-body">
|
||||||
|
<div class="verwaltung-box-empty" id="verwaltung-land-empty" style="display:none;">
|
||||||
|
<span class="verwaltung-box-empty-icon" aria-hidden="true">🗺️</span>
|
||||||
|
<p>Noch keine Bestellungen.</p>
|
||||||
|
<p class="small">Sobald Bestellungen eingehen, siehst du hier den Anteil je Land (DE/AT/CH/LU).</p>
|
||||||
|
</div>
|
||||||
|
<div class="verwaltung-bar-list" id="verwaltung-land-list"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section-tight">
|
||||||
|
<div class="container">
|
||||||
|
<div class="verwaltung-box" style="--box-color: var(--c-sale);">
|
||||||
|
<div class="verwaltung-box-head">
|
||||||
|
<span class="verwaltung-box-icon" aria-hidden="true">👑</span>
|
||||||
|
<h2>Stammkundschaft</h2>
|
||||||
|
</div>
|
||||||
|
<div class="verwaltung-box-body">
|
||||||
|
<div class="verwaltung-box-empty" id="verwaltung-kunden-empty" style="display:none;">
|
||||||
|
<span class="verwaltung-box-empty-icon" aria-hidden="true">💌</span>
|
||||||
|
<p>Noch keine wiederkehrende Kundschaft.</p>
|
||||||
|
<p class="small">Sobald jemand zum zweiten Mal bestellt, erscheint sie hier — sortiert nach bisherigem Umsatz.</p>
|
||||||
|
</div>
|
||||||
|
<div class="verwaltung-bar-list" id="verwaltung-kunden-list"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -482,14 +540,19 @@ const lang: Locale = "de";
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
const landList = document.getElementById("verwaltung-land-list");
|
const landList = document.getElementById("verwaltung-land-list");
|
||||||
landList.innerHTML = auswertungLaender.length === 0
|
const landEmpty = document.getElementById("verwaltung-land-empty");
|
||||||
? `<p class="small">Noch keine Bestellungen.</p>`
|
if (auswertungLaender.length === 0) {
|
||||||
: auswertungLaender.map((l) => `
|
landList.innerHTML = "";
|
||||||
|
landEmpty.style.display = "";
|
||||||
|
} else {
|
||||||
|
landEmpty.style.display = "none";
|
||||||
|
landList.innerHTML = auswertungLaender.map((l) => `
|
||||||
<div class="verwaltung-bar-row">
|
<div class="verwaltung-bar-row">
|
||||||
<div class="verwaltung-bar-head"><span>${l.flagge} ${escapeHtml(l.name)}</span><span class="small">${l.count} Bestellungen · ${l.prozent}%</span></div>
|
<div class="verwaltung-bar-head"><span>${l.flagge} ${escapeHtml(l.name)}</span><span class="small">${l.count} Bestellungen · ${l.prozent}%</span></div>
|
||||||
<div class="verwaltung-bar-track"><div class="verwaltung-bar-fill verwaltung-bar-fill-land" style="width:${l.balken}%"></div></div>
|
<div class="verwaltung-bar-track"><div class="verwaltung-bar-fill verwaltung-bar-fill-land" style="width:${l.balken}%"></div></div>
|
||||||
</div>
|
</div>
|
||||||
`).join("");
|
`).join("");
|
||||||
|
}
|
||||||
|
|
||||||
// ── NEU: Beste Kundinnen (Umsatz pro E-Mail, nur wer mehr als 1× bestellt hat) ──
|
// ── NEU: Beste Kundinnen (Umsatz pro E-Mail, nur wer mehr als 1× bestellt hat) ──
|
||||||
const umsatzProKundin = new Map(); // email -> { name, summe, anzahl }
|
const umsatzProKundin = new Map(); // email -> { name, summe, anzahl }
|
||||||
@@ -505,14 +568,12 @@ const lang: Locale = "de";
|
|||||||
.sort((a, b) => b.summe - a.summe)
|
.sort((a, b) => b.summe - a.summe)
|
||||||
.slice(0, 8);
|
.slice(0, 8);
|
||||||
const maxKundenUmsatz = Math.max(1, ...besteKunden.map((k) => k.summe));
|
const maxKundenUmsatz = Math.max(1, ...besteKunden.map((k) => k.summe));
|
||||||
const kundenCard = document.getElementById("verwaltung-kunden-card");
|
|
||||||
const kundenEmpty = document.getElementById("verwaltung-kunden-empty");
|
const kundenEmpty = document.getElementById("verwaltung-kunden-empty");
|
||||||
const kundenList = document.getElementById("verwaltung-kunden-list");
|
const kundenList = document.getElementById("verwaltung-kunden-list");
|
||||||
if (besteKunden.length === 0) {
|
if (besteKunden.length === 0) {
|
||||||
kundenCard.style.display = "none";
|
kundenList.innerHTML = "";
|
||||||
kundenEmpty.style.display = "";
|
kundenEmpty.style.display = "";
|
||||||
} else {
|
} else {
|
||||||
kundenCard.style.display = "";
|
|
||||||
kundenEmpty.style.display = "none";
|
kundenEmpty.style.display = "none";
|
||||||
kundenList.innerHTML = besteKunden.map((k) => `
|
kundenList.innerHTML = besteKunden.map((k) => `
|
||||||
<div class="verwaltung-bar-row">
|
<div class="verwaltung-bar-row">
|
||||||
|
|||||||
@@ -2861,6 +2861,75 @@ a:focus-visible, button:focus-visible {
|
|||||||
|
|
||||||
/* Interne Bestellverwaltung (/verwaltung/) — Status-Kacheln, Filterleiste, Auswertungs-Balken. */
|
/* Interne Bestellverwaltung (/verwaltung/) — Status-Kacheln, Filterleiste, Auswertungs-Balken. */
|
||||||
|
|
||||||
|
/* "Kisten" — jede zusammengehörige Gruppe (Bestellstatus, Kennzahlen, Bestellliste, Bestseller,
|
||||||
|
Herkunft, Stammkundschaft) bekommt ihre eigene, klar abgegrenzte Box mit eigener Akzentfarbe
|
||||||
|
(--box-color, pro Kiste per inline style gesetzt) statt lose auf der Seite zu stehen — auf
|
||||||
|
Wunsch ("alles was zueinander passt in einer Kiste, richtig geil speziell") deutlich
|
||||||
|
eigenständiger gestaltet als eine normale .card: eigener farbiger Eckenschein, eigenes
|
||||||
|
Icon-Abzeichen vor dem Titel, dezent pulsierender Rand. */
|
||||||
|
.verwaltung-box {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: var(--radius-l);
|
||||||
|
border: 1.5px solid color-mix(in srgb, var(--box-color, var(--c-accent)) 38%, transparent);
|
||||||
|
background: linear-gradient(155deg, color-mix(in srgb, var(--box-color, var(--c-accent)) 9%, var(--c-anthracite-light)), var(--c-anthracite));
|
||||||
|
padding: 1.6rem 1.7rem;
|
||||||
|
margin: 1.4rem 0;
|
||||||
|
animation: verwaltung-box-glow 3.4s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
@keyframes verwaltung-box-glow {
|
||||||
|
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--box-color, var(--c-accent)) 22%, transparent); }
|
||||||
|
50% { box-shadow: 0 0 22px -8px color-mix(in srgb, var(--box-color, var(--c-accent)) 55%, transparent); }
|
||||||
|
}
|
||||||
|
.verwaltung-box::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: -45%;
|
||||||
|
right: -15%;
|
||||||
|
width: 260px;
|
||||||
|
height: 260px;
|
||||||
|
background: radial-gradient(circle, color-mix(in srgb, var(--box-color, var(--c-accent)) 30%, transparent), transparent 70%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.verwaltung-box-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
margin-bottom: 1.1rem;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.verwaltung-box-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 2.6rem;
|
||||||
|
height: 2.6rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
background: color-mix(in srgb, var(--box-color, var(--c-accent)) 24%, transparent);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--box-color, var(--c-accent)) 55%, transparent);
|
||||||
|
}
|
||||||
|
.verwaltung-box-head h2 { margin: 0; font-size: 1.3rem; }
|
||||||
|
.verwaltung-box-body { position: relative; z-index: 1; }
|
||||||
|
@media (prefers-reduced-motion: reduce) { .verwaltung-box { animation: none; } }
|
||||||
|
|
||||||
|
/* Leerzustände innerhalb einer Kiste — großes Icon + kurzer, freundlicher Text statt nacktem
|
||||||
|
Fließtext, damit auch "noch nichts da" nicht trostlos wirkt. */
|
||||||
|
.verwaltung-box-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
padding: 2.2rem 1rem;
|
||||||
|
color: var(--c-text-muted);
|
||||||
|
}
|
||||||
|
.verwaltung-box-empty-icon { font-size: 2.6rem; opacity: 0.75; }
|
||||||
|
.verwaltung-box-empty p { margin: 0; }
|
||||||
|
.verwaltung-box-empty p:first-of-type { color: var(--c-text); font-weight: 600; font-size: 1.02rem; }
|
||||||
|
|
||||||
/* Hero-Kopf: dieselbe "besondere" Formsprache wie die anderen Premium-Karten der Seite
|
/* Hero-Kopf: dieselbe "besondere" Formsprache wie die anderen Premium-Karten der Seite
|
||||||
(wanderndes Verlaufslicht + pulsierender Rand + Funkeln), passend zu einer Seite, die "alles
|
(wanderndes Verlaufslicht + pulsierender Rand + Funkeln), passend zu einer Seite, die "alles
|
||||||
übertrifft" — nur dezenter/edler gehalten, weil es ein Arbeits-Dashboard ist, kein Verkaufs-
|
übertrifft" — nur dezenter/edler gehalten, weil es ein Arbeits-Dashboard ist, kein Verkaufs-
|
||||||
|
|||||||
Reference in New Issue
Block a user