# Архитектура клиентского приложения Документ описывает устройство 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`. Следование существующим паттернам гарантирует единообразие и упрощает поддержку сервиса.