Docs: sync Front#39 Mood chip + Lens strip. Fixes EventHub/EventHubSpec#16
Refs EventHub/EventHubFront#39 (c2cb754 / d38a927).
This commit is contained in:
+26
-10
@@ -38,7 +38,7 @@ Deep-link на календарь, владельцем которого явл
|
||||
- Сборщик: Vite
|
||||
- UI: React 19 + Tailwind CSS 4 + shadcn/Radix
|
||||
- Типографика: Syne (display) + Manrope (UI)
|
||||
- Состояние: Zustand (auth + mood + calendar context), TanStack React Query v5 (сервер)
|
||||
- Состояние: Zustand (auth + mood + lens + calendar context), TanStack React Query v5 (сервер)
|
||||
- HTTP: Axios с интерсепторами
|
||||
- Формы: React Hook Form + Zod
|
||||
- Дата/время: dayjs (ru locale)
|
||||
@@ -55,8 +55,14 @@ Deep-link на календарь, владельцем которого явл
|
||||
и «Мои записи» (participant); пустые группы скрывать. Confirm на карточке события остаётся.
|
||||
Past/expired: бейдж `expired` («истекла»), Cancel скрыт; empty-state с CTA Discover / календари.
|
||||
Время на list-карточках — вторичное к title (`.eh-book-list-time`).
|
||||
- В **Ещё**: пункт входящих specialist invites скрыт при `pending=0`; при `pending > 0` —
|
||||
badge со счётчиком (deep-link `/invites` работает).
|
||||
- В **Ещё**: язык (`LanguageSwitcher`); пункт входящих specialist invites скрыт при
|
||||
`pending=0`; при `pending > 0` — badge со счётчиком (deep-link `/invites` работает).
|
||||
**Mood в Ещё нет** — только chip в chrome workspace календаря (Front#39).
|
||||
- **Mood + Lens (workspace, Front#39):** в chrome календаря — mood chip (FLOW/MOMENTUM/
|
||||
CONTROL → sheet picker); отдельно lens «Обзор / Сегодня / Записи» (desktop segment /
|
||||
mobile sheet); над сеткой — collapsible lens strip (Front-only derive из уже
|
||||
загруженных events/bookings). Без flip календаря; без 4-го CREATOR. Strip по
|
||||
умолчанию раскрыт на desktop, свёрнут на mobile. Нет на HTML-архиве месяца.
|
||||
- Контекст виджета: свой календарь (селектор) или чужой (browse после поиска). Чужой `personal` —
|
||||
только просмотр; чужой `commercial` с `booking_open=true` — запись; при `booking_open=false`
|
||||
(restricted / нет подписки владельца) — просмотр + сообщение «Запись временно недоступна».
|
||||
@@ -89,7 +95,7 @@ Deep-link на календарь, владельцем которого явл
|
||||
|
||||
## 3.2. Настроения (mood themes) / режимы CalenTIQ
|
||||
|
||||
Публичный бренд UI: **CalenTIQ** (см. [BRANDING.md](BRANDING.md)). Внутренние ключи API/preferences без изменений.
|
||||
Публичный бренд UI: **CalenTIQ** (см. [BRANDING.md](BRANDING.md)). Внутренние ключи API/preferences без изменений. Три mood только — **без CREATOR**, без flip календаря.
|
||||
|
||||
Пользователь переключает визуальный режим; атрибут `html[data-mood]`. Для гостя и при отсутствии `preferences.mood` — дефолт `calm` (в профиль при логине не пишется). После входа смена mood сохраняется в `preferences.mood` через `PATCH /v1/user/me`.
|
||||
|
||||
@@ -99,9 +105,19 @@ Deep-link на календарь, владельцем которого явл
|
||||
| MOMENTUM | `energetic` | тёмный ink + coral `#FF6A3D` |
|
||||
| CONTROL | `business` | charcoal + steel `#324A5F`, более жёсткие радиусы |
|
||||
|
||||
Переключатели mood и языка: на экранах auth (`/login`, `/register`, `/verify`) и в `/more`. В шапке workspace — wordmark CalenTIQ (Time Arc), **nickname** (не raw email) и выход (без mood/lang). Desktop chrome — одна строка: logo | nav | logout.
|
||||
**Где mood:**
|
||||
- Auth (`/login`, `/register`, `/verify`, forgot/reset) — compact `MoodSwitcher` (+ language).
|
||||
- Calendar workspace — primary control: **mood chip** → dialog/sheet (не в `/more`).
|
||||
- App shell header — wordmark + nickname + logout (**без** mood/lang). Desktop: logo \| nav \| logout.
|
||||
|
||||
Язык UI (`ru`/`en`): до логина — `navigator.language`; после входа — поле `language` профиля (`PATCH /v1/user/me`). Если в профиле язык пуст — при логине записывается текущий (браузерный/выбранный на экране входа). Язык также можно сменить в форме `/profile`.
|
||||
**Lens** (отдельно от mood и от view month/week/day): `overview` / `today` / `bookings`
|
||||
(UI: Обзор / Сегодня / Записи). Persist только `localStorage` (`eh.calendar.lens` +
|
||||
`eh.calendar.lens.pinned`); **не** поле профиля / Back API. Soft-default при смене mood,
|
||||
если lens не pinned пользователем: FLOW→overview, MOMENTUM→today, CONTROL→bookings.
|
||||
Strip над сеткой: free gaps сегодня / события сегодня / upcoming bookings (derive
|
||||
на клиенте из уже загруженных данных).
|
||||
|
||||
Язык UI (`ru`/`en`): до логина — `navigator.language`; после входа — поле `language` профиля (`PATCH /v1/user/me`). Если в профиле язык пуст — при логине записывается текущий (браузерный/выбранный на экране входа). Язык также в `/more` и в форме `/profile`.
|
||||
|
||||
## 4. Маршруты
|
||||
|
||||
@@ -116,8 +132,8 @@ Deep-link на календарь, владельцем которого явл
|
||||
- `/bookings` — grouped inbox: (A) к подтверждению (owner/specialist pending) +
|
||||
(B) мои записи участника; deep-link в `/c/.../e/...`
|
||||
- `/calendars` — управление своими календарями (CRUD)
|
||||
- `/more` — вторичное меню + mood switcher; пункт specialist invites **скрыт**,
|
||||
если входящих pending = 0; при pending > 0 — badge со счётчиком
|
||||
- `/more` — вторичное меню + language switcher (**без** mood); пункт specialist
|
||||
invites **скрыт**, если входящих pending = 0; при pending > 0 — badge со счётчиком
|
||||
(deep-link `/invites?token=` работает)
|
||||
- `/invites` — inbox входящих specialist invites (не смешивать с `/bookings`)
|
||||
- `/following` — отслеживаемые чужие календари (follow; не платная Подписка)
|
||||
@@ -125,7 +141,7 @@ Deep-link на календарь, владельцем которого явл
|
||||
|
||||
Redirects: `/discover` → `/search`; `/calendars/:id` → `/c/:id`; `/calendars/:id/events/:eventId` → `/c/:id/e/:eventId`.
|
||||
|
||||
Состояние вида: Zustand `calendarContextStore` (`view`, `cursorDate`, last own `calendarId` в `localStorage`).
|
||||
Состояние вида: Zustand `calendarContextStore` (`view`, `cursorDate`, last own `calendarId` в `localStorage`); lens — `lensStore` + `localStorage` (см. §3.2).
|
||||
|
||||
## 5. Модули
|
||||
|
||||
@@ -133,7 +149,7 @@ Redirects: `/discover` → `/search`; `/calendars/:id` → `/c/:id`; `/calendars
|
||||
Регистрация, верификация, вход, восстановление сессии.
|
||||
|
||||
### 5.2. Профиль
|
||||
`GET /v1/user/me` + форма на `/profile`. Редактируемые через `PATCH /v1/user/me`: `nickname`, `phone`, `timezone`, `avatar_url`, `language`; смена пароля — `current_password` + `password`. Read-only в UI: `id`, `email`, `role`, `status`. Mood — отдельно в `/more` (`preferences.mood`). Язык при первом визите — из браузера; при первом логине без `language` — пишется в профиль. Mood по умолчанию `calm`, при логине не сидится.
|
||||
`GET /v1/user/me` + форма на `/profile`. Редактируемые через `PATCH /v1/user/me`: `nickname`, `phone`, `timezone`, `avatar_url`, `language`; смена пароля — `current_password` + `password`. Read-only в UI: `id`, `email`, `role`, `status`. Mood — chip в calendar workspace (+ compact на auth); persist `preferences.mood` через `PATCH /v1/user/me` (**не** в `/more`). Язык при первом визите — из браузера; при первом логине без `language` — пишется в профиль. Mood по умолчанию `calm`, при логине не сидится. Lens — только localStorage (не профиль).
|
||||
|
||||
### 5.3. Поиск (участник)
|
||||
`GET /v1/search` — фильтры (`type`, `q`, `tags`, даты, `lat`/`lon`/`radius`, sort, order, пагинация). Без `q`/дат/tags/geo/sort — топы календарей и событий; иначе — поиск. В списке бейдж типа — `calendar`|`event` (не `personal`/`commercial`). Даты, теги, geo и сортировка свёрнуты по умолчанию. Переход к `/c/:id` или `/c/:id/e/:eventId`.
|
||||
|
||||
Reference in New Issue
Block a user