diff --git a/src/app/panel/components/PanelSidebarContent.tsx b/src/app/panel/components/PanelSidebarContent.tsx index 3f78050..08e2199 100644 --- a/src/app/panel/components/PanelSidebarContent.tsx +++ b/src/app/panel/components/PanelSidebarContent.tsx @@ -4,21 +4,24 @@ import Link from 'next/link' import { usePathname } from 'next/navigation' import { useMemo, type ComponentType } from 'react' +import { Plus, type LucideIcon } from 'lucide-react' + import { getExtensionRegistry } from '@extensions/loader' import { useLanguage } from '@i18n/LanguageProvider' import { translations } from '@i18n/translations' import { resolveAccess } from '@lib/accessControl' import { useUserStore } from '@lib/userStore' -import { SidebarHeader, SidebarContent } from '../../../components/layout/SidebarRoot' +import { SidebarHeader, SidebarContent, SidebarFooter } from '../../../components/layout/SidebarRoot' const registry = getExtensionRegistry() const PlaceholderIcon: ComponentType<{ className?: string }> = () => null interface NavItem { + id?: string href: string label: string description: string - Icon: ComponentType<{ className?: string }> + Icon: ComponentType<{ className?: string }> | LucideIcon disabled: boolean } @@ -68,6 +71,7 @@ export function PanelSidebarContent({ onNavigate, collapsed = false }: PanelSide const Icon = route.icon ?? PlaceholderIcon return { + id: route.id, href: route.path, label: route.label, description: route.description ?? '', @@ -75,7 +79,7 @@ export function PanelSidebarContent({ onNavigate, collapsed = false }: PanelSide disabled, } }) - .filter((value): value is NavItem => Boolean(value)) + .filter((value) => Boolean(value)) as NavItem[] if (items.length === 0) { return null @@ -87,7 +91,7 @@ export function PanelSidebarContent({ onNavigate, collapsed = false }: PanelSide items, } }) - .filter((value): value is NavSection => Boolean(value)) + .filter((value) => Boolean(value)) as NavSection[] }, [requiresSetup, user]) return ( @@ -193,7 +197,9 @@ export function PanelSidebarContent({ onNavigate, collapsed = false }: PanelSide - {item.label} + + {(item.id && translations[language].userCenter.items[item.id as keyof typeof translations.en.userCenter.items]) || item.label} + {item.description} @@ -218,6 +224,18 @@ export function PanelSidebarContent({ onNavigate, collapsed = false }: PanelSide ) })} + + + + ) } diff --git a/src/app/services/Material3Layout.tsx b/src/app/services/Material3Layout.tsx index 1ee708e..fde1266 100644 --- a/src/app/services/Material3Layout.tsx +++ b/src/app/services/Material3Layout.tsx @@ -1,7 +1,6 @@ 'use client' import React from 'react' -import { Sidebar } from '../../components/Sidebar' import { Header } from '../../components/Header' interface Material3LayoutProps { @@ -11,7 +10,6 @@ interface Material3LayoutProps { export function Material3Layout({ children }: Material3LayoutProps) { return (
-
diff --git a/src/i18n/translations.ts b/src/i18n/translations.ts index e3a5f2a..8562d1a 100644 --- a/src/i18n/translations.ts +++ b/src/i18n/translations.ts @@ -478,9 +478,25 @@ type UserCenterTranslation = { sections: { workspace: string productivity: string + infra: string management: string preferences: string } + items: { + dashboard: string + mail: string + agents: string + apis: string + accounts: string + subscription: string + ldp: string + appearance: string + deployments: string + resources: string + apiKeys: string + logs: string + settings: string + } overview: UserCenterOverviewTranslation mfa: UserCenterMfaTranslation } @@ -950,9 +966,25 @@ export const translations: Record<'en' | 'zh', Translation> = { sections: { workspace: 'Workspace', productivity: 'Productivity Tools', + infra: 'Infrastructure', management: 'Accounts & Access', preferences: 'Preferences', }, + items: { + dashboard: 'Dashboard', + mail: 'Mail', + agents: 'Agents', + apis: 'APIs', + accounts: 'Accounts', + subscription: 'Subscription', + ldp: 'LDP', + appearance: 'Appearance', + deployments: 'Deployments', + resources: 'Resources', + apiKeys: 'API Keys', + logs: 'Logs', + settings: 'Settings', + }, overview: { heading: 'User Center', loading: 'Loading your personalized space…', @@ -1702,9 +1734,25 @@ export const translations: Record<'en' | 'zh', Translation> = { sections: { workspace: '工作台', productivity: '生产力工具', + infra: '资源运维', management: '账户与权限', preferences: '偏好设置', }, + items: { + dashboard: '仪表盘', + mail: '邮箱服务', + agents: '运行节点', + apis: '接口集成', + accounts: '账户中心', + subscription: '订阅计划', + ldp: '身份平面', + appearance: '个性化', + deployments: '部署管理', + resources: '资源列表', + apiKeys: '接口密钥', + logs: '运行日志', + settings: '系统设置', + }, overview: { heading: '用户中心', loading: '正在加载你的专属空间…', diff --git a/src/modules/extensions/builtin/index.ts b/src/modules/extensions/builtin/index.ts index bd4488c..b64dc50 100644 --- a/src/modules/extensions/builtin/index.ts +++ b/src/modules/extensions/builtin/index.ts @@ -1,5 +1,9 @@ import type { DashboardExtension } from '../types' import { userCenterExtension } from './user-center' +import { infraExtension } from './infra' -export const builtinExtensions: DashboardExtension[] = [userCenterExtension] +export const builtinExtensions: DashboardExtension[] = [ + userCenterExtension, + infraExtension, +] diff --git a/src/modules/extensions/builtin/infra/index.ts b/src/modules/extensions/builtin/infra/index.ts new file mode 100644 index 0000000..48b50e3 --- /dev/null +++ b/src/modules/extensions/builtin/infra/index.ts @@ -0,0 +1,66 @@ +import { Database, History, Key, Rocket, Settings } from 'lucide-react' + +import type { DashboardExtension } from '../../types' + +export const infraExtension: DashboardExtension = { + id: 'builtin.infra', + meta: { + title: '基础设施管理', + description: '云基础设施、部署、资源与日志管理。', + version: '1.0.0', + author: 'Cloud-Neutral', + keywords: ['infrastructure', 'deployments', 'resources', 'logs'], + }, + routes: [ + { + id: 'deployments', + path: '/panel/deployments', + label: 'Deployments', + description: '部署任务与运行状态', + icon: Rocket, + loader: () => import('./routes/placeholder'), + guard: { requireLogin: true }, + sidebar: { section: 'infra', order: 0 }, + }, + { + id: 'resources', + path: '/panel/resources', + label: 'Resources', + description: '云资源与数据库实例', + icon: Database, + loader: () => import('./routes/placeholder'), + guard: { requireLogin: true }, + sidebar: { section: 'infra', order: 1 }, + }, + { + id: 'apiKeys', + path: '/panel/api-keys', + label: 'API Keys', + description: '接口密钥与访问凭证', + icon: Key, + loader: () => import('./routes/placeholder'), + guard: { requireLogin: true }, + sidebar: { section: 'infra', order: 2 }, + }, + { + id: 'logs', + path: '/panel/logs', + label: 'Logs', + description: '系统流水与审计日志', + icon: History, + loader: () => import('./routes/placeholder'), + guard: { requireLogin: true }, + sidebar: { section: 'infra', order: 3 }, + }, + { + id: 'settings', + path: '/panel/settings', + label: 'Settings', + description: '全局系统配置', + icon: Settings, + loader: () => import('./routes/placeholder'), + guard: { requireLogin: true, roles: ['admin', 'operator'] }, + sidebar: { section: 'preferences', order: 99 }, + }, + ], +} diff --git a/src/modules/extensions/builtin/infra/routes/placeholder.tsx b/src/modules/extensions/builtin/infra/routes/placeholder.tsx new file mode 100644 index 0000000..d183f10 --- /dev/null +++ b/src/modules/extensions/builtin/infra/routes/placeholder.tsx @@ -0,0 +1,22 @@ +'use client' + +import React from 'react' +import { usePathname } from 'next/navigation' + +export default function PlaceholderPage() { + const pathname = usePathname() + const title = pathname.split('/').pop()?.replace(/-/g, ' ') || 'Page' + + return ( +
+
+ {title.charAt(0)} +
+

{title}

+

+ This feature is currently under active development. + It will soon provide a powerful interface for managing your {title.toLowerCase()}. +

+
+ ) +} diff --git a/src/modules/extensions/builtin/user-center/index.ts b/src/modules/extensions/builtin/user-center/index.ts index 06b4948..45cbdbb 100644 --- a/src/modules/extensions/builtin/user-center/index.ts +++ b/src/modules/extensions/builtin/user-center/index.ts @@ -13,6 +13,7 @@ export const userCenterExtension: DashboardExtension = { }, routes: [ { + id: 'dashboard', path: '/panel', label: 'Dashboard', description: '专属于你的信息总览', @@ -24,6 +25,7 @@ export const userCenterExtension: DashboardExtension = { sidebar: { section: 'workspace', order: 0 }, }, { + id: 'mail', path: '/panel/mail', label: 'Mail', description: '租户邮件与 AI 助理', @@ -34,6 +36,7 @@ export const userCenterExtension: DashboardExtension = { sidebar: { section: 'workspace', order: 1 }, }, { + id: 'agents', path: '/panel/agent', label: 'Agents', description: '管理运行节点', @@ -51,6 +54,7 @@ export const userCenterExtension: DashboardExtension = { }, }, { + id: 'apis', path: '/panel/api', label: 'APIs', description: '洞察后端服务', @@ -68,6 +72,7 @@ export const userCenterExtension: DashboardExtension = { }, }, { + id: 'accounts', path: '/panel/account', label: 'Accounts', description: '目录与多因素设置', @@ -78,6 +83,7 @@ export const userCenterExtension: DashboardExtension = { sidebar: { section: 'management', order: 20 }, }, { + id: 'subscription', path: '/panel/subscription', label: 'Subscription', description: '订阅方案与计费规则', @@ -95,6 +101,7 @@ export const userCenterExtension: DashboardExtension = { }, }, { + id: 'ldp', path: '/panel/ldp', label: 'LDP', description: '低时延身份平面', @@ -112,6 +119,7 @@ export const userCenterExtension: DashboardExtension = { }, }, { + id: 'appearance', path: '/panel/appearance', label: 'Appearance', description: '个性化主题设置', diff --git a/src/modules/extensions/types.ts b/src/modules/extensions/types.ts index 05c5859..9ad4d9c 100644 --- a/src/modules/extensions/types.ts +++ b/src/modules/extensions/types.ts @@ -27,6 +27,7 @@ export interface ExtensionMenuItem { } export interface ExtensionRoute { + id?: string path: string label: string description?: string