Verwaltung: neue Kennzahlen-Kachel "Diesen Monat"
Bisher gab es nur "Heute"/"Letzte 7 Tage" — der ganze aktuelle Kalendermonat fehlte. Neue Kachel zeigt Bestellanzahl + Umsatz diesen Monat, anklickbar wie die anderen Kennzahlen-Kacheln (filtert die Bestellliste direkt danach). Auch als neue Option "Dieser Monat" im Zeitraum-Dropdown ergänzt — bewusst als echter Kalendermonat (ab dem 1.) berechnet, nicht einfach "letzte 30 Tage". Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
398ff2f886
commit
056ff6e574
@@ -121,6 +121,11 @@ const lang: Locale = "de";
|
|||||||
<span class="verwaltung-stat-value" id="stat-7tage">0</span>
|
<span class="verwaltung-stat-value" id="stat-7tage">0</span>
|
||||||
<span class="verwaltung-stat-label">Letzte 7 Tage</span>
|
<span class="verwaltung-stat-label">Letzte 7 Tage</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="monat">
|
||||||
|
<span class="verwaltung-stat-icon" aria-hidden="true">📆</span>
|
||||||
|
<span class="verwaltung-stat-value" id="stat-monat">0</span>
|
||||||
|
<span class="verwaltung-stat-label" id="stat-monat-label">Diesen Monat</span>
|
||||||
|
</button>
|
||||||
<div class="card verwaltung-stat-tile verwaltung-stat-tile-mini">
|
<div class="card verwaltung-stat-tile verwaltung-stat-tile-mini">
|
||||||
<span class="verwaltung-stat-icon" aria-hidden="true">📈</span>
|
<span class="verwaltung-stat-icon" aria-hidden="true">📈</span>
|
||||||
<span class="verwaltung-stat-value" id="stat-avg">–</span>
|
<span class="verwaltung-stat-value" id="stat-avg">–</span>
|
||||||
@@ -224,6 +229,7 @@ const lang: Locale = "de";
|
|||||||
<option value="alle">Alle Zeiträume</option>
|
<option value="alle">Alle Zeiträume</option>
|
||||||
<option value="heute">Heute</option>
|
<option value="heute">Heute</option>
|
||||||
<option value="7tage">Letzte 7 Tage</option>
|
<option value="7tage">Letzte 7 Tage</option>
|
||||||
|
<option value="monat">Dieser Monat</option>
|
||||||
<option value="30tage">Letzte 30 Tage</option>
|
<option value="30tage">Letzte 30 Tage</option>
|
||||||
</select>
|
</select>
|
||||||
<select id="verwaltung-sort" class="verwaltung-input verwaltung-select">
|
<select id="verwaltung-sort" class="verwaltung-input verwaltung-select">
|
||||||
@@ -405,13 +411,24 @@ const lang: Locale = "de";
|
|||||||
setText("stat-umsatz-label", `Gesamtumsatz (${aktive.length} Bestellung${aktive.length === 1 ? "" : "en"})`);
|
setText("stat-umsatz-label", `Gesamtumsatz (${aktive.length} Bestellung${aktive.length === 1 ? "" : "en"})`);
|
||||||
setText("stat-avg", aktive.length > 0 ? formatPrice(gesamtumsatz / aktive.length, lang) : "–");
|
setText("stat-avg", aktive.length > 0 ? formatPrice(gesamtumsatz / aktive.length, lang) : "–");
|
||||||
|
|
||||||
// ── Heute / letzte 7 Tage + "braucht Aufmerksamkeit" ──
|
// ── Heute / letzte 7 Tage / diesen Monat + "braucht Aufmerksamkeit" ──
|
||||||
const jetzt = Date.now();
|
const jetzt = Date.now();
|
||||||
const heuteStr = new Date().toLocaleDateString("de-DE");
|
const heuteStr = new Date().toLocaleDateString("de-DE");
|
||||||
const heuteCount = aktive.filter((b) => new Date(b.created_at).toLocaleDateString("de-DE") === heuteStr).length;
|
const heuteCount = aktive.filter((b) => new Date(b.created_at).toLocaleDateString("de-DE") === heuteStr).length;
|
||||||
const siebenTageCount = aktive.filter((b) => jetzt - new Date(b.created_at).getTime() <= 7 * MS_PRO_TAG).length;
|
const siebenTageCount = aktive.filter((b) => jetzt - new Date(b.created_at).getTime() <= 7 * MS_PRO_TAG).length;
|
||||||
|
// "Diesen Monat" = echter Kalendermonat (1. bis heute), nicht "letzte 30 Tage" — deshalb ein
|
||||||
|
// eigenes Feld statt einfach den 30-Tage-Wert zu verwenden.
|
||||||
|
const heuteDatum = new Date();
|
||||||
|
const monatsStart = new Date(heuteDatum.getFullYear(), heuteDatum.getMonth(), 1).getTime();
|
||||||
|
const monatCount = aktive.filter((b) => new Date(b.created_at).getTime() >= monatsStart).length;
|
||||||
|
const monatUmsatz = aktive.filter((b) => new Date(b.created_at).getTime() >= monatsStart).reduce((s, b) => s + Number(b.summe), 0);
|
||||||
setText("stat-heute", String(heuteCount));
|
setText("stat-heute", String(heuteCount));
|
||||||
setText("stat-7tage", String(siebenTageCount));
|
setText("stat-7tage", String(siebenTageCount));
|
||||||
|
setText("stat-monat", String(monatCount));
|
||||||
|
setText(
|
||||||
|
"stat-monat-label",
|
||||||
|
`Diesen Monat${monatCount > 0 ? ` (${formatPrice(monatUmsatz, lang)})` : ""}`
|
||||||
|
);
|
||||||
|
|
||||||
const attentionIds = new Set(
|
const attentionIds = new Set(
|
||||||
aktive.filter((b) => b.status === "bezahlt" && jetzt - new Date(b.created_at).getTime() > ALTER_SCHWELLE_TAGE * MS_PRO_TAG).map((b) => b.id)
|
aktive.filter((b) => b.status === "bezahlt" && jetzt - new Date(b.created_at).getTime() > ALTER_SCHWELLE_TAGE * MS_PRO_TAG).map((b) => b.id)
|
||||||
@@ -774,12 +791,19 @@ const lang: Locale = "de";
|
|||||||
const zeitraum = zeitraumSelect.value;
|
const zeitraum = zeitraumSelect.value;
|
||||||
const jetzt = Date.now();
|
const jetzt = Date.now();
|
||||||
const zeitraumMs = zeitraum === "heute" ? MS_PRO_TAG : zeitraum === "7tage" ? 7 * MS_PRO_TAG : zeitraum === "30tage" ? 30 * MS_PRO_TAG : null;
|
const zeitraumMs = zeitraum === "heute" ? MS_PRO_TAG : zeitraum === "7tage" ? 7 * MS_PRO_TAG : zeitraum === "30tage" ? 30 * MS_PRO_TAG : null;
|
||||||
|
// "Dieser Monat" ist kein festes Zeitfenster (wie die anderen), sondern der echte
|
||||||
|
// Kalendermonat ab dem 1. — deshalb separat berechnet statt über zeitraumMs.
|
||||||
|
const heuteDatum = new Date();
|
||||||
|
const monatsStart = zeitraum === "monat" ? new Date(heuteDatum.getFullYear(), heuteDatum.getMonth(), 1).getTime() : null;
|
||||||
|
|
||||||
let sichtbar = 0;
|
let sichtbar = 0;
|
||||||
document.querySelectorAll("#verwaltung-order-list .order-card").forEach((card) => {
|
document.querySelectorAll("#verwaltung-order-list .order-card").forEach((card) => {
|
||||||
const matchStatus = aktuellerStatusFilter === "alle" || card.dataset.bucket === aktuellerStatusFilter;
|
const matchStatus = aktuellerStatusFilter === "alle" || card.dataset.bucket === aktuellerStatusFilter;
|
||||||
const matchSuche = !suchtext || card.dataset.search.includes(suchtext);
|
const matchSuche = !suchtext || card.dataset.search.includes(suchtext);
|
||||||
const matchZeitraum = !zeitraumMs || jetzt - new Date(card.dataset.created).getTime() <= zeitraumMs;
|
const erstelltMs = new Date(card.dataset.created).getTime();
|
||||||
|
const matchZeitraum = monatsStart !== null
|
||||||
|
? erstelltMs >= monatsStart
|
||||||
|
: !zeitraumMs || jetzt - erstelltMs <= zeitraumMs;
|
||||||
const zeigen = matchStatus && matchSuche && matchZeitraum;
|
const zeigen = matchStatus && matchSuche && matchZeitraum;
|
||||||
card.style.display = zeigen ? "" : "none";
|
card.style.display = zeigen ? "" : "none";
|
||||||
if (zeigen) sichtbar++;
|
if (zeigen) sichtbar++;
|
||||||
|
|||||||
Reference in New Issue
Block a user