From bd694b30a6bd111f1c21916d831d35d36855d783 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 5 Apr 2026 11:28:33 +0200 Subject: [PATCH] feat: Add admin access denial alert to Dashboard with timeout handling --- docs/issues/REVIEW_OPEN_ISSUES_2026-04-04.md | 11 +++---- frontend/src/pages/Dashboard.jsx | 31 +++++++++++++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/docs/issues/REVIEW_OPEN_ISSUES_2026-04-04.md b/docs/issues/REVIEW_OPEN_ISSUES_2026-04-04.md index 9f6e98b..30d23d5 100644 --- a/docs/issues/REVIEW_OPEN_ISSUES_2026-04-04.md +++ b/docs/issues/REVIEW_OPEN_ISSUES_2026-04-04.md @@ -17,7 +17,7 @@ | # | Titel (gekürzt) | Vorschlag | Notiz | |---|-----------------|-----------|--------| -| 14 | Icon Picker Trainingstypen | OFFEN | Nur Freitext-Feld `icon` | +| 14 | Icon Picker Trainingstypen | **ERLEDIGT** | `EmojiIconPicker` in `AdminTrainingTypesPage.jsx`; Gitea #14 geschlossen (2026-04) | | 15 | Quality-Filter KI & Charts | TEILWEISE | Registry/Charts Confidence, kein durchgängiges Produkt | | 21 | Universeller CSV-Parser + Mapping | OFFEN | Modul-spezifische Parser | | 25 | Ziele-System Goals | DONE? | GoalsPage, Router, Focus Areas | @@ -48,14 +48,11 @@ ## Details je Issue (älteste zuerst) -### #14 – [FEAT-001] Icon Picker für Trainingstypen +### #14 – [FEAT-001] Icon Picker für Trainingstypen — **ERLEDIGT** -**Code-Stand:** `AdminTrainingTypesPage.jsx` nutzt ein **Textfeld** `icon` (frei, z. B. Emoji). Kein dedizierter Icon-Picker (Palette, Vorschau, Kategorien). +**Code-Stand:** `AdminTrainingTypesPage.jsx` nutzt **`EmojiIconPicker`** (`frontend/src/components/EmojiIconPicker.jsx`) für Neu- und Bearbeiten-Dialoge; Wert bleibt String in `training_types.icon`. -**Vorschlag:** `OFFEN` – Issue beibehalten; optional präzisieren: „Emoji-Picker oder vordefinierte Icon-Liste statt Freitext“. - -**Kommentar-Entwurf für Gitea:** -> Stand Backend/Frontend: `icon` wird als String in `training_types` gespeichert, Eingabe ist Freitext. Icon-Picker-UX steht noch aus. +**Gitea:** Issue **#14 geschlossen** (Kommentar + Close, Stand 2026-04). --- diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index eb2ae66..7cff98c 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react' -import { useNavigate } from 'react-router-dom' +import { useNavigate, useLocation } from 'react-router-dom' import { Check, Brain } from 'lucide-react' import { LineChart, Line, XAxis, YAxis, Tooltip, @@ -252,8 +252,11 @@ function ComboChart({ weights, nutrition }) { // ── Main Dashboard ──────────────────────────────────────────────────────────── export default function Dashboard() { const nav = useNavigate() + const location = useLocation() const { activeProfile } = useProfile() + const [adminDeniedHint, setAdminDeniedHint] = useState(false) + const [stats, setStats] = useState(null) const [weights, setWeights] = useState([]) const [calipers, setCalipers] = useState([]) @@ -299,6 +302,14 @@ export default function Dashboard() { useEffect(()=>{ load() },[]) + useEffect(() => { + if (!location.state?.adminDenied) return + setAdminDeniedHint(true) + nav('.', { replace: true, state: null }) + const clear = window.setTimeout(() => setAdminDeniedHint(false), 8000) + return () => window.clearTimeout(clear) + }, [location.state, nav]) + if (loading) return
const latestCal = calipers[0] @@ -349,6 +360,24 @@ export default function Dashboard() { return (
+ {adminDeniedHint && ( +
+ Kein Admin-Zugriff. Dieser Bereich ist nur für Konten mit Administrator-Rolle. + Du wurdest zur Übersicht weitergeleitet. +
+ )} {/* Header greeting */}