mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-03 03:35:04 +03:00
refactor(frontend): read the panel's navigation from one route manifest (#6922)
The router, the sidebar, the page titles and the command palette each kept their own list of the panel's pages, so a page added to one could go missing from another without any test noticing. They all read src/routes/panelRoutes.tsx now, and a contract test holds the manifest to the router, the translation bundle and the palette keywords. The unused useZodForm helper goes, and CONTRIBUTING, frontend/CLAUDE.md and the frontend README describe the useForm + rhfZodValidate pattern the panel's forms actually use.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { lazy } from 'react';
|
||||
import type { ComponentType } from 'react';
|
||||
import {
|
||||
ApiOutlined,
|
||||
ClusterOutlined,
|
||||
CrownOutlined,
|
||||
DashboardOutlined,
|
||||
ExportOutlined,
|
||||
GlobalOutlined,
|
||||
ImportOutlined,
|
||||
SettingOutlined,
|
||||
SwapOutlined,
|
||||
TagsOutlined,
|
||||
TeamOutlined,
|
||||
ToolOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const IndexPage = lazy(() => import('@/pages/index/IndexPage'));
|
||||
const InboundsPage = lazy(() => import('@/pages/inbounds/InboundsPage'));
|
||||
const ClientsPage = lazy(() => import('@/pages/clients/ClientsPage'));
|
||||
const GroupsPage = lazy(() => import('@/pages/groups/GroupsPage'));
|
||||
const NodesPage = lazy(() => import('@/pages/nodes/NodesPage'));
|
||||
const HostsPage = lazy(() => import('@/pages/hosts/HostsPage'));
|
||||
const SettingsPage = lazy(() => import('@/pages/settings/SettingsPage'));
|
||||
const XrayPage = lazy(() => import('@/pages/xray/XrayPage'));
|
||||
const ApiDocsPage = lazy(() => import('@/pages/api-docs/ApiDocsPage'));
|
||||
const SponsorsPage = lazy(() => import('@/pages/sponsors/SponsorsPage'));
|
||||
|
||||
export interface PanelRoute {
|
||||
path: string;
|
||||
titleKey: string;
|
||||
icon: ComponentType;
|
||||
component: ComponentType;
|
||||
}
|
||||
|
||||
// The router, the sidebar, the page titles and the command palette all read this list, so a
|
||||
// page cannot go missing from one of them.
|
||||
export const PANEL_ROUTES: PanelRoute[] = [
|
||||
{ path: '/', titleKey: 'menu.dashboard', icon: DashboardOutlined, component: IndexPage },
|
||||
{ path: '/inbounds', titleKey: 'menu.inbounds', icon: ImportOutlined, component: InboundsPage },
|
||||
{ path: '/clients', titleKey: 'menu.clients', icon: TeamOutlined, component: ClientsPage },
|
||||
{ path: '/groups', titleKey: 'menu.groups', icon: TagsOutlined, component: GroupsPage },
|
||||
{ path: '/nodes', titleKey: 'menu.nodes', icon: ClusterOutlined, component: NodesPage },
|
||||
{ path: '/hosts', titleKey: 'menu.hosts', icon: GlobalOutlined, component: HostsPage },
|
||||
{ path: '/outbound', titleKey: 'menu.outbounds', icon: ExportOutlined, component: XrayPage },
|
||||
{ path: '/routing', titleKey: 'menu.routing', icon: SwapOutlined, component: XrayPage },
|
||||
{ path: '/settings', titleKey: 'menu.settings', icon: SettingOutlined, component: SettingsPage },
|
||||
{ path: '/xray', titleKey: 'menu.xray', icon: ToolOutlined, component: XrayPage },
|
||||
{ path: '/api-docs', titleKey: 'menu.apiDocs', icon: ApiOutlined, component: ApiDocsPage },
|
||||
{ path: '/sponsors', titleKey: 'menu.sponsors', icon: CrownOutlined, component: SponsorsPage },
|
||||
];
|
||||
|
||||
export const PANEL_ROUTE_PATHS = PANEL_ROUTES.map((route) => route.path);
|
||||
|
||||
export const PANEL_TITLE_KEYS: Record<string, string> = Object.fromEntries(
|
||||
PANEL_ROUTES.map((route) => [route.path, route.titleKey]),
|
||||
);
|
||||
Reference in New Issue
Block a user