Files
glchat/web/src/router.tsx
T
grendervill 566e1cf981 feat(invites): страница приглашения со splash и переопределением
- миграция 00015: переопределение splash у приглашения (AGENT.md 7.9)
- GET /invites/{code} доступен без сессии: гость по ссылке видит карточку
  сервера, описание, число участников и пригласившего
- POST/DELETE /invites/{code}/background: своя картинка страницы под правом
  создателя или MANAGE_GUILD, файл удаляется при замене и снятии
- клиент: маршрут /invite/:code с фоном (переопределение → splash → баннер),
  карточкой сервера, кнопками «Присоединиться»/«Открыть сервер» и входом с
  возвратом на страницу (?next=)
- тесты: Go (карточка, загрузка, права, снятие) и Vitest (splash, гость,
  присоединение, недействительная ссылка)
2026-09-21 19:25:06 +03:00

99 lines
3.9 KiB
TypeScript

import { createBrowserRouter, Navigate } from 'react-router';
import { AuthGuard } from '@/components/AuthGuard';
import {
AccountSettingsLayout,
AppearanceSettingsPage,
AppLayout,
IndexRedirect,
FriendsPage,
InvitePage,
GuildView,
InstanceSettingsPage,
LoginPage,
NoGuildView,
OnboardingPage,
ProfileSettingsPage,
ProfileServerTab,
RegisterPage,
SecuritySettingsPage,
SettingsLayout,
StatusPage,
} from '@/pages/lazyPages';
/** Таблица маршрутов: публичные страницы, защищённые и настройки. */
export const routes = [
{
path: '/',
children: [
{ index: true, element: <IndexRedirect /> },
{ path: 'login', element: <LoginPage /> },
{ path: 'register', element: <RegisterPage /> },
{ path: 'status', element: <StatusPage /> },
// Страница приглашения: доступна без входа, гость видит предпросмотр.
{ path: 'invite/:code', element: <InvitePage /> },
{
element: <AuthGuard allowIncompleteOnboarding />,
children: [{ path: 'onboarding', element: <OnboardingPage /> }],
},
{
element: <AuthGuard />,
children: [
{
path: 'app',
element: <AppLayout />,
children: [
{ index: true, element: <Navigate to="empty" replace /> },
{ path: 'empty', element: <NoGuildView /> },
// Раздел друзей: статические сегменты выше динамических,
// поэтому `friends` не перехватывается маршрутом `:guildId`.
{ path: 'friends', element: <FriendsPage /> },
{ path: 'friends/:channelId', element: <FriendsPage /> },
{ path: ':guildId', element: <GuildView /> },
{ path: ':guildId/:channelId', element: <GuildView /> },
],
},
],
},
{
element: <AuthGuard allowIncompleteOnboarding />,
children: [
{
path: 'settings',
element: <SettingsLayout />,
children: [
{ index: true, element: <Navigate to="/settings/account/profile" replace /> },
{
// Настройки аккаунта и инстанса: /settings/account/*
path: 'account',
element: <AccountSettingsLayout />,
children: [
{ index: true, element: <Navigate to="profile" replace /> },
{ path: 'profile', element: <ProfileSettingsPage /> },
{ path: 'security', element: <SecuritySettingsPage /> },
{ path: 'appearance', element: <AppearanceSettingsPage /> },
{ path: 'instance', element: <InstanceSettingsPage /> },
],
},
// Настройки пользовательских серверов: /settings/servers/:guildId
{ path: 'servers', element: <ProfileServerTab /> },
{ path: 'servers/:guildId', element: <ProfileServerTab /> },
// Старые пути Фазы 1: закладки и внешние ссылки продолжают работать.
{ path: 'profile', element: <Navigate to="/settings/account/profile" replace /> },
{ path: 'security', element: <Navigate to="/settings/account/security" replace /> },
{
path: 'appearance',
element: <Navigate to="/settings/account/appearance" replace />,
},
{ path: 'instance', element: <Navigate to="/settings/account/instance" replace /> },
],
},
],
},
{ path: '*', element: <Navigate to="/" replace /> },
],
},
];
export const router = createBrowserRouter(routes);