feat(frontend): race form, start time selects, calendar views, day page
Some checks failed
CI / build-and-test (pull_request) Has been cancelled

- Hide org schedule fields when editing a past race; isRaceDateInPast helper
- StartTimeSelects (HH:mm:ss) and optional ?date= prefill on new race
- Full-card link to edit for races needing result entry; shadow token
- List/calendar toggle (sessionStorage); year grid and month focus views
- Date hover popover and /races/day/:ymd page with Add button
- Docs plan-korrektirovok-starty.md and startTime API note; client 0.4.0

Made-with: Cursor
This commit is contained in:
Vaka.pro
2026-04-13 22:07:37 +03:00
parent b997dcb01e
commit 3c6baa66a1
16 changed files with 1193 additions and 69 deletions

View File

@@ -207,7 +207,7 @@ GET /api/races?year=2026&month=5
| `distanceKm` | number | да | да | Дистанция в км |
| `status` | string \| null | нет | да | `"planned"` / `"registered"` / `"completed"` |
| `officialUrl` | string \| null | нет | да | URL организатора |
| `startTime` | string \| null | нет | да | Время старта, напр. `"09:30"` |
| `startTime` | string \| null | нет | да | Время старта, напр. `"09:30"` или `"09:30:00"` (часы:минуты:секунды) |
| `clusterSchedule` | string \| null | нет | да | Расписание кластеров |
| `bibPickup` | string \| null | нет | да | Выдача номеров |
| `bibNumber` | string \| null | нет | да | Стартовый номер |

View File

@@ -0,0 +1,52 @@
# План корректировок: форма старта, время, календарь стартов
Краткое описание реализованных изменений в клиенте **runners-calendar** (версия клиента см. в футере приложения).
## 1. Форма старта (редактирование прошедшего события)
При **редактировании** старта, чья **дата уже в прошлом**, в блоке «Организация» скрыты поля, неактуальные после забега:
- сайт организатора;
- время старта;
- расписание кластеров;
- выдача номеров.
Значения по-прежнему хранятся в состоянии формы и отправляются при сохранении (не затираются). Утилита: `isRaceDateInPast` в `frontend/src/lib/raceMetrics.ts`.
## 2. Время старта
Вместо свободного текста — три селекта (часы, минуты, секунды), компонент `StartTimeSelects` в `frontend/src/components/StartTimeSelects.tsx`. Сохраняется строка `HH:mm:ss` или пусто → `null` в API. Поддерживается разбор старых значений `HH:mm` при загрузке.
## 3. Список на странице «Календарь стартов»
Для стартов со статусом **«внесите результат»** вся карточка — ссылка на `/races/:id/edit` с лёгким увеличением и тенью при наведении/фокусе (токен `--shadow-card-lift`).
## 4. Виды: список и календарь
- Переключатель **Список / Календарь**, выбор сохраняется в `sessionStorage` (`races-view-mode`).
- **Календарь:** загрузка гонок за выбранный **год** (без фильтра месяца в запросе), отображение сетки месяцев.
- При выборе **месяца** в фильтре — крупная сетка этого месяца и компактная навигация по остальным месяцам + «Весь год».
## 5. Ячейка даты в календаре
- Наведение или фокус: всплывающая панель — либо «Стартов нет» и кнопка **Добавить** (`/races/new?date=YYYY-MM-DD`), либо список стартов со ссылками на карточки и **Добавить**.
- Клик по числу — страница дня `/races/day/:ymd`.
## 6. Страница дня
Маршрут `races/day/:ymd`: список стартов на дату, пустое состояние, кнопка **Добавить** с предзаполнением даты через query.
## 7. Новый старт с датой из календаря
`RaceFormPage` читает query-параметр `?date=YYYY-MM-DD` при создании старта.
## Основные файлы
| Область | Файлы |
|--------|--------|
| Метрики даты | `frontend/src/lib/raceMetrics.ts`, `frontend/src/lib/calendarUtils.ts` |
| Форма | `frontend/src/pages/RaceFormPage.tsx`, `frontend/src/components/StartTimeSelects.tsx` |
| Список и календарь | `frontend/src/pages/RacesPage.tsx`, `frontend/src/components/RacesCalendar.tsx` |
| День | `frontend/src/pages/RaceDayPage.tsx`, `frontend/src/app/router.tsx` |
| Стили | `frontend/src/styles/global.css`, `frontend/src/styles/tokens.css` |
| API-док | `docs/backend-api-for-frontend.md` (формат `startTime`) |