diff --git a/webdesign/verwaltung.html b/webdesign/verwaltung.html index 6714b2b0..bfeefb6c 100644 --- a/webdesign/verwaltung.html +++ b/webdesign/verwaltung.html @@ -35,16 +35,60 @@ .vw-leiste h1 { margin: 0; font-size: clamp(1.4rem, 3.4vw, 2rem); } .vw-wer { margin-left: auto; display: flex; align-items: center; gap: .6rem; font-size: .9rem; color: var(--wd-text-soft); } - /* ---------- Kennzahlen ---------- */ - .vw-zahlen { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: .7rem; margin-bottom: 1.4rem; } - .vw-zahl { - padding: .9rem 1rem; border-radius: 14px; - background: rgba(16,26,41,.6); border: 1px solid var(--wd-rand); - text-align: left; + + /* ---------- Kennzahlen, gehobene Fassung ---------- + Die erste Fassung war eine Reihe stiller Zahlen. Zahlen, die man + nur anschauen kann, sind Dekoration. Diese hier sind Werkzeuge: + jede Kachel filtert die Liste darunter, sobald man sie antippt. + + Eine Null wird bewusst gedaempft. Sonst konkurriert "0 abgelehnt" + optisch mit "3 neu" -- und genau die Drei ist die, auf die man + schauen soll. Was nichts zu tun gibt, soll auch nicht leuchten. */ + .vw-zahlen { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: .7rem; margin-bottom: 1.4rem; } - .vw-zahl-wert { font-family: var(--font-head); font-weight: 800; font-size: 1.7rem; line-height: 1; color: var(--wd-blau); } - .vw-zahl-name { font-size: .78rem; letter-spacing: .06em; color: var(--wd-text-soft); margin-top: .3rem; } + .vw-zahl { + position: relative; overflow: hidden; + display: block; width: 100%; text-align: left; cursor: pointer; + padding: .95rem 1.05rem; + border-radius: 16px; + background: linear-gradient(180deg, rgba(20,32,50,.62), rgba(9,15,26,.8)); + border: 1px solid var(--wd-rand); + transition: border-color var(--wd-zeit-schnell) ease, + transform var(--wd-zeit-schnell) ease, + box-shadow var(--wd-zeit) ease; + } + .vw-zahl:hover { border-color: var(--wd-rand-stark); transform: translateY(-2px); } + .vw-zahl.vw-an { + border-color: var(--wd-blau); + box-shadow: 0 0 0 1px var(--wd-blau) inset, 0 14px 34px -20px rgba(127,208,232,.7); + } + .vw-zahl-kopf { display: flex; align-items: center; gap: .45rem; margin-bottom: .35rem; } + .vw-zahl-symbol { font-size: 1rem; line-height: 1; opacity: .85; } + .vw-zahl-wert { + font-family: var(--font-head); font-weight: 800; + font-size: clamp(1.5rem, 3.4vw, 1.9rem); line-height: 1; + color: var(--wd-blau); font-variant-numeric: tabular-nums; + } + .vw-zahl-name { font-size: .78rem; letter-spacing: .03em; color: var(--wd-text-soft); } + .vw-zahl-zusatz { font-size: .74rem; color: var(--wd-text-soft); margin-top: .3rem; display: block; } + + /* Null: alles gedaempft, damit es nicht um Aufmerksamkeit buhlt. */ + .vw-zahl--null { opacity: .5; } + .vw-zahl--null .vw-zahl-wert { color: var(--wd-text-soft); } + + /* Handlungsbedarf: Gold, und nur hier. */ + .vw-zahl--achtung { border-color: rgba(232,200,119,.34); background: linear-gradient(180deg, rgba(232,200,119,.07), rgba(9,15,26,.8)); } .vw-zahl--achtung .vw-zahl-wert { color: var(--wd-gold); } + .vw-zahl--achtung .vw-zahl-zusatz { color: var(--wd-gold); } + + /* Dringend: etwas liegt zu lange. */ + .vw-zahl--dringend { border-color: rgba(255,157,157,.4); background: linear-gradient(180deg, rgba(255,157,157,.07), rgba(9,15,26,.8)); } + .vw-zahl--dringend .vw-zahl-wert, + .vw-zahl--dringend .vw-zahl-zusatz { color: var(--wd-fehler); } + /* ---------- Filter ---------- */ .vw-filter { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; align-items: center; } @@ -453,20 +497,83 @@ } function zeichneZahlen(zaehler) { - var offen = (zaehler.neu || 0) + (zaehler.rueckfrage || 0); var gesamt = Object.keys(zaehler).reduce(function (n, k) { return n + zaehler[k]; }, 0); + + /* Der aelteste unbearbeitete Vorgang ist die ehrlichste Kennzahl + ueberhaupt: Er sagt nicht, wie viel man geschafft hat, sondern wie + lange jemand schon auf eine Antwort wartet. Genau daran misst ein + Kunde, ob man zuverlaessig ist. */ + var wartend = alleAnfragen.filter(function (a) { + return a.status === "neu" || a.status === "rueckfrage"; + }); + var aeltesteTage = wartend.reduce(function (max, a) { + return Math.max(max, tageSeit(a.erstellt_am)); + }, 0); + var kacheln = [ - { wert: zaehler.neu || 0, name: "neu, ungelesen", achtung: (zaehler.neu || 0) > 0 }, - { wert: zaehler.pruefung || 0, name: "in Prüfung" }, - { wert: zaehler.angebot || 0, name: "Angebot raus" }, - { wert: zaehler.angenommen || 0, name: "angenommen" }, - { wert: gesamt, name: "insgesamt offen" }, + { + wert: zaehler.neu || 0, name: "neu, ungelesen", symbol: "📬", filter: "neu", + achtung: (zaehler.neu || 0) > 0, + zusatz: (zaehler.neu || 0) > 0 ? "warten auf dich" : "alles gesichtet", + }, + { + wert: zaehler.pruefung || 0, name: "in Prüfung", symbol: "🔍", filter: "pruefung", + zusatz: "du bist dran", + }, + { + wert: zaehler.angebot || 0, name: "Angebot raus", symbol: "📄", filter: "angebot", + zusatz: "Kunde ist dran", + }, + { + wert: zaehler.angenommen || 0, name: "angenommen", symbol: "✅", filter: "angenommen", + zusatz: "Projekt anlegen", + }, + { + /* Diese Kachel filtert bewusst NICHT -- sie zeigt einen Zustand, + keinen Status. Deshalb ist sie auch nicht anklickbar. */ + wert: aeltesteTage, name: aeltesteTage === 1 ? "Tag wartet der Älteste" : "Tage wartet der Älteste", + symbol: "⏳", filter: null, + dringend: aeltesteTage >= 7, + zusatz: aeltesteTage === 0 ? "nichts liegen geblieben" + : aeltesteTage >= 7 ? "das ist zu lang" : "noch im Rahmen", + }, + { + wert: gesamt, name: "insgesamt offen", symbol: "📊", filter: "", + zusatz: "alle anzeigen", + }, ]; + document.getElementById("vw-zahlen").innerHTML = kacheln.map(function (k) { - return '