# Frontend (React) Quellcode in `frontend/`: Vite, React, TypeScript, React Router, TanStack Query. **Optik:** bewusst brutalistisch-roh. Markup, IDs und Klassen entsprechen dem früheren Vanilla-Frontend, `frontend/src/app.css` ist das einzige Stylesheet. Umbauten ändern Funktion, nicht Aussehen. ## Entwickeln Zwei Terminals: ```sh set -a; . ./dev.env; set +a; go run . # Backend auf :8081 cd frontend && npm run dev # http://localhost:5173 ``` Vite reicht `/api` und `/static` ans Backend durch (`frontend/vite.config.ts`, `changeOrigin: false` ist Pflicht, sonst scheitert jeder POST am Origin-Check). ## Bauen `npm run build` in `frontend/` prüft die Typen und schreibt nach `../web/` (gitignored). Von dort liefert das Go-Backend aus (`frontend.go`), lokal also auch ohne Vite: `npm run build`, dann `go run .`. Die Rechtstexte (`frontend/static/docs/*.html`) sind reine HTML-Seiten ohne JS, aber weitere Einstiege des Builds (`vite.config.ts`). So bekommen sie dasselbe gebaute `app.css`; ausgeliefert unter `/static/docs/…` (`serveDoc`). ### DEV-Container `./dev-up.sh` baut das Image aus dem Arbeitsverzeichnis und startet den Container `kver-dev` auf http://127.0.0.1:8081 neu (DSN aus `dev.env`, Daten und Medien read-only aus `prod_backup/`). Mit `git config core.hooksPath githooks` läuft das nach jedem Commit automatisch im Hintergrund (Log: `.git/dev-up.log`); einmalig aussetzen mit `KVER_NO_DEV_UP=1 git commit …`. ## Aufbau | Datei | Zweck | |-------|-------| | `src/api.ts` | API-Client; jeder Nicht-2xx-Status wird zu `ApiError` | | `src/types.ts` | Typen der API-Antworten (Referenz: `notes/api.md`) | | `src/auth.ts` | `useMe()` (eigenes Konto oder `null`), `useAuthChanged()` | | `src/main.tsx` | Router, QueryClient | | `src/Layout.tsx` | Header, Headerbar | | `src/pages/*` | Startseite, Thread, Profil, Statistik | | `src/components/*` | Feed, Beitragskarte, Votes, Repost, Login, Beitrag verfassen | Seitenrouten des Clients (`/`, `/e/:pid`, `/u/:username`, `/stats`) müssen auch in `routes()` (main.go) stehen, sonst liefert ein direkter Aufruf 404. ## Impressions Das Backend zählt Seitenaufrufe beim Ausliefern der `index.html`. Navigation innerhalb der App lädt keine Seite mehr vom Server und wird deshalb nicht gezählt -- nur der erste Aufruf bzw. ein Reload.