fix: phase 1 bugs — CSS tokens, pluralization, error handling, cross-platform tests
Some checks failed
CI / build-and-test (pull_request) Has been cancelled
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
This commit is contained in:
102
FRONTEND_PLAN.md
Normal file
102
FRONTEND_PLAN.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user