10 KiB
10 KiB
Архитектура клиентского приложения
Документ описывает устройство 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/ отведён под документацию (включая текущий файл).
Жизненный цикл приложения
src/main.tsxмонтирует<App />в StrictMode.src/app/App.tsxсобирает корневое дерево:<StoreProvider>→<AppTheme>→<CssBaseline>→<RouterProvider router={router} />.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/*) используют MUITextField, локальную валидацию и обращения кadminApi. - раздел лидов (
components/leads/dashboard-leads.tsx) общается сleadsApiнапрямую и хранит состояние в локальных хуках, поскольку данных немного.
- маршруты
Поток данных и валидации
- Компонент фичи (например,
ServicesилиAdminDashboardNews) вызывает методы стора (services.fetch,news.fetchAdmin). - Стор делегирует запрос соответствующему SDK (
servicesApi,adminApi) и обновляет MobX‑модели. - Компоненты, обёрнутые в
observer, автоматически перерисовываются и показывают лоадеры/ошибки. - Формы в админке валидируют ввод на клиенте, а серверные ошибки ловятся как
ApiErrorи выводятся в UI.
Такая цепочка (компонент → стор → API → стор → компонент) делает логику прозрачной и облегчает внедрение новых сущностей.
Ассеты и стили
- Брендовые изображения и логотипы лежат в
src/assetsи импортируются напрямую в компоненты (например, хедер используетsrc/assets/logo.png). - Файлы в
public/доступны по прямым URL и могут использоваться для метатегов или фавиконок. - Изображения партнёров (
src/assets/partners) подключаются только внутри лендинга, что упрощает tree-shaking.
Расширение проекта
Чтобы добавить новую сущность:
- Создайте Zod‑схемы и API‑клиент в
src/api/<entity>. - Опишите MobX‑модель + коллекцию в
src/stores/<entity>, инициализируйте её вRootStore. - Подготовьте UI в отдельном модуле внутри
src/modules/<entity>и подключите маршруты черезsrc/app/router/routes.tsx. - При необходимости добавьте переиспользуемые компоненты/хуки в
src/shared.
Следование существующим паттернам гарантирует единообразие и упрощает поддержку сервиса.