import * as React from 'react'; import { styled, useTheme } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Drawer from '@mui/material/Drawer'; import Toolbar from '@mui/material/Toolbar'; import List from '@mui/material/List'; import Divider from '@mui/material/Divider'; import IconButton from '@mui/material/IconButton'; import MenuIcon from '@mui/icons-material/Menu'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import AppBar from '@mui/material/AppBar'; import { Outlet } from 'react-router-dom'; import { AccountCircle } from '@mui/icons-material'; import Menu from '@mui/material/Menu'; import MenuItem from '@mui/material/MenuItem'; import { LayoutAlertErr, token, user } from '@/store/store'; import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai'; import Button from '@mui/material/Button'; import { useNavigate } from "react-router-dom"; import { useRequest, useMemoizedFn } from 'ahooks'; import { getConfig, userInfo } from '@/apis/apis' import Snackbar from '@mui/material/Snackbar'; import Alert from '@mui/material/Alert'; import { memo } from 'react'; import useMediaQuery from '@mui/material/useMediaQuery'; import Typography from '@mui/material/Typography'; import Container from '@mui/material/Container'; import PersonIcon from '@mui/icons-material/Person'; import SecurityIcon from '@mui/icons-material/Security'; import SettingsIcon from '@mui/icons-material/Settings'; import { Link } from "react-router-dom"; import GroupIcon from '@mui/icons-material/Group'; import { ApiErr } from '@/apis/error'; const drawerWidth = 240; const DrawerOpen = atom(false) const DrawerHeader = styled('div')(({ theme }) => ({ display: 'flex', alignItems: 'center', padding: theme.spacing(0, 1), // necessary for content to be below app bar ...theme.mixins.toolbar, justifyContent: 'flex-end', })); interface ListItem { icon: JSX.Element title: string link: string } const Layout = memo(function Layout() { const theme = useTheme(); const [err, setErr] = useAtom(LayoutAlertErr) return (<> setErr("")} severity="error">{err} ) }) const MyToolbar = memo(function MyToolbar() { const [nowUser, setNowUser] = useAtom(user) const [anchorEl, setAnchorEl] = React.useState(null); const navigate = useNavigate(); const setToken = useSetAtom(token) const setErr = useSetAtom(LayoutAlertErr) const setOpen = useSetAtom(DrawerOpen) const server = useRequest(getConfig, { cacheKey: "/api/v1/config", staleTime: 60000, onError: e => { console.warn(e) setErr(String(e)) } }) const handleLogOut = useMemoizedFn(() => { setAnchorEl(null); setNowUser({ name: "", uuid: "" }) setToken("") navigate("/login") }) return ( <> {nowUser.name != "" && (<> setOpen(true)} > ) } {server.data?.serverName ?? "皮肤站"} {nowUser.name != "" && (
setAnchorEl(event.currentTarget)} color="inherit" > setAnchorEl(null)} > 登出
)} {nowUser.name == "" && ( )}
) }) const MyList = memo(function MyList(p: { list: ListItem[] }) { return ( <> {p.list.map(item => )} ) }) const MyListItem = function MyListItem(p: ListItem) { const navigate = useNavigate(); const handleClick = () => { navigate(p.link) } return ( {p.icon} ) } const MyDrawer = function MyDrawer() { const nowToken = useAtomValue(token) const setErr = useSetAtom(LayoutAlertErr) const theme = useTheme(); const isLg = useMediaQuery(theme.breakpoints.up('lg')) const [open, setOpen] = useAtom(DrawerOpen) const navigate = useNavigate(); const userinfo = useRequest(() => userInfo(nowToken), { refreshDeps: [nowToken], cacheKey: "/api/v1/user" + nowToken, staleTime: 60000, onError: e => { if (e instanceof ApiErr && e.code == 5) { navigate("/login") } console.warn(e) setErr(String(e)) }, }) const userDrawerList = React.useMemo(() => [ { icon: , title: '个人信息', link: '/profile' }, { icon: , title: '皮肤设置', link: '/textures' }, { icon: , title: '账号设置', link: '/security' } ] as ListItem[], []) const adminDrawerList = React.useMemo(() => [ { icon: , title: '用户管理', link: '/admin/user' } ] as ListItem[], []) return (<> {userinfo.data && ( setOpen(false)} > setOpen(false)}> {theme.direction === 'ltr' ? : } {userinfo.data?.is_admin && ( <> )} )} ) } export default Layout