"use client"
import {
AppShell,
Box,
Burger,
Divider,
Flex,
Menu,
NavLink,
ScrollArea,
Space,
Stack,
Text,
Tooltip,
UnstyledButton,
useComputedColorScheme,
useMantineColorScheme,
} from "@mantine/core"
import Avvvatars from "avvvatars-react"
import { useDisclosure, useMediaQuery } from "@mantine/hooks"
import {
IconChevronDown,
IconLogout,
IconMoon,
IconSun,
} from "@tabler/icons-react"
import cx from "clsx"
import { Suspense, useEffect, useMemo, useState } from "react"
import actionToggleClasses from "./ActionToggle.module.css"
import headerLinkClasses from "./HeaderLink.module.css"
import { useUserStore } from "@/app/store/user"
import { usePathname, useRouter } from "next/navigation"
import { usePermissionStore } from "../label/store/auth"
import { deleteCookie } from "../login/api"
import classes from "./AppLayout.module.css"
import { MenuItem, withoutLayoutRoutes } from "./common"
import { ClientIcon } from "./components/ClientIcon"
import { LinksGroup } from "./components/NavbarLinks"
import { getShellNavLinkStyles } from "./navStyles"
import { useAppLayoutStore } from "./store"
const COMPOUND_SURNAMES = new Set([
"欧阳",
"太史",
"端木",
"上官",
"司马",
"东方",
"独孤",
"南宫",
"万俟",
"闻人",
"夏侯",
"诸葛",
"尉迟",
"公羊",
"赫连",
"澹台",
"皇甫",
"宗政",
"濮阳",
"公冶",
"太叔",
"申屠",
"公孙",
"慕容",
"仲孙",
"钟离",
"长孙",
"宇文",
"司徒",
"鲜于",
"司空",
"闾丘",
"子车",
"亓官",
"司寇",
"巫马",
"公西",
"颛孙",
"壤驷",
"公良",
"漆雕",
"乐正",
"宰父",
"谷梁",
"拓跋",
"轩辕",
"令狐",
"段干",
"百里",
"呼延",
"东郭",
"南门",
"羊舌",
"微生",
"梁丘",
"左丘",
"东门",
"西门",
"南荣",
"第五",
])
function isChineseName(value: string) {
return /[\u4e00-\u9fff]/.test(value)
}
function getAvatarDisplayValue(rawValue?: string | null) {
const value = rawValue?.trim() ?? ""
if (!value) return "-"
if (isChineseName(value)) {
const normalized = value.replace(/[\s·•・・]/g, "")
if (normalized.length <= 1) return normalized
const surnameLength =
normalized.length >= 3 && COMPOUND_SURNAMES.has(normalized.slice(0, 2))
? 2
: 1
const givenName = normalized.slice(surnameLength)
if (!givenName) return normalized.slice(-1)
if (givenName.length <= 2) return givenName
return givenName.slice(-2)
}
const tokens = value.split(/[\s-_]+/).filter(Boolean)
if (tokens.length >= 2) {
return `${tokens[0][0] ?? ""}${tokens[tokens.length - 1][0] ?? ""}`
.trim()
.toUpperCase()
}
return value.slice(0, 2).toUpperCase()
}
export default function AppLayout({
menu,
children,
}: {
menu: MenuItem[]
children: React.ReactNode
}) {
const [mobileOpened, { toggle: toggleMobile }] = useDisclosure()
const { updateIsOpen } = useAppLayoutStore.getState()
const { isOpen } = useAppLayoutStore()
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
const { setColorScheme } = useMantineColorScheme()
const computedColorScheme = useComputedColorScheme("light", {
getInitialValueInEffect: true,
})
const pathname = usePathname()
const withoutLayout = useMemo(
() => withoutLayoutRoutes.includes(pathname),
[pathname]
)
const router = useRouter()
const activeHeaderMenu = useMemo(() => {
return menu?.find((child) => pathname.startsWith(`/${child.url}`))
}, [pathname, menu])
const { menuDefaultRouter } = useAppLayoutStore.getState()
const headItems = menu.map((item) => (
{
e.preventDefault()
if (activeHeaderMenu?.url === item.url) return
let toPathname = menuDefaultRouter[`/${item.url}`] || `/${item.url}`
window.location.href = toPathname
// router.replace(toPathname)
}}>