import ExpandMore from "@mui/icons-material/ExpandMore"; import Inventory2Outlined from "@mui/icons-material/Inventory2Outlined"; import LockReset from "@mui/icons-material/LockReset"; import Logout from "@mui/icons-material/Logout"; import Menu from "@mui/icons-material/Menu"; import MenuOpen from "@mui/icons-material/MenuOpen"; import Person from "@mui/icons-material/Person"; import Refresh from "@mui/icons-material/Refresh"; import Search from "@mui/icons-material/Search"; import MuiMenu from "@mui/material/Menu"; import MenuItem from "@mui/material/MenuItem"; import TextField from "@mui/material/TextField"; import { lazy, Suspense, useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useAppScope } from "@/app/app-scope/AppScopeProvider.jsx"; import { useAuth } from "@/app/auth/AuthProvider.jsx"; import { useTimeZone } from "@/app/timezone/TimeZoneProvider.jsx"; import { changePassword } from "@/features/auth/api"; import { AdminFormDialog } from "@/shared/ui/AdminFormDialog.jsx"; import { IconButton } from "@/shared/ui/IconButton.jsx"; import { useToast } from "@/shared/ui/ToastProvider.jsx"; const SearchDialog = lazy(() => import("@/features/search/components/SearchDialog.jsx").then((module) => ({ default: module.SearchDialog }))); const emptyPasswordForm = { oldPassword: "", newPassword: "", confirmPassword: "" }; export function Header({ activeLabel, isSidebarCollapsed, menuItems = [], onRefresh, onToggleSidebar }) { const [searchOpen, setSearchOpen] = useState(false); const [searchMounted, setSearchMounted] = useState(false); const [userMenuAnchor, setUserMenuAnchor] = useState(null); const [passwordDialogOpen, setPasswordDialogOpen] = useState(false); const [passwordForm, setPasswordForm] = useState(emptyPasswordForm); const [passwordError, setPasswordError] = useState(""); const [changingPassword, setChangingPassword] = useState(false); const navigate = useNavigate(); const { logout, user } = useAuth(); const appScope = useAppScope(); const { showToast } = useToast(); const { setTimeZone, timeZone, timeZoneOptions } = useTimeZone(); const ToggleIcon = isSidebarCollapsed ? MenuOpen : Menu; const userMenuOpen = Boolean(userMenuAnchor); useEffect(() => { if (searchOpen) { setSearchMounted(true); return undefined; } const timeout = window.setTimeout(() => setSearchMounted(false), 280); return () => window.clearTimeout(timeout); }, [searchOpen]); const openSearch = () => { setSearchMounted(true); setSearchOpen(true); }; const closeUserMenu = () => { setUserMenuAnchor(null); }; const openPasswordDialog = () => { closeUserMenu(); setPasswordForm(emptyPasswordForm); setPasswordError(""); setPasswordDialogOpen(true); }; const closePasswordDialog = () => { if (changingPassword) { return; } setPasswordDialogOpen(false); setPasswordError(""); }; const handleLogout = async () => { closeUserMenu(); await logout(); navigate("/login", { replace: true }); }; const handlePasswordFieldChange = (field) => (event) => { setPasswordForm((current) => ({ ...current, [field]: event.target.value })); if (passwordError) { setPasswordError(""); } }; const handlePasswordSubmit = async (event) => { event.preventDefault(); const { oldPassword, newPassword, confirmPassword } = passwordForm; if (!oldPassword || !newPassword || !confirmPassword) { setPasswordError("请填写原密码、新密码和确认密码"); return; } if (newPassword.length < 6) { setPasswordError("新密码至少 6 位"); return; } if (newPassword.length > 72) { setPasswordError("新密码不能超过 72 位"); return; } if (newPassword !== confirmPassword) { setPasswordError("两次输入的新密码不一致"); return; } setChangingPassword(true); try { await changePassword({ oldPassword, newPassword }); showToast("密码已修改,请重新登录", "success"); await logout(); navigate("/login", { replace: true }); } catch (err) { setPasswordError(err.message || "修改密码失败"); } finally { setChangingPassword(false); } }; const handleSearchSelect = (result) => { if (result?.target) { navigate(result.target); } }; const refresh = () => { onRefresh(); showToast("已刷新当前页面", "success"); }; return (
HYApp 管理平台 Admin Platform
{activeLabel}
appScope.setAppCode(event.target.value)} > {appScope.apps.length ? ( appScope.apps.map((app) => ( {app.appName || app.appCode} )) ) : ( {appScope.appCode} )} setTimeZone(event.target.value)} > {timeZoneOptions.map((option) => ( {option.label} ))} 修改密码 退出
{searchMounted ? ( setSearchOpen(false)} onSelect={handleSearchSelect} /> ) : null}
); }