# Архитектура клиентского приложения
Документ описывает устройство 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` монтирует `` в StrictMode.
2. `src/app/App.tsx` собирает корневое дерево: `` → `` → `` → ``.
3. `src/app/router/routes.tsx` объявляет все маршруты, разделяя публичные страницы (`/`, `/news`, `/services`, `/about`) и защищённую зону `/admin/dashboard` с вложенными разделами.
Благодаря `` внутри `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/`.
2. Опишите MobX‑модель + коллекцию в `src/stores/`, инициализируйте её в `RootStore`.
3. Подготовьте UI в отдельном модуле внутри `src/modules/` и подключите маршруты через `src/app/router/routes.tsx`.
4. При необходимости добавьте переиспользуемые компоненты/хуки в `src/shared`.
Следование существующим паттернам гарантирует единообразие и упрощает поддержку сервиса.