This commit is contained in:
xuqssq
2024-12-28 15:39:48 +08:00
parent b3ac241354
commit 6e8334ecaf
18 changed files with 5017 additions and 420 deletions

View File

@@ -1,79 +1,91 @@
import React from 'react';
import { Layout, Switch, Button, Dropdown } from 'antd';
import { UserOutlined, LogoutOutlined } from '@ant-design/icons';
import { useTheme } from '@/contexts/ThemeContext';
import { useAuth } from '@/contexts/AuthContext';
import { MenuTrigger } from '../Layout/MenuTrigger';
import React from "react";
import { Layout, Switch, Button, Dropdown } from "antd";
import { UserOutlined, LogoutOutlined } from "@ant-design/icons";
import { useTheme } from "@/contexts/ThemeContext";
import { useAuth } from "@/contexts/AuthContext";
import { MenuTrigger } from "../Layout/MenuTrigger";
const { Header: AntHeader } = Layout;
import { LuSun } from "react-icons/lu";
import { GoMoon } from "react-icons/go";
const Header = ({ collapsed, setCollapsed }) => {
const { isDarkMode, toggleTheme } = useTheme();
const { user, logout } = useAuth();
const handleLogout = async () => {
try {
await logout();
} catch (error) {
console.error('Logout error:', error);
console.error("Logout error:", error);
}
};
const userMenuItems = [
{
key: 'profile',
key: "profile",
icon: <UserOutlined />,
label: '个人信息',
label: "个人信息",
},
{
key: 'logout',
key: "logout",
icon: <LogoutOutlined />,
label: '退出登录',
label: "退出登录",
onClick: handleLogout,
},
];
return (
<AntHeader
style={{
padding: 0,
background: isDarkMode ? '#141414' : '#fff',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
<AntHeader
style={{
padding: 0,
background: isDarkMode ? "#141414" : "#fff",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
<div className="flex items-center">
<MenuTrigger
collapsed={collapsed}
<MenuTrigger
collapsed={collapsed}
setCollapsed={setCollapsed}
isDarkMode={isDarkMode}
/>
</div>
<div className="flex items-center gap-4 mr-6">
<Switch
checked={isDarkMode}
onChange={toggleTheme}
checkedChildren="🌙"
unCheckedChildren="☀️"
/>
<Dropdown
menu={{ items: userMenuItems }}
<div className="flex items-center gap-4 mr-10 h-full select-none">
<div className="flex items-center justify-center cursor-pointer h-full" onClick={toggleTheme}>
{isDarkMode ? (
<GoMoon className="text-2xl" />
) : (
<LuSun className="text-2xl" />
)}
</div>
<Dropdown
menu={{ items: userMenuItems }}
placement="bottomRight"
trigger={['click']}
trigger={["click"]}
>
<Button
type="text"
icon={<UserOutlined />}
className="flex items-center"
>
{user?.email}
</Button>
<div className="flex gap-2 items-center justify-center cursor-pointer h-full">
{user?.user_metadata?.picture ? (
<img
src={user?.user_metadata?.picture}
alt="picture"
className="w-8 h-8 rounded-full"
/>
) : (
<div className="text-2xl bg-gray-400 dark:bg-gray-600 rounded-full flex justify-center items-center w-8 h-8 text-white pb-1">
{user?.email.slice(0, 1)}
</div>
)}
<p className="max-w-20 truncate">
{!user?.user_metadata?.name || user?.email?.split("@")[0]}
</p>
</div>
</Dropdown>
</div>
</AntHeader>
);
};
export default Header;
export default Header;

View File

@@ -1,9 +1,10 @@
import React, { useMemo } from 'react';
import { Layout, Menu } from 'antd';
import { useNavigate, useLocation } from 'react-router-dom';
import { useTheme } from '@/contexts/ThemeContext';
import { getMenuItems } from '@/utils/menuUtils';
import { Logo } from '@/components/Layout/Logo';
import React, { useMemo } from "react";
import { Layout, Menu } from "antd";
import { useNavigate, useLocation } from "react-router-dom";
import { useTheme } from "@/contexts/ThemeContext";
import { getMenuItems } from "@/utils/menuUtils";
import { Logo } from "@/components/Layout/Logo";
import { useAuth } from "@/contexts/AuthContext";
const { Sider } = Layout;
@@ -11,13 +12,18 @@ const Sidebar = ({ collapsed }) => {
const navigate = useNavigate();
const location = useLocation();
const { isDarkMode } = useTheme();
const { user } = useAuth();
const menuItems = useMemo(() => getMenuItems(), []);
const menuItems = useMemo(() => {
if (!user?.id) return [];
const { adminRole: role } = user;
return getMenuItems(role);
}, [user]);
const defaultOpenKeys = useMemo(() => {
const pathSegments = location.pathname.split('/').filter(Boolean);
const pathSegments = location.pathname.split("/").filter(Boolean);
return pathSegments.reduce((acc, _, index) => {
const path = `/${pathSegments.slice(0, index + 1).join('/')}`;
const path = `/${pathSegments.slice(0, index + 1).join("/")}`;
acc.push(path);
return acc;
}, []);
@@ -29,18 +35,18 @@ const Sidebar = ({ collapsed }) => {
};
return (
<Sider
trigger={null}
collapsible
<Sider
trigger={null}
collapsible
collapsed={collapsed}
theme={isDarkMode ? 'dark' : 'light'}
theme={isDarkMode ? "dark" : "light"}
width={256}
collapsedWidth={80} // 添加这个属性
className={`app-sidebar ${collapsed ? 'collapsed' : ''}`} // 添加collapsed类名
className={`app-sidebar ${collapsed ? "collapsed" : ""}`} // 添加collapsed类名
>
<Logo collapsed={collapsed} isDarkMode={isDarkMode} />
<Menu
theme={isDarkMode ? 'dark' : 'light'}
theme={isDarkMode ? "dark" : "light"}
mode="inline"
selectedKeys={[location.pathname]}
defaultOpenKeys={defaultOpenKeys}
@@ -51,4 +57,4 @@ const Sidebar = ({ collapsed }) => {
);
};
export default React.memo(Sidebar);
export default React.memo(Sidebar);