79 lines
6.9 KiB
Markdown
79 lines
6.9 KiB
Markdown
# Active Context — Strava Frontend
|
||
|
||
## Task State
|
||
|
||
- task_id: TASK-MCP-SETUP
|
||
- status: success
|
||
- parent_task: —
|
||
- summary: **Настроить Playwright MCP для UI-верификации через браузер. Конфиг Zoo Code обновлён (Node 22), Chromium установлен.**
|
||
- next task: —
|
||
|
||
## TASK-MCP-SETUP: Playwright MCP configuration
|
||
|
||
**Что сделано:**
|
||
- MCP-конфиг Zoo Code (`mcp_settings.json`): server `web-browser` → `@playwright/mcp@latest`, Node 22 via nvm absolute path, `--headless`
|
||
- Chromium `1234` уже установлен в `~/.cache/ms-playwright/`
|
||
- `.mcp.json` создан в проекте (project-level, для совместимости)
|
||
- `techContext.md` обновлён: секция "UI Verification (MCP Browser)"
|
||
|
||
**Как использовать (workflow):**
|
||
1. `yarn dev` — запустить dev server (порт 5173)
|
||
2. `browser_navigate` → `http://localhost:5173/explore` — проверить публичную страницу
|
||
3. `browser_evaluate` → `() => { localStorage.setItem('token', 'test'); localStorage.setItem('user', JSON.stringify({id:1,name:'Test'})); location.reload(); }` — сымитировать auth
|
||
4. `browser_navigate` → проверить auth-страницы (`/workouts`, `/workouts/:id`)
|
||
5. `browser_snapshot` — проверить DOM-структуру
|
||
6. `browser_take_screenshot` — визуальная проверка
|
||
7. `browser_network_requests` — проверить API-запросы
|
||
|
||
### Баг (контекст)
|
||
|
||
Сайдбар показывает `publicRoutes` (Лента + Маршрут) после логина до F5. Корень: [`NavigationRoutes.ts:70`](src/components/sidebar/NavigationRoutes.ts:70) — `routes` вычисляется один раз при module evaluation и кэшируется. TASK-AUTH-NAV-1 уже добавил реактивный `isAuthenticated` в `useGlobalStore` (инициализация из localStorage + `setAuthenticated` в Login/Logout). Эта задача переключает UI на computed.
|
||
|
||
### TASK-AUTH-NAV-2: реактивные маршруты (3 файла)
|
||
|
||
**1. `src/components/sidebar/NavigationRoutes.ts`**
|
||
|
||
- Сделать named exports: `export const authRoutes: INavigationRoute[]` и `export const publicRoutes: INavigationRoute[]` (сейчас это локальные `const`, не экспортированные).
|
||
- Убрать статическое поле `routes` из default export (или оставить default без `routes`, т.к. оба потребителя перейдут на computed). `INavigationRoute` интерфейс — не трогать.
|
||
- Важно: массивы `authRoutes`/`publicRoutes` остаются теми же по структуре/содержимому — только экспортируются.
|
||
|
||
**2. `src/components/sidebar/AppSidebar.vue`** (Options API, `setup()`)
|
||
|
||
- `import { useGlobalStore } from "../../stores/global-store";` + `import { authRoutes, publicRoutes } from "./NavigationRoutes";` (импорт `navigationRoutes` по default можно оставить/убрать — но все обращения `navigationRoutes.routes` заменить).
|
||
- В `setup()`: `const globalStore = useGlobalStore();`
|
||
- computed: `const routes = computed(() => globalStore.isAuthenticated ? authRoutes : publicRoutes);`
|
||
- В `return` заменить `navigationRoutes` на `routes` (тепловой шаблон уже использует `navigationRoutes.routes` → поправить на `routes.value`? НЕТ — в Options API computed из setup доступно в шаблоне как `routes` без `.value`, т.е. в шаблоне `navigationRoutes.routes` → `routes`).
|
||
- `setActiveExpand`: `navigationRoutes.routes.map(...)` → `routes.value.map(...)` (в setup `.value` нужен).
|
||
- Шаблоны: `v-for="(route, index) in navigationRoutes.routes"` → `in routes`.
|
||
|
||
**3. `src/components/app-layout-navigation/AppLayoutNavigation.vue`** (script setup)
|
||
|
||
- `import { authRoutes, publicRoutes } from "../sidebar/NavigationRoutes";` + `import { useGlobalStore } from "../../stores/global-store";`
|
||
- `const globalStore = useGlobalStore();`
|
||
- `findRouteName` (строка ~64): `traverse(NavigationRoutes.routes)` → `traverse(globalStore.isAuthenticated ? authRoutes : publicRoutes)`.
|
||
- Убедиться, что `items` computed (зависит от `route.matched` и `findRouteName`) остаётся реактивным — т.к. `findRouteName` читает `globalStore.isAuthenticated` внутри `items` computed, реactivity сохранится.
|
||
|
||
### Acceptance Criteria (TASK-AUTH-NAV-2)
|
||
|
||
1. `yarn lint` → 0 ошибок.
|
||
2. `yarn build` → 0 ошибок (vue-tsc --noEmit).
|
||
3. `NavigationRoutes.ts`: `authRoutes` и `publicRoutes` экспортируются; статического `routes` с localStorage-тернарником больше нет.
|
||
4. `AppSidebar.vue`: routes = computed от `globalStore.isAuthenticated`; `setActiveExpand` использует `routes.value`.
|
||
5. `AppLayoutNavigation.vue`: `traverse` использует выбор по `globalStore.isAuthenticated`.
|
||
6. **Ручной сценарий (ключевой)**: без F5 — выход из профиля → `/explore` → логин → сайдбар **сразу** показывает «Мои тренировки» (authRoutes). Аут → сайдбар сразу `publicRoutes`.
|
||
|
||
## ✅ CODER SUCCESS REPORT — TASK-AUTH-NAV-2
|
||
|
||
- `src/components/sidebar/NavigationRoutes.ts`: `export const authRoutes` / `export const publicRoutes`; удалён статический `routes: localStorage.getItem("token") ? ...` из default export (оставлен только `root`).
|
||
- `src/components/sidebar/AppSidebar.vue`: импорт `authRoutes, publicRoutes` + `useGlobalStore`; `computed(() => globalStore.isAuthenticated ? authRoutes : publicRoutes)`; `setActiveExpand` использует `routes.value.map`; шаблон `v-for="(route, index) in routes"`.
|
||
- `src/components/app-layout-navigation/AppLayoutNavigation.vue`: `const globalStore = useGlobalStore()`; `traverse(globalStore.isAuthenticated ? authRoutes : publicRoutes)` внутри `findRouteName` (вызывается в `items` computed → реactivity сохранена).
|
||
- Verified: `yarn lint` exit 0, `yarn build` exit 0 (vue-tsc --noEmit 0 ошибок, vite ✓ 7.07s).
|
||
|
||
## История (закрытые задачи)
|
||
|
||
- **TASK-AUTH-NAV-1**: success — `isAuthenticated` + `setAuthenticated` в `useGlobalStore`; Login `setAuthenticated(true)`, Logout `setAuthenticated(false)`. Verified lint/build 0.
|
||
- TASK-SSR-DETAIL: success — SSR /public/workouts/:id под DOM WorkoutItem.vue.
|
||
- TASK-404: success — HTTP 404 для неизвестных страниц.
|
||
- TASK-PUBLIC-ROUTE-FIX: success — workout_public_item в top-level router.
|
||
- TASK-F11/F12/F13/F14: success — SEO + фиксы карты тренировки.
|