# web-react — фронтенд на React (Vite + TypeScript) Замена Flet-интерфейса (`../web`). Обычный SPA: грузится в браузер один раз и работает локально, обращаясь к API по HTTP. **Нет WebSocket и серверного UI-стейта** — это убирает зависания, которые были у Flet (он рендерил UI на сервере и держал WS на каждого юзера). Flet-сервис `web` намеренно оставлен в `docker-compose.yml` как запасной. Этот новый фронтенд публикуется на **порту 3000**. ## Архитектура ``` Браузер ──▶ [ nginx :80 (контейнер web-react) ] ├── / → статика React (SPA, fallback на index.html) └── /api/* → proxy_pass http://api:8000/ (включая SVG-диаграммы) ``` API-контейнер доступен только внутри Docker-сети, поэтому браузер ходит к нему через nginx-прокси на том же origin (`/api/...`). SVG-диаграмма тянется напрямую ``/``. ## Разработка (локально) ```bash # 1. Поднять API + БД (из корня репозитория) docker compose up -d api postgres redis # postgres/redis — из docker-compose_db.yml # 2. Dev-сервер фронтенда cd web-react npm install npm run dev # http://localhost:5173, /api проксируется на http://localhost:8000 ``` Адрес API для dev-прокси переопределяется переменной `API_URL` (см. `vite.config.ts`). ## Сборка / прод ```bash # из корня репозитория docker compose up -d --build web-react # http://localhost:3000 ``` Либо вручную: `npm run build` → статика в `dist/`, раздаётся nginx (см. `Dockerfile`, `nginx.conf`). ## Структура | Путь | Назначение | |---|---| | `src/api/client.ts` | все запросы к API (порт `web/api_client.py`) | | `src/auth/` | `AuthContext` — токен в localStorage + `/users/me` | | `src/theme/` | 5 тем + слайдер масштаба через CSS-переменные | | `src/components/` | переиспользуемые компоненты (Button, TextField, SearchableDropdown, Layout, Modal, RadarBlock…) | | `src/pages/` | экраны: Login, Register, Home, TestList, Poll, MyTests, Response, Profile | | `src/styles/global.css` | стили на CSS-переменных | ## Маршруты `/login`, `/register`, `/` (домашняя), `/tests`, `/poll/:pollId`, `/my-tests`, `/response/:responseId`, `/profile`. Защищённые маршруты требуют токен (`ProtectedRoute`).