import { ModeToggle } from "@/components/mode-toggle" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Button } from "@/components/ui/button" import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, } from "@/components/ui/drawer" import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { NavigationMenu, NavigationMenuItem, NavigationMenuLink, navigationMenuTriggerStyle, } from "@/components/ui/navigation-menu" import { IconButton } from "@/components/xui/icon-button" import { NzNavigationMenuLink } from "@/components/xui/navigation-menu" import { useAuth } from "@/hooks/useAuth" import { useMainStore } from "@/hooks/useMainStore" import { useMediaQuery } from "@/hooks/useMediaQuery" import { cn } from "@/lib/utils" import i18next from "i18next" import { LogOut, Settings, User2 } from "lucide-react" import { DateTime } from "luxon" import { useEffect, useRef, useState } from "react" import { useTranslation } from "react-i18next" import { Link, useLocation, useNavigate } from "react-router-dom" // ======================================================= // vvvvvvvvvvv 1. 在这里为移动端菜单添加新页面 vvvvvvvvvvv const pages = [ { href: "/dashboard", label: i18next.t("Server") }, { href: "/dashboard/service", label: i18next.t("Service") }, { href: "/dashboard/cron", label: i18next.t("Task") }, { href: "/dashboard/notification", label: i18next.t("Notification") }, { href: "/dashboard/ddns", label: i18next.t("DDNS") }, { href: "/dashboard/nat", label: i18next.t("NATT") }, { href: "/dashboard/domain", label: i18next.t("Domain") }, // <-- 新增的域名监控链接 { href: "/dashboard/server-group", label: i18next.t("Group") }, ] // ^^^^^^^^^^^ 1. 在这里为移动端菜单添加新页面 ^^^^^^^^^^^ // ======================================================= export default function Header() { const { t } = useTranslation() const { logout } = useAuth() const profile = useMainStore((store) => store.profile) const location = useLocation() const isDesktop = useMediaQuery("(min-width: 890px)") const [open, setOpen] = useState(false) const [dropdownOpen, setDropdownOpen] = useState(false) const navigate = useNavigate() // @ts-expect-error DisableAnimatedMan is a global variable const disableAnimatedMan = window.DisableAnimatedMan as boolean return isDesktop ? (
{!disableAnimatedMan && ( {"animated-man"} )}
{t("nezha")}
{t("BackToHome")} {profile && ( <> {profile.username} { setDropdownOpen(false) navigate("/dashboard/profile") }} className="cursor-pointer" >
{t("Profile")}
{ setDropdownOpen(false) navigate("/dashboard/settings") }} className="cursor-pointer" >
{t("Settings")}
{t("Logout")}
)}
{profile && ( <> {t("Server")} {t("Service")} {t("Task")} {t("Notification")} {t("DDNS")} {t("NATT")} {/* ======================================================= */} {/* vvvvvvvvvvv 2. 在这里为桌面端菜单添加新链接 vvvvvvvvvvv */} {t("Domain")} {/* ^^^^^^^^^^^ 2. 在这里为桌面端菜单添加新链接 ^^^^^^^^^^^ */} {/* ======================================================= */} {t("Group")} )}
) : (
{profile && ( {t("NavigateTo")} {t("SelectAPageToNavigateTo")}
{pages.slice(0).map((item, index) => ( { setOpen(false) }} > {item.label} ))}
)}
{t("nezha")}
{t("BackToHome")} {profile && ( <> {profile.username} { setDropdownOpen(false) navigate("/dashboard/profile") }} className="cursor-pointer" >
{t("Profile")}
{ setDropdownOpen(false) navigate("/dashboard/settings") }} className="cursor-pointer" >
{t("Settings")}
{t("Logout")} ⇧⌘Q
)}
) } // https://github.com/streamich/react-use/blob/master/src/useInterval.ts const useInterval = (callback: () => void, delay?: number | null) => { const savedCallback = useRef<() => void>(() => {}) useEffect(() => { savedCallback.current = callback }) useEffect(() => { if (delay !== null) { const interval = setInterval(() => savedCallback.current(), delay || 0) return () => clearInterval(interval) } return undefined }, [delay]) } function Overview() { const { t } = useTranslation() const profile = useMainStore((store) => store.profile) const timeOption = DateTime.TIME_SIMPLE timeOption.hour12 = true const [timeString, setTimeString] = useState( DateTime.now().setLocale("en-US").toLocaleString(timeOption), ) useInterval(() => { setTimeString(DateTime.now().setLocale("en-US").toLocaleString(timeOption)) }, 1000) return (
{profile && (
👋 Hi, {profile?.username} {profile?.login_ip && (

from {profile?.login_ip}

)}
)} {!profile &&

{t("LoginFirst")}

}

{t("CurrentTime")}

{timeString}

) }