Files
Kontrollverlust/notes/frontend.md
T

55 lines
2.1 KiB
Markdown

# 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 .`.
### 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.