# Frontend-Architektur ## Struktur ``` frontend/src/ ├── App.jsx # Root: Auth-Gates, Navigation, Routing ├── app.css # CSS-Variablen + globale Klassen ├── main.jsx # Vite Entry Point ├── context/ │ ├── AuthContext.jsx # Session, Login, Logout, getToken() │ └── ProfileContext.jsx # Aktives Profil, Profile-Liste ├── pages/ # Eine Datei pro Screen ├── utils/ │ ├── api.js # Alle API-Calls (Token automatisch injiziert) │ ├── calc.js # Körperfett-Formeln (Jackson/Pollock etc.) │ ├── interpret.js # Regelbasierte Auswertungen │ ├── Markdown.jsx # Eigener Markdown-Renderer │ └── guideData.js # Messanleitungen (statisch) └── public/ # Icons (Jinkendo Ensō-Logo) ``` ## API-Calls – IMMER über api.js ```javascript // ✅ Richtig – Token wird automatisch injiziert: import { api } from '../utils/api' const data = await api.listWeight() await api.upsertWeight(date, weight, note) // ❌ Falsch – kein Token, gibt 401: const r = await fetch('/api/weight') ``` ## Neue API-Methode hinzufügen In `frontend/src/utils/api.js`: ```javascript export const api = { // ...bestehende Methoden... meinEndpoint: (param) => req(`/mein-endpoint?p=${param}`), createItem: (data) => req('/items', json(data)), updateItem: (id, d) => req(`/items/${id}`, jput(d)), deleteItem: (id) => req(`/items/${id}`, {method:'DELETE'}), } ``` ## Navigation (Haupt-App & Admin) - **Hauptmenü (Mobile + Desktop):** `frontend/src/config/appNav.js` (`getMainNavItems`) – in `App.jsx` (Bottom-Nav) und `DesktopSidebar.jsx` nutzen. - **Admin-Bereich:** `frontend/src/config/adminNav.js` + `layouts/AdminShell.jsx` + `layouts/RequireAdmin.jsx`; Shell wie Analyse (`.analysis-split*`). - **Bottom-Nav / Safe Area (PWA):** `--nav-h`, `.bottom-nav`, `.app-main` in `app.css`. - **Agent-Doku:** `docs/issues/GUI_IA_ADMIN_NAV_2026-04-05.md` ## Neue Seite hinzufügen 1. `frontend/src/pages/MeineSeite.jsx` erstellen 2. In `App.jsx` importieren und Route hinzufügen 3. Navigation: Eintrag in **`config/appNav.js`** (und ggf. Admin in **`adminNav.js`**) – nicht mehr nur in `App.jsx` duplizieren ## Komponenten-Pattern ```jsx export default function MeineSeite() { const [data, setData] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { load() }, []) const load = async () => { try { setLoading(true) setData(await api.meinEndpoint()) } catch(e) { setError(e.message) } finally { setLoading(false) } } if (loading) return