duoqi-admin/src/components/layout/Sidebar.tsx
Wang Zhuoxuan 165625f362
All checks were successful
Build & Deploy Admin / deploy (push) Successful in 28s
feat: 添加当前管理员修改密码功能
在侧边栏底部新增"修改密码"入口,支持输入当前密码和新密码修改自己的登录密码。
2026-04-23 12:34:45 +08:00

96 lines
3.2 KiB
TypeScript

import { useState } from "react"
import { NavLink, useNavigate } from "react-router"
import {
LayoutDashboard,
BookOpen,
FolderOpen,
TreePine,
Users,
MessageSquare,
Settings,
LogOut,
FileCheck,
AlertCircle,
Shield,
BookMarked,
KeyRound,
} from "lucide-react"
import { cn } from "@/lib/utils"
import { useAuth } from "@/hooks/use-auth"
import { ChangePasswordDialog } from "@/components/admin/ChangePasswordDialog"
const navItems = [
{ to: "/", label: "数据看板", icon: LayoutDashboard, end: true },
{ to: "/questions", label: "题库管理", icon: BookOpen },
{ to: "/questions?source=ugc", label: "UGC 审核", icon: FileCheck },
{ to: "/categories", label: "分类管理", icon: FolderOpen },
{ to: "/knowledge-cards", label: "知识卡", icon: BookMarked },
{ to: "/skill-tree", label: "技能树", icon: TreePine },
{ to: "/users", label: "用户管理", icon: Users },
{ to: "/feedback", label: "用户反馈", icon: MessageSquare },
{ to: "/reports", label: "举报处理", icon: AlertCircle },
{ to: "/admins", label: "管理员", icon: Shield },
{ to: "/settings", label: "系统设置", icon: Settings },
]
export function Sidebar() {
const { logout } = useAuth()
const navigate = useNavigate()
const [changePasswordOpen, setChangePasswordOpen] = useState(false)
function handleLogout() {
logout()
navigate("/login")
}
return (
<>
<aside className="flex h-screen w-60 flex-col border-r bg-sidebar-background">
<div className="flex h-14 items-center border-b px-4">
<span className="text-lg font-semibold"></span>
</div>
<nav className="flex-1 space-y-1 p-3">
{navItems.map(({ to, label, icon: Icon, end }) => (
<NavLink
key={to}
to={to}
end={end}
className={({ isActive }) =>
cn(
"flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
isActive
? "bg-sidebar-accent text-sidebar-accent-foreground"
: "text-sidebar-foreground/70 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground",
)
}
>
<Icon className="h-4 w-4" />
{label}
</NavLink>
))}
</nav>
<div className="border-t p-3 space-y-1">
<button
onClick={() => setChangePasswordOpen(true)}
className="flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-sidebar-foreground/70 transition-colors hover:bg-sidebar-accent/50 hover:text-sidebar-foreground"
>
<KeyRound className="h-4 w-4" />
</button>
<button
onClick={handleLogout}
className="flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-sidebar-foreground/70 transition-colors hover:bg-sidebar-accent/50 hover:text-sidebar-foreground"
>
<LogOut className="h-4 w-4" />
退
</button>
</div>
</aside>
<ChangePasswordDialog open={changePasswordOpen} onOpenChange={setChangePasswordOpen} />
</>
)
}