From c2b2c71ccd3a7430901d6b06ad289215379a5230 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 5 Apr 2026 08:03:53 +0200 Subject: [PATCH] feat: Enhance Dashboard layout with responsive greeting and metrics display --- docs/issues/PHASE_PLAN_RESPONSIVE_UI.md | 4 +- frontend/src/app.css | 78 +++++++++++++++++++++++++ frontend/src/pages/Dashboard.jsx | 21 ++++--- 3 files changed, 90 insertions(+), 13 deletions(-) diff --git a/docs/issues/PHASE_PLAN_RESPONSIVE_UI.md b/docs/issues/PHASE_PLAN_RESPONSIVE_UI.md index 332ae17..fedefdb 100644 --- a/docs/issues/PHASE_PLAN_RESPONSIVE_UI.md +++ b/docs/issues/PHASE_PLAN_RESPONSIVE_UI.md @@ -3,7 +3,7 @@ > **Gitea:** [#30 – Responsive UI](http://192.168.2.144:3000/Lars/mitai-jinkendo/issues/30) > **Spec:** `.claude/docs/functional/RESPONSIVE_UI.md` > **Breakpoint:** `<1024px` = Mobile (Bottom-Nav, bestehendes Verhalten), `≥1024px` = Desktop (Sidebar 220px) -> **Letzte Plan-Aktualisierung:** 2026-04-05 +> **Letzte Plan-Aktualisierung:** 2026-04-06 --- @@ -14,7 +14,7 @@ | P0 | Vorbereitung & Baseline | ☑ erledigt | Spec `RESPONSIVE_UI.md` bereinigt | | P1 | App-Shell: Sidebar + Breakpoint + gemeinsame Navigation | ☑ erledigt | `DesktopSidebar`, `config/appNav.js`, Admin `/admin/*`-Highlight | | P2 | Globales Layout & Content-Bereich (CSS) | ☑ erledigt | Desktop: Header aus, Content max 1200px; Mobile unverändert Bottom-Nav | -| P3 | Dashboard (Desktop-Grid) | ☐ pending | | +| P3 | Dashboard (Desktop-Grid) | ☑ erledigt | 4-spaltige Kennzahlen; Begrüßung; Ernährung/Aktivität 2-spaltig | | P4 | Verlauf (Tabs links / Content rechts) | ☐ pending | | | P5 | Analyse (Prompts links / Ergebnis rechts) | ☐ pending | | | P6 | Erfassung / Capture & Formularseiten | ☐ pending | | diff --git a/frontend/src/app.css b/frontend/src/app.css index b572b16..034ae63 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -344,4 +344,82 @@ body { font-family: var(--font); background: var(--bg); color: var(--text1); -we width: 100%; box-sizing: border-box; } + + /* Dashboard (P3): Begrüßung + Kennzahlen-Zeile */ + .dashboard-greeting { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 16px; + flex-wrap: wrap; + margin-bottom: 16px; + } + + .dashboard-greeting__meta { + margin-top: 0 !important; + text-align: right; + } +} + +/* ── Dashboard layout (Mobile baseline + Desktop im Block oben teilweise) ─ */ + +.dashboard-page { + width: 100%; +} + +.dashboard-greeting { + margin-bottom: 16px; +} + +.dashboard-stat-grid { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 16px; +} + +.dashboard-stat-card { + background: var(--surface); + border-radius: 12px; + padding: 12px 10px; + border: 1px solid var(--border); + transition: border-color 0.15s; + flex: 1 1 140px; + min-width: 80px; + box-sizing: border-box; +} + +.dashboard-summary-row { + display: flex; + gap: 8px; + margin-bottom: 16px; +} + +.dashboard-summary-row > .card { + flex: 1; + min-width: 0; +} + +@media (min-width: 1024px) { + .dashboard-stat-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + } + + .dashboard-stat-grid .dashboard-stat-card { + flex: unset; + min-width: 0; + width: 100%; + } + + .dashboard-summary-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + } + + .dashboard-summary-row > .card { + flex: unset; + } } diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index bee4249..fd0e4fa 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -148,11 +148,10 @@ function StatCard({ icon, label, value, unit, delta, deltaGoodWhenNeg=false, sub const deltaColor = delta==null ? null : (deltaGoodWhenNeg ? delta<0 : delta>0) ? 'var(--accent)' : 'var(--warn)' return ( -
onClick&&(e.currentTarget.style.borderColor='var(--accent)')} onMouseLeave={e=>onClick&&(e.currentTarget.style.borderColor='var(--border)')}>
{icon}
@@ -321,13 +320,13 @@ export default function Dashboard() { console.log('[Dashboard] hasAnyData=', hasAnyData, 'latestW=', !!latestW, 'latestCal=', !!latestCal, 'nutrition.length=', nutrition.length) return ( -
+
{/* Header greeting */} -
+

Hallo, {activeProfile?.name||'Nutzer'} 👋

-
+
{dayjs().format('dddd, DD. MMMM YYYY')} {latestW && ` · Letztes Update ${dayjs(latestW.date).format('DD.MM.')}`}
@@ -362,8 +361,8 @@ export default function Dashboard() {
- {/* Key metrics */} -
+ {/* Key metrics — Mobile: flex-wrap; Desktop: 4-spaltig (RESPONSIVE_UI P3) */} +
+
{(avgKcal||avgProtein) && (
nav('/history',{state:{tab:'nutrition'}})}>
🍽️ ERNÄHRUNG (Ø 7T)