/** 应用框架:100vh 布局(侧栏 + 顶栏页面标题 + 内容区滚动),会话守卫 + 主题切换 + 头像下拉(设置/退出) */ import { useEffect, useState } from "react"; import { Outlet, useLocation, useNavigate } from "react-router-dom"; import { Avatar, Button, Dropdown, Layout, Menu } from "antd"; import { DashboardOutlined, MailOutlined, CloudServerOutlined, GlobalOutlined, UserOutlined, LogoutOutlined, SettingOutlined, } from "@ant-design/icons"; import { health, logout, me } from "./api.ts"; import { SettingsModal } from "./components/SettingsModal.tsx"; import { useTheme } from "./theme-context.ts"; const { Sider, Header, Content } = Layout; /** # 成员变量: 侧栏菜单项 **/ const MENU_ITEMS = [ { key: "/", icon: , label: "概览" }, { key: "/accounts", icon: , label: "账号 Accounts" }, { key: "/domains", icon: , label: "域名 Domains" }, { key: "/mailboxes", icon: , label: "邮箱 Mailboxes" }, { key: "/inboxs", icon: , label: "收件箱 Inboxs" }, ]; /** # 成员变量: 路由 -> 页面标题/副标题 **/ const PAGE_META: Record = { "/": { title: "概览", subtitle: "账号、域名与邮件总览" }, "/accounts": { title: "账号", subtitle: "通过 Cloudflare OAuth 接入的 Cloudflare 账号(Email Worker 直连)" }, "/domains": { title: "域名", subtitle: "OAuth 自动同步的收件域名与 Email Workers" }, "/mailboxes": { title: "邮箱", subtitle: "收件地址、保留策略与邮箱级 Webhook" }, "/inboxs": { title: "收件箱", subtitle: "已接收邮件(默认保留 1 天),支持按域名筛选" }, }; /** # 成员变量: 主题切换按钮的太阳/月亮 SVG 图标 **/ const SunIcon = ( ); const MoonIcon = ( ); /** # 函数 * 应用框架组件:未登录跳 /login;顶栏展示页面标题 + 主题切换 + 头像下拉;侧栏品牌带版本号 */ export function App() { const navigate = useNavigate(); const location = useLocation(); const { dark, toggle } = useTheme(); const [ready, setReady] = useState(false); const [username, setUsername] = useState(""); const [version, setVersion] = useState(""); const [settingsOpen, setSettingsOpen] = useState(false); useEffect(() => { void (async () => { try { const [healthInfo, meInfo] = await Promise.all([health(), me()]); setVersion(healthInfo.version); setUsername(meInfo.user.username); setReady(true); } catch { navigate("/login", { replace: true }); } })(); }, [navigate]); if (!ready) return null; const meta = PAGE_META[location.pathname] ?? { title: "WmailHub", subtitle: "" }; return ( <>
WmailHub WmailHub {/* 版本号小一号、居上对齐(来源 package.json) */} {version && v{version}}
navigate(key)} style={{ borderInlineEnd: "none" }} />
{meta.title}
{meta.subtitle}
{/* 主题切换:亮↔暗,位于头像左侧 */}
setSettingsOpen(false)} /> ); }