diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx index e54f9ca..5a17771 100644 --- a/src/components/header/index.tsx +++ b/src/components/header/index.tsx @@ -3,15 +3,25 @@ import { ColorModeContext } from "@contexts/color-mode"; import DarkModeOutlined from "@mui/icons-material/DarkModeOutlined"; import LightModeOutlined from "@mui/icons-material/LightModeOutlined"; +import Logout from "@mui/icons-material/Logout"; +import SwapHoriz from "@mui/icons-material/SwapHoriz"; import AppBar from "@mui/material/AppBar"; import Avatar from "@mui/material/Avatar"; +import ButtonBase from "@mui/material/ButtonBase"; +import Divider from "@mui/material/Divider"; import IconButton from "@mui/material/IconButton"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import Menu from "@mui/material/Menu"; +import MenuItem from "@mui/material/MenuItem"; import Stack from "@mui/material/Stack"; import Toolbar from "@mui/material/Toolbar"; import Typography from "@mui/material/Typography"; -import { useGetIdentity } from "@refinedev/core"; +import { useGetIdentity, useLogout } from "@refinedev/core"; import { HamburgerMenu, RefineThemedLayoutHeaderProps } from "@refinedev/mui"; -import React, { useContext } from "react"; +import React, { useContext, useState } from "react"; +import { ProjectSelector } from "@components/project/ProjectSelector"; +import { setMapWorkspace, setNetworkName } from "@config/config"; type IUser = { id: number; @@ -23,9 +33,35 @@ export const Header: React.FC = ({ sticky = true, }) => { const { mode, setMode } = useContext(ColorModeContext); + const { mutate: logout } = useLogout(); + const [anchorEl, setAnchorEl] = useState(null); + const [showProjectSelector, setShowProjectSelector] = useState(false); + const open = Boolean(anchorEl); const { data: user } = useGetIdentity(); + const handleMenuOpen = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleMenuClose = () => { + setAnchorEl(null); + }; + + const handleSwitchProjectClick = () => { + handleMenuClose(); + setShowProjectSelector(true); + }; + + const handleProjectSelect = (workspace: string, networkName: string) => { + setMapWorkspace(workspace); + setNetworkName(networkName); + localStorage.setItem("NEXT_PUBLIC_MAP_WORKSPACE", workspace); + localStorage.setItem("NEXT_PUBLIC_NETWORK_NAME", networkName); + setShowProjectSelector(false); + window.location.reload(); + }; + return ( @@ -52,27 +88,118 @@ export const Header: React.FC = ({ {(user?.avatar || user?.name) && ( - - {user?.name && ( - + + - {user?.name} - - )} - - + {user?.name && ( + + {user?.name} + + )} + + + + + + + + + 切换项目 + + + logout()}> + + + + 登出 + + + setShowProjectSelector(false)} + /> + )} diff --git a/src/components/project/ProjectSelector.tsx b/src/components/project/ProjectSelector.tsx index 7537cb2..03c951f 100644 --- a/src/components/project/ProjectSelector.tsx +++ b/src/components/project/ProjectSelector.tsx @@ -12,12 +12,15 @@ import { Box, Typography, Fade, + IconButton, } from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; import { useState } from "react"; interface ProjectSelectorProps { open: boolean; onSelect: (workspace: string, networkName: string) => void; + onClose?: () => void; } const PROJECTS = [ @@ -29,6 +32,7 @@ const PROJECTS = [ export const ProjectSelector: React.FC = ({ open, onSelect, + onClose, }) => { const [workspace, setWorkspace] = useState(PROJECTS[0].workspace); const [networkName, setNetworkName] = useState(PROJECTS[0].networkName); @@ -41,7 +45,8 @@ export const ProjectSelector: React.FC = ({ return ( = ({ minWidth: 400, background: "rgba(255, 255, 255, 0.95)", backdropFilter: "blur(10px)", + position: "relative", } } }} slots={{ transition: Fade }} transitionDuration={500} > + {onClose && ( + theme.palette.grey[500], + }} + > + + + )}