# Спецификация 06: Flutter Web UI (`3-app\3-web\admin-web`) Источники: решение владельца 2026-10-17 (Flutter Web), UI/UX-стандарт (tech-req разд. 6: тёмная тема, ≥16pt, цвет дублируется текстом). ## 1. Каркас - `flutter create --platforms web` (SDK 3.47.7, `C:\tools\flutter`); Material 3, тёмная тема; **без внешних pub-пакетов** (только SDK: `dart:io`/`http` из `dart:io`? web → `package:http` входит в SDK как `dart:io` нет — используется `HttpRequest`/`fetch` через `package:http` из SDK-зависимостей flutter (входит в flutter create) — внешних добавок нет); - состояние — `ChangeNotifier` (`AdminState`: токен, текущий экран); токен — `sessionStorage['adminToken']`; - `ApiClient(baseUrl, token)`: GET/POST JSON; 401 → очистка токена, экран логина; все запросы `/api/admin/*` относительно origin. ## 2. Экраны (навигация — NavigationRail слева) 1. **Логин**: логин/пароль → `POST login` → токен в sessionStorage. 2. **Атлеты**: таблица (id, имя, блок, создан); «+ Атлет» — диалог (имя) → показать ключ в диалоге с кнопкой «Скопировать» и предупреждением «показывается один раз»; смена ключа — то же; блокировка — Switch. 3. **Тренировки**: фильтры (атлет-дропдаун, дата с/по), таблица (дата, атлет, мин, ср. пульс, подходы, adherence), пагинация (limit 50); строка → карточка: план/факт по упражнениям, таймлайн подходов (старт/длит./пульс/отдых), пульсограмма (`CustomPaint`, линия по hrCurve); кнопка «CSV» — ссылка `workouts.csv` с текущими фильтрами (+ токен через `?token=` не поддерживается — CSV открывается через fetch c Bearer и Blob-download). 4. **Программы**: выбор атлета → версии (номер, статус, автор, rationale, дата); просмотр body (formatted JSON, сворачиваемое); активация draft (подтверждение); rules-draft — кнопка «Применить предложение» (подтверждение с rationale). 5. **Метрики**: атлет + период; таблица тренировок; недельный график — столбики тоннажа + линия adherence (CustomPaint, значения подписаны текстом). 6. **План/факт**: атлет → сводка недель (запланировано/выполнено/ пропущено, adherence), отклонение цветом + текстом. ## 3. Сборка и хостинг - `flutter build web --release` → `build/web`; - копия в `Server.WatchBody.Web\wwwroot\admin\` (скрипт `build.ps1` в проекте UI); Kestrel отдаёт статику: `/admin` → `index.html` (fallback-маршрут), ассеты — как файлы; - базовый URL API = origin страницы (консоль на том же сервере). ## 4. Проверки - `flutter analyze` — чисто; `flutter build web` — без ошибок; - ручной смок по чек-листу: логин/401-редирект, CRUD атлетов, список/карточка/CSV, активация/применение, метрики, план/факт (данные — тестовые атлеты docker-БД).