Files
sop-ultime/sop-front/README.md
2026-05-06 12:22:17 +02:00

167 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Smash or Pass — Frontend
Vue 3 + TypeScript + Vite + Pinia + Tailwind CSS v4. Talks to the [`sop-back`](../sop-back/) FastAPI server.
See [`../CLAUDE.md`](../CLAUDE.md) for full architecture notes.
---
## Stack
- Vue 3 with `<script setup lang="ts">` (TypeScript everywhere)
- Vite 8 (dev server + bundler)
- Vue Router (SPA: `/`, `/game/:id`, `/summary`)
- Pinia (game state: queue / smashed / passed)
- Tailwind CSS v4 via `@tailwindcss/vite`. Custom palette + fonts in [`src/assets/main.css`](src/assets/main.css) inside an `@theme { ... }` block.
---
## Project layout
```
sop-front/
├── index.html
├── vite.config.ts # Tailwind v4 plugin + alias '@'
├── nginx.conf # SPA fallback for production image
├── Dockerfile # multi-stage: vite build → nginx
└── src/
├── main.ts # imports ./assets/main.css
├── App.vue # only <RouterView />
├── router/index.ts
├── api/client.ts # typed fetch wrapper, reads VITE_API_BASE_URL
├── stores/game.ts # Pinia store
├── assets/main.css # Tailwind + @theme tokens (palette, fonts)
├── components/
│ ├── SwipeCard.vue # pointer-event drag, exposes triggerSmash/Pass
│ └── AdminPanel.vue
└── views/
├── HomeView.vue
├── GameView.vue
└── SummaryView.vue
```
---
## Configuration
One environment variable, **build-time** (Vite inlines it):
| Var | Default | Notes |
|---|---|---|
| `VITE_API_BASE_URL` | `http://localhost:8000` | Backend origin |
For dev, set in a `.env.local`:
```
VITE_API_BASE_URL=http://localhost:8000
```
For Docker builds, pass it as a build arg (already wired in the repo-root `docker-compose.yml`):
```yaml
frontend:
build:
context: ./sop-front
args:
VITE_API_BASE_URL: "https://api.example.com"
```
---
## Local development
```bash
cd sop-front
npm install
npm run dev
```
- App: http://localhost:5173
- Make sure the backend is running at `VITE_API_BASE_URL` (default `http://localhost:8000`).
### Other scripts
| Command | What |
|---|---|
| `npm run dev` | Vite dev server with HMR |
| `npm run build` | Type-check + production build into `dist/` |
| `npm run type-check` | `vue-tsc --build` only |
| `npm run preview` | Serve the built `dist/` locally |
| `npm run lint` | oxlint + eslint |
| `npm run format` | Prettier |
| `npm run test:unit` | Vitest |
---
## Customizing colors / fonts
**All design tokens live in [`src/assets/main.css`](src/assets/main.css)** under `@theme`. The palette is **graded** (Tailwind-style): each hue has a 50900 scale, with **500** as the canonical brand value. Add new shades there; don't hardcode hex values in components.
### Scales (`50` lightest → `900/950` darkest)
| Family | 500 (brand) | Use |
|---|---|---|
| `--color-purple-{50…900}` | `#8324DE` | Primary brand |
| `--color-red-{50…900}` | `#FF453B` | Pass / errors / destructive |
| `--color-lime-{50…900}` | `#B9D532` | Smash / success |
| `--color-neutral-{50…950}` | `#63586E` | Backgrounds, surfaces, text, borders |
Components reference shades like `var(--color-purple-300)`, `var(--color-neutral-800)`, etc. The neutral scale handles dark-mode surfaces (`50` = off-white text, `950` = `#16141A` background).
### Semantic aliases (prefer these in components)
These point at scale values — change them once in `main.css` to retheme:
| Alias | → Scale | Role |
|---|---|---|
| `--color-primary` | `purple-500` | CTAs / brand |
| `--color-primary-hover` | `purple-400` | CTA hover |
| `--color-smash` | `lime-500` | Smash action |
| `--color-pass` | `red-500` | Pass action |
| `--color-bg` | `neutral-950` | App background |
| `--color-surface` | `neutral-900` | Card surface |
| `--color-surface-2` | `neutral-800` | Elevated surface |
| `--color-border` | `neutral-700` | Borders |
| `--color-text` | `neutral-50` | Primary text |
| `--color-text-muted` | `neutral-300` | Secondary text |
Fonts: **Bebas Neue** (display) + **Roboto** (body), loaded via Google Fonts in `main.css`.
---
## Production deployment
### Docker (recommended)
A multi-stage Dockerfile builds the SPA with Vite and serves the static bundle with nginx. From the repo root:
```bash
docker compose up -d --build frontend
```
The image listens on port 80 inside the container; the compose file maps it to host `:8080`.
For a real deployment:
1. **Set `VITE_API_BASE_URL`** to the public backend URL **at build time** (build arg, not runtime env). Rebuild the image whenever it changes.
2. **Front it with HTTPS** — Caddy / Traefik / Cloudflare in front of port 80.
3. The bundled `nginx.conf` already does SPA fallback (`try_files $uri /index.html`).
4. Make sure the backend CORS `ALLOWED_ORIGINS` includes the frontend's public origin.
### Static hosting (no Docker)
```bash
npm install
VITE_API_BASE_URL=https://api.example.com npm run build
```
Upload the contents of `dist/` to any static host (S3+CloudFront, Netlify, Vercel, GitHub Pages, etc.). Configure SPA fallback so any unknown path serves `index.html`.
---
## Notes
- `VITE_API_BASE_URL` is **baked into the JS bundle** at build time. Changing it requires a rebuild.
- All API calls go through [`src/api/client.ts`](src/api/client.ts) — extend that wrapper rather than calling `fetch` directly from components.
- The admin panel renders only when `GET /admin/status` returns `admin_enabled: true`. That flag lives in the **backend's** `.env`.