Маршрутизация и навигация¶
Архитектура маршрутизации¶
Приложение использует React Router v6 с декларативной конфигурацией маршрутов в App.tsx. Применяется паттерн nested routes: защищённые маршруты оборачиваются в ProtectedRoute и получают общий layout с нижней навигацией.
graph TD
BrowserRouter --> Routes
subgraph ProtectedLayout["Protected + AppLayout"]
Routes --> LayoutRoute["Route element=Protected+AppLayout"]
LayoutRoute --> HOME["/ HomePage"]
LayoutRoute --> FEED["/feed FeedPage"]
LayoutRoute --> WARDROBE["/wardrobe WardrobePage"]
LayoutRoute --> ITEM["/wardrobe/:itemId"]
LayoutRoute --> ADD["/add AddItemSourcePage"]
LayoutRoute --> ADD_D["/add/details AddItemDetailsPage"]
LayoutRoute --> OUTFITS["/outfits OutfitsPage"]
LayoutRoute --> BUILD["/outfits/build"]
LayoutRoute --> SELECT["/outfits/build/select"]
LayoutRoute --> OUTFIT_D["/outfits/:outfitId"]
LayoutRoute --> PROFILE["/profile ProfilePage"]
LayoutRoute --> SETTINGS["/profile/settings"]
LayoutRoute --> SHARE["/share/:outfitId SharePage"]
end
subgraph PublicRoutes["Публичные маршруты (без layout)"]
Routes --> LOGIN["/login LoginPage"]
Routes --> REGISTER["/register RegisterPage"]
Routes --> SHARE_V["/share/view/:token"]
end

Полная таблица маршрутов¶
| Путь | Компонент | Защищённый | Layout | Назначение |
|---|---|---|---|---|
/ |
HomePage | да | AppLayout | Главная (точка входа) |
/feed |
FeedPage | да | AppLayout | AI-лента образов |
/wardrobe |
WardrobePage | да | AppLayout | Список вещей с фильтрацией |
/wardrobe/:itemId |
WardrobeItemPage | да | AppLayout | Детальная карточка вещи |
/add |
AddItemSourcePage | да | AppLayout | Выбор источника фото |
/add/details |
AddItemDetailsPage | да | AppLayout | Форма атрибутов + ML |
/outfits |
OutfitsPage | да | AppLayout | Список образов |
/outfits/build |
OutfitBuilderPage | да | AppLayout | Конструктор образа |
/outfits/build/select |
ItemSelectPage | да | AppLayout | Выбор вещи для слота |
/outfits/:outfitId |
OutfitDetailPage | да | AppLayout | Детали образа |
/profile |
ProfilePage | да | AppLayout | Профиль пользователя |
/profile/settings |
SettingsPage | да | AppLayout | Настройки |
/share/:outfitId |
SharePage | да | AppLayout | Создание ссылки для шеринга |
/login |
LoginPage | нет | — | Вход |
/register |
RegisterPage | нет | — | Регистрация |
/share/view/:token |
ShareRecipientPage | нет | — | Просмотр расшаренного образа |
Структура layout¶
AppLayout
├── OfflineBanner — баннер при отсутствии сети
├── <main role="main"> — контент (Outlet)
│ └── [Page Component]
└── BottomNav — нижняя навигация (Home, Feed, Add, Outfits, Profile)
AppLayout рендерит <Outlet /> из React Router — дочерние маршруты автоматически подставляются внутрь.
Механизм защиты маршрутов¶
Защита реализована через компонент ProtectedRoute:
- Проверяет isAuthenticated из authStore
- Незалогиненный пользователь перенаправляется на /login?redirect=<текущий путь>
- После успешного входа — редирект обратно на исходную страницу
// Ключевая логика (5 строк)
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
if (!isAuthenticated) {
const redirect = encodeURIComponent(location.pathname + location.search);
return <Navigate to={`/login?redirect=${redirect}`} replace />;
}
→ Полный код guards: route-guards.md