|
@@ -0,0 +1,88 @@
|
|
|
|
|
+## MOC: Фронтенд-паттерны и компоненты PhotoPlaces
|
|
|
|
|
+
|
|
|
|
|
+### Архитектура фронтенда
|
|
|
|
|
+
|
|
|
|
|
+```mermaid
|
|
|
|
|
+graph TB
|
|
|
|
|
+ Next[Next.js 14 App Router] --> Pages[Pages]
|
|
|
|
|
+ Next --> Components[Shared Components]
|
|
|
|
|
+ Next --> Hooks[Custom Hooks]
|
|
|
|
|
+ Components --> Modal[Modal]
|
|
|
|
|
+ Components --> MapView[MapView + Leaflet]
|
|
|
|
|
+ Components --> PlaceForm[PlaceForm]
|
|
|
|
|
+ Hooks --> useAuth[AuthProvider + Context]
|
|
|
|
|
+ Hooks --> useWebSocket[WebSocket]
|
|
|
|
|
+ Pages --> API[api.ts: fetch wrapper]
|
|
|
|
|
+ API --> Auth[Auto-refresh 401]
|
|
|
|
|
+ API --> Backend[Go API :8080]
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### Ключевые компоненты
|
|
|
|
|
+
|
|
|
|
|
+| Компонент | Файл | Назначение |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| Modal (общий) | `components/Modal.tsx` | Переиспользуемая модалка, скроллбар внутри контента |
|
|
|
|
|
+| MapView | `components/MapView.tsx` | Карта Leaflet + PlaceCardModal |
|
|
|
|
|
+| PlaceForm | `components/PlaceForm.tsx` | Форма места / студии / услуги |
|
|
|
|
|
+| PlaceCardModal | `MapView.tsx` (встроен) | Bottom-panel карточка места |
|
|
|
|
|
+| LoginModal | `components/LoginModal.tsx` | Форма входа |
|
|
|
|
|
+| RegisterModal | `components/RegisterModal.tsx` | Форма регистрации |
|
|
|
|
|
+| AddLocationModal | `components/AddLocationModal.tsx` | Добавление места |
|
|
|
|
|
+| ErrorBoundary | `components/ErrorBoundary.tsx` | Отлов ошибок рендера |
|
|
|
|
|
+| ErrorReporter | `components/ErrorReporter.tsx` | Панель ошибок (debug) |
|
|
|
|
|
+| MapPicker | `components/MapPicker.tsx` | Полноэкранный выбор координат |
|
|
|
|
|
+| Header | `components/Header.tsx` | Навигация |
|
|
|
|
|
+
|
|
|
|
|
+### Паттерны
|
|
|
|
|
+
|
|
|
|
|
+| Паттерн | Где | Заметка |
|
|
|
|
|
+|---|---|---|
|
|
|
|
|
+| **Shared Modal** с `overflow-y-auto` внутри | `components/Modal.tsx` | [[atomic-modal-scrollbar-inside]] |
|
|
|
|
|
+| Ad-hoc модалки → общий компонент (DRY) | decision record | [[decision-modal-component-extraction]] |
|
|
|
|
|
+| Auth через Context + custom hook | `hooks/useAuth.tsx` | [[frontend-api-client]] |
|
|
|
|
|
+| Ghost markers для гостей | `MapView.tsx:82-83` | [[atomic-ghost-markers]] |
|
|
|
|
|
+| Diff-обновление маркеров (markerIdsRef) | `MapView.tsx:70-87` | [[architecture-overview]] |
|
|
|
|
|
+| API client с auto-refresh токена | `lib/api.ts` | [[frontend-api-client]] |
|
|
|
|
|
+| Error suppression (антипаттерн) | `PlaceForm.tsx:42-43` | [[atomic-error-swallowing-frontend]] |
|
|
|
|
|
+| Fetch retry infinite loop (антипаттерн) | `lib/api.ts:87` | [[atomic-fetch-retry-infinite-loop]] |
|
|
|
|
|
+| Координаты [lat,lng] консистентность | `lib/map.ts` | [[atomic-map-coordinates-inconsistency]] |
|
|
|
|
|
+
|
|
|
|
|
+### Стек
|
|
|
|
|
+
|
|
|
|
|
+- **Фреймворк**: Next.js 14 App Router
|
|
|
|
|
+- **Стили**: Tailwind CSS (без CSS-модулей)
|
|
|
|
|
+- **Карты**: Leaflet + OSM dark tiles
|
|
|
|
|
+- **Состояние**: React Context (AuthProvider)
|
|
|
|
|
+- **API**: Custom fetch wrapper (`lib/api.ts`)
|
|
|
|
|
+- **Тесты**: Vitest + @testing-library/react
|
|
|
|
|
+
|
|
|
|
|
+### Code style
|
|
|
|
|
+
|
|
|
|
|
+- Все компоненты — `'use client'` (прямые функции, не классы)
|
|
|
|
|
+- Нет выделенных CSS/SCSS-файлов — только Tailwind utility классы в JSX
|
|
|
|
|
+- Импорты: `@/` алиас → `./src/`
|
|
|
|
|
+- Комментарии на русском языке
|
|
|
|
|
+- Нет сторонних UI-библиотек (MUI, Radix, Headless UI)
|
|
|
|
|
+
|
|
|
|
|
+### Антипаттерны (исправленные)
|
|
|
|
|
+
|
|
|
|
|
+| Проблема | Заметка |
|
|
|
|
|
+|---|---|
|
|
|
|
|
+| 7 ad-hoc модалок | [[atomic-modal-scrollbar-inside]] |
|
|
|
|
|
+| Подавление ошибок | [[atomic-error-swallowing-frontend]] |
|
|
|
|
|
+| Retry loop на /auth/logout | [[atomic-fetch-retry-infinite-loop]] |
|
|
|
|
|
+| Ghost markers — стиль разный от logged-in | [[atomic-ghost-markers]] |
|
|
|
|
|
+| Типы не синхронизированы с backend | [[atomic-frontend-types-backend-sync]] |
|
|
|
|
|
+
|
|
|
|
|
+### Связанные заметки
|
|
|
|
|
+
|
|
|
|
|
+- [[architecture-overview]] — общий обзор
|
|
|
|
|
+- [[frontend-api-client]] — API client и auth flow
|
|
|
|
|
+- [[atomic-modal-scrollbar-inside]] — модалка со скроллбаром
|
|
|
|
|
+- [[decision-modal-component-extraction]] — решение об извлечении Modal
|
|
|
|
|
+- [[atomic-error-swallowing-frontend]] — подавление ошибок
|
|
|
|
|
+- [[atomic-ghost-markers]] — ghost-маркеры на карте
|
|
|
|
|
+- [[MOC-backend-patterns]] — бэкенд-паттерны
|
|
|
|
|
+- [[MOC-security-patterns]] — безопасность
|
|
|
|
|
+
|
|
|
|
|
+#frontend #react #nextjs #MOC #best-practice #components
|