feat(ui): UI-004 Dashboard "Was ist jetzt zu tun?"-Karte
Neue Karte ganz oben fasst offene Fehlbestände, kritische Mängel, überfällige Prüfungen, abgelaufene Chargen und nie kontrollierte Objekte zusammen (bereits geladene Daten, keine neuen Endpunkte), mit Direktlinks - "5-Sekunden-Antwort" auf "was muss ich jetzt tun". Nebenbei: fehlende .text-success/.text-danger in global.css ergänzt (waren in AktePage.tsx bereits referenziert, aber nie definiert). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
@@ -121,6 +121,30 @@ export function DashboardPage() {
|
||||
const maengelOffenAnzahl = maengel.filter((m) => m.status !== "erledigt").length;
|
||||
const maengelKritischAnzahl = maengel.filter((m) => m.status !== "erledigt" && m.prioritaet === "hoch").length;
|
||||
const maengelOffenListe = maengel.filter((m) => m.status !== "erledigt");
|
||||
const pruefungenUeberfaellig = prueftermine.filter((p) => p.status === "abgelaufen").length;
|
||||
const ablaufdatenAbgelaufen = ablaufdaten.filter((a) => a.status === "abgelaufen").length;
|
||||
|
||||
// UI-004 (Epic 20): "Was ist einsatzbereit und was muss ich jetzt tun?" in
|
||||
// 5 Sekunden beantwortbar - eine Aufgaben-Karte statt Zahlen über sechs
|
||||
// gleichrangige Karten verteilt suchen zu müssen. Keine neuen Daten, nur
|
||||
// Zusammenfassung der bereits geladenen Kennzahlen mit Direktlinks.
|
||||
const aufgaben = [
|
||||
kennzahlen && kennzahlen.anzahl_offener_fehlbestaende > 0
|
||||
? { text: `${kennzahlen.anzahl_offener_fehlbestaende} offene Fehlbestände`, ziel: "/fehlbestaende" }
|
||||
: null,
|
||||
maengelKritischAnzahl > 0
|
||||
? { text: `${maengelKritischAnzahl} kritische Mängel offen`, ziel: "/maengel" }
|
||||
: null,
|
||||
pruefungenUeberfaellig > 0
|
||||
? { text: `${pruefungenUeberfaellig} Geräteprüfungen überfällig`, ziel: null }
|
||||
: null,
|
||||
ablaufdatenAbgelaufen > 0
|
||||
? { text: `${ablaufdatenAbgelaufen} Chargen abgelaufen`, ziel: null }
|
||||
: null,
|
||||
bereitschaft && bereitschaft.unbekannt > 0
|
||||
? { text: `${bereitschaft.unbekannt} Objekte noch nie kontrolliert`, ziel: "/objekte" }
|
||||
: null,
|
||||
].filter((a): a is { text: string; ziel: string | null } => a !== null);
|
||||
|
||||
return (
|
||||
<main className="page-wide">
|
||||
@@ -129,6 +153,23 @@ export function DashboardPage() {
|
||||
{laedt && <p className="text-muted">Lade…</p>}
|
||||
{!laedt && bereitschaft && (
|
||||
<div className="card-grid">
|
||||
<div className="card" style={{ flexBasis: "100%" }}>
|
||||
<h3 style={{ marginTop: 0 }}>Was ist jetzt zu tun?</h3>
|
||||
{aufgaben.length === 0 ? (
|
||||
<p className="text-success" style={{ fontWeight: 600 }}>
|
||||
✅ Nichts Dringendes offen.
|
||||
</p>
|
||||
) : (
|
||||
<ul className="card-list">
|
||||
{aufgaben.map((a, i) => (
|
||||
<li key={i}>
|
||||
{a.ziel ? <Link to={a.ziel}>{a.text}</Link> : <span>{a.text}</span>}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="card">
|
||||
<h3 style={{ marginTop: 0 }}>Einsatzbereitschaft</h3>
|
||||
<p className="stat-number">
|
||||
|
||||
@@ -541,6 +541,14 @@ select.input:focus {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user