Some checks failed
CI / build-and-test (pull_request) Has been cancelled
- Add missing --space-1 CSS token used by filter and detail components - Fix active nav link losing styles on hover (CSS specificity) - Correct Russian day pluralization (21 день, 22 дня, 25 дней) - Show filter error banner even when stale race data is present - Add cross-env for Windows-compatible npm test - Add global JSON error handler in Express for malformed request bodies - Replace stateless mock DB with in-memory store for correct DELETE/UPDATE behavior Made-with: Cursor
102 lines
8.0 KiB
Markdown
102 lines
8.0 KiB
Markdown
---
|
||
|
||
name: Frontend implementation plan
|
||
overview: Собрать минималистичный frontend для календаря забегов по UI-инструкции, строго в рамках текущего API-контракта, с отдельной внешней задачей на недостающие backend-поля для completed-забегов.
|
||
todos:
|
||
|
||
- id: frontend-structure
|
||
content: Подготовить структуру frontend, роутинг, базовые layout-компоненты и дизайн-токены на CSS variables + BEM
|
||
status: completed
|
||
- id: api-contract-layer
|
||
content: Реализовать типизированный API-клиент и слой нормализации/обработки ошибок по контракту backend-api-for-frontend.md
|
||
status: completed
|
||
- id: dashboard-and-calendar
|
||
content: Собрать Dashboard, списки будущих/прошедших стартов и базовые карточки по минималистичному UI-гайду
|
||
status: completed
|
||
- id: race-details-and-metrics
|
||
content: Реализовать экран карточки старта, вычисление темпа на фронте и отображение completed-метрик
|
||
status: completed
|
||
- id: pr-and-comparison
|
||
content: Сделать блок PR и сравнение стартов с fallback для отсутствующего поля place
|
||
status: completed
|
||
- id: backend-dependency-task
|
||
content: Подготовить отдельную задачу для другого агента на расширение API полем place и последующую интеграцию во frontend
|
||
status: pending
|
||
isProject: false
|
||
|
||
---
|
||
|
||
# План frontend части Calendar Run
|
||
|
||
## Исходные опоры
|
||
|
||
- UI и UX принципы берём строго из [d:\vaka.pro\calendar_run\agent-frontend-ui-instructions.md](d:/vaka.pro/calendar_run/agent-frontend-ui-instructions.md): минимализм, воздух, акцент на данных, спокойная палитра, быстрые сценарии.
|
||
- Продуктовые ограничения и структура экранов сверяем с [d:\vaka.pro\calendar_run\PLAN.md](d:/vaka.pro/calendar_run/PLAN.md).
|
||
- Интеграционный контракт берём из [d:\vaka.pro\calendar_run\docs\backend-api-for-frontend.md](d:/vaka.pro/calendar_run/docs/backend-api-for-frontend.md).
|
||
- Общий контекст запуска/окружения — [d:\vaka.pro\calendar_run\README.md](d:/vaka.pro/calendar_run/README.md) и [d:\vaka.pro\calendar_run\docs\backend.md](d:/vaka.pro/calendar_run/docs/backend.md).
|
||
|
||
## Границы версии (V1)
|
||
|
||
- Только frontend + интеграция с текущим API.
|
||
- Статус `зарегистрирован` трактуется как UI-вариант `planned` (без изменения backend-контракта).
|
||
- Для completed-забегов обязательно показываем `темп`; считаем на фронте из `finishTime` и `distanceKm`.
|
||
- Для completed-забегов поле `место` обязательно по UX, но в API отсутствует: выделяем отдельную задачу другому агенту на расширение backend (`place`) и считаем это внешней зависимостью.
|
||
|
||
## Архитектура frontend
|
||
|
||
- Базовая структура: `frontend/src/app`, `frontend/src/pages`, `frontend/src/components`, `frontend/src/api`, `frontend/src/features`, `frontend/src/lib`, `frontend/src/styles`.
|
||
- Дизайн-система на CSS variables: токены цвета/типографики/отступов/радиусов, единые состояния (`success`, `warning`, `error`).
|
||
- БЭМ для всех UI-блоков и модификаторов (`block`, `block__element`, `block--modifier`).
|
||
- Единый слой API-клиента:
|
||
- `GET /races`, `GET /races/:id`, `POST /races`, `PATCH /races/:id`, `DELETE /races/:id` (если используется UI-сценарием).
|
||
- Типы `Race`, `RaceStatus`, DTO для POST/PATCH.
|
||
- Централизованный маппинг ошибок API (`validation_error`, `not_found`, `database_unavailable`, `conflict`) в UX-сообщения.
|
||
|
||
## Экранная модель и сценарии
|
||
|
||
- Dashboard:
|
||
- `Ближайший старт`, `Последний результат`, `Личный рекорд`, `Сезон`.
|
||
- CTA к календарю и добавлению старта.
|
||
- Календарь стартов:
|
||
- Переключение `Будущие` / `Прошедшие`.
|
||
- Карточка старта: `title`, `date`, `distanceKm`, статус-лейбл.
|
||
- Карточка старта:
|
||
- Базовые поля + `finishTime`, вычисляемый `pace`, `notes`.
|
||
- `place` — вывод включается после backend-расширения.
|
||
- PR блок:
|
||
- Дистанции: 5K, 10K, 21.1, 42.2 (согласно UI-инструкции).
|
||
- Расчёт по completed-забегам с валидным `finishTime`.
|
||
- Сравнение стартов (ключевая фича):
|
||
- Таблица/карточки по годам с `time`, `pace`, `place`.
|
||
- До появления `place` в API — graceful-degradation: колонка в состоянии «нет данных».
|
||
|
||
## UX и визуальные требования
|
||
|
||
- Визуальная система: светлый фон, белые карточки, один акцентный цвет, без кислотных сочетаний.
|
||
- Иерархия типографики: H1/H2/body/caption, крупные числовые метрики.
|
||
- Минимум визуального шума, 2–3 клика на частые действия.
|
||
- Консистентные состояния загрузки/ошибок/пустых данных.
|
||
- A11y-базис: фокус-стили, клавиатурная навигация, контраст, корректная разметка интерактивных элементов.
|
||
|
||
## Отдельная зависимая задача (другой агент)
|
||
|
||
- Создать отдельную backend-задачу: добавить поле `place` в модель `Race` (миграция + API + документация контракта).
|
||
- После доставки backend-изменения: обновить frontend-типы, формы и блок сравнения, заменить placeholder на реальное значение.
|
||
|
||
## Порядок реализации
|
||
|
||
1. Подготовить каркас frontend и дизайн-токены (BEM + CSS variables).
|
||
2. Реализовать API-клиент и типы данных с обработкой ошибок.
|
||
3. Собрать Dashboard и календарные списки (будущие/прошедшие).
|
||
4. Реализовать карточку старта с вычислением `pace` на клиенте.
|
||
5. Реализовать PR и блок сравнения стартов с fallback для `place`.
|
||
6. Добавить состояния пустых данных/ошибок/загрузки и а11y-полировку.
|
||
7. Подготовить handoff-note с зависимостью на backend-задачу (`place`) и интеграционным чеклистом.
|
||
|
||
## Definition of Done для frontend
|
||
|
||
- Все ключевые экраны из UI-инструкции доступны и консистентны визуально.
|
||
- API-интеграция работает по текущему контракту без локальных обходов хранилища.
|
||
- `pace` считается корректно для completed-забегов.
|
||
- `registered` не ломает модель: визуально интерпретируется в рамках `planned`.
|
||
- Для `place` есть явная внешняя задача и безопасный fallback в UI. |