Add docker

This commit is contained in:
Evgenii Saenko
2025-12-17 11:51:25 +03:00
parent a01b46182e
commit 4f6700e0e2
110 changed files with 8838 additions and 181 deletions

97
docs/architecture.md Normal file
View File

@@ -0,0 +1,97 @@
# Архитектура клиентского приложения
Документ описывает устройство Reactклиента из `src/` и взаимосвязь его модулей, чтобы упростить навигацию по проекту и подключение новых разработчиков.
## Технологический стек
- **React 19 + TypeScript** — основной UIфреймворк (`src/main.tsx`, `src/app/App.tsx`), компоненты пишутся как функции с хуками.
- **Vite** — сборка, локальный дев‑сервер и предпросмотр (`package.json` скрипты `dev`, `build`, `preview`).
- **React Router v7** — маршрутизация клиентского приложения (`src/app/router/routes.tsx`).
- **MobX + mobx-react-lite** — управление состоянием через сторы и модели (`src/stores/*`), привязка к компонентам через `observer`.
- **Material UI 7** — дизайн‑система и тема (`src/shared/theme`), включает Emotion для стилизации.
- **Zod** — валидация сетевых ответов и входных данных (`src/api/**/*.ts`).
## Организация каталогов
```
src/
├─ app/ # точка входа UI, глобальные маршруты и обёртка приложения
├─ modules/ # фичевые модули (публичный сайт, админка, разделы)
├─ shared/ # переиспользуемые UIкомпоненты, хуки, тема
├─ providers/ # Reactпровайдеры, контексты
├─ stores/ # состояние MobX и доменные модели
├─ api/ # HTTPклиент, DTO и SDK для бэкенда
├─ assets/ # картинки и брендинговые ассеты
├─ index.css # глобальные стили
└─ main.tsx # инициализация Reactприложения
```
`public/` хранит статические файлы Vite, а `docs/` отведён под документацию (включая текущий файл).
## Жизненный цикл приложения
1. `src/main.tsx` монтирует `<App />` в StrictMode.
2. `src/app/App.tsx` собирает корневое дерево: `<StoreProvider>``<AppTheme>``<CssBaseline>``<RouterProvider router={router} />`.
3. `src/app/router/routes.tsx` объявляет все маршруты, разделяя публичные страницы (`/`, `/news`, `/services`, `/about`) и защищённую зону `/admin/dashboard` с вложенными разделами.
Благодаря `<Outlet />` внутри `AdminDashboardLayout` (`src/modules/admin/components/dashboard-layout.tsx`) дочерние страницы админки получают общий chrome (AppBar, Drawer, выход из аккаунта).
## Управление состоянием
- `src/stores/root.tsx` инициализирует `RootStore` с коллекциями новостей, услуг и категорий услуг. Экземпляр передаётся в Reactконтекст через `StoreProvider` (`src/providers/store.tsx`), а хук `useStore` (`src/shared/hooks/useStore.ts`) упрощает доступ к нему.
- Каждый доменный объект описан MobXмоделью (например, `NewsModel` и `ServiceModel`), которая инкапсулирует нормализацию данных, вычисляемые геттеры (`href`) и методы `update` / `toJSON`.
- Коллекции (`NewsCollectionModel`, `ServicesCollectionModel`, `ServiceCategoryCollectionModel`) отвечают за загрузку данных из API, трекинг `isLoading`/`error`, пагинацию и дедупликацию через `Map`.
- В компонентах состояние наблюдается через `observer` (см. `src/modules/main/components/services.tsx`, `src/modules/services/pages/service-details.tsx`, `src/modules/admin/components/news/dashboard-news.tsx`), что гарантирует реактивность без ручных `useState`.
## Сетевой слой и API
- `src/api/httpClient.ts` содержит унифицированный `send` (GET/POST/PUT/DELETE), сборщик queryпараметров и работу с токеном администратора в `localStorage`. Ответы проходят через Zodсхемы, а при ошибках выбрасывается `ApiError`.
- В `src/api/*` реализованы специализированные SDK:
- `newsApi`, `servicesApi`, `leadsApi` — публичные чтения.
- `adminApi` — все CRUDоперации админки (авторизация, категории, услуги, новости, администрирование).
- Типы DTO и схемы (`src/api/**/types.ts`) документируют поля и позволяют IDE/TypeScript подсказывать структуры данных по всему приложению.
## UI-слой и тема
- Тема MUI собирается в `src/shared/theme/theme.tsx`: кастомные `colorSchemes`, `typography`, `shadows` и набор component overrides (`shared/theme/customizations/*`). Цветовая схема подключается через CSSпеременные и переключатель режима (`ColorModeSelect`, `ColorModeIconDropdown`).
- Глобальные стили (`src/index.css`) подключают шрифты и базовые переменные.
- Переиспользуемые шапка и подвал (`src/shared/components/header.tsx`, `src/shared/components/footer.tsx`) формируют каркас публичных страниц.
## Фичевые модули
- **Main (`src/modules/main`)** — лендинг: блоки `Hero`, `Services`, `RecentNews`, `Features`, `Partners`, `Feedback`. Использует сторы для вывода последних услуг и новостей, а `usePageTitle` (`src/shared/hooks/usePageTitle.ts`) обновляет `document.title`.
- **Services (`src/modules/services`)** — список и детальная страница услуг. `ServiceDetailsPage` грузит данные по `slug`, отображает карточку, хлебные крошки и форматирует цену через `formatPrice`.
- **News (`src/modules/news`)** — лента с пагинацией, просмотр новости (`NewsDetailsPage`), утилита форматирования дат `formatDate`.
- **About (`src/modules/about`)** — информационная статическая страница.
- **Admin (`src/modules/admin`)** — полноценная панель управления:
- маршруты `/admin` (логин) и `/admin/dashboard/*`;
- `dashboard-layout` отвечает за адаптивную навигацию;
- разделы: новости, услуги, категории, лиды, администраторы;
- формы создания/редактирования (`components/services/service-form.tsx`, `components/news/news-create-form.tsx`, `components/service-categories/*`) используют MUI `TextField`, локальную валидацию и обращения к `adminApi`.
- раздел лидов (`components/leads/dashboard-leads.tsx`) общается с `leadsApi` напрямую и хранит состояние в локальных хуках, поскольку данных немного.
## Поток данных и валидации
1. Компонент фичи (например, `Services` или `AdminDashboardNews`) вызывает методы стора (`services.fetch`, `news.fetchAdmin`).
2. Стор делегирует запрос соответствующему SDK (`servicesApi`, `adminApi`) и обновляет MobXмодели.
3. Компоненты, обёрнутые в `observer`, автоматически перерисовываются и показывают лоадеры/ошибки.
4. Формы в админке валидируют ввод на клиенте, а серверные ошибки ловятся как `ApiError` и выводятся в UI.
Такая цепочка (компонент → стор → API → стор → компонент) делает логику прозрачной и облегчает внедрение новых сущностей.
## Ассеты и стили
- Брендовые изображения и логотипы лежат в `src/assets` и импортируются напрямую в компоненты (например, хедер использует `src/assets/logo.png`).
- Файлы в `public/` доступны по прямым URL и могут использоваться для метатегов или фавиконок.
- Изображения партнёров (`src/assets/partners`) подключаются только внутри лендинга, что упрощает tree-shaking.
## Расширение проекта
Чтобы добавить новую сущность:
1. Создайте Zodсхемы и APIклиент в `src/api/<entity>`.
2. Опишите MobXмодель + коллекцию в `src/stores/<entity>`, инициализируйте её в `RootStore`.
3. Подготовьте UI в отдельном модуле внутри `src/modules/<entity>` и подключите маршруты через `src/app/router/routes.tsx`.
4. При необходимости добавьте переиспользуемые компоненты/хуки в `src/shared`.
Следование существующим паттернам гарантирует единообразие и упрощает поддержку сервиса.