duoqi-admin/src/components/layout/Sidebar.tsx
Wang Zhuoxuan 0a31f8634e feat: 实现 Phase 3 — UGC 审核、举报处理、运营配置、多管理员
Phase 3a - UGC 审核队列:
- 题目列表添加来源 Tab 切换(全部/官方/用户投稿)
- UGC 审核对话框,支持通过/拒绝并填写备注
- 添加来源列和审核操作入口

Phase 3b - 举报处理:
- 举报列表页面,支持搜索和筛选
- 举报详情对话框,支持驳回/采纳处理
- 5 种举报原因和 4 种处理状态

Phase 3c - 运营配置:
- 设置页面使用 Tabs 布局
- 活动配置:XP 加成、时间范围、状态管理
- 推送文案:模板管理、变量支持、测试发送
- 通用设置:应用级配置项管理

Phase 3d - 多管理员支持:
- 用户名密码登录(替换 Token 登录)
- 管理员管理页面:创建、删除、重置密码
- 角色区分:admin(管理员)/ moderator(审核员)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:38:07 +08:00

79 lines
2.4 KiB
TypeScript

import { NavLink, useNavigate } from "react-router"
import {
LayoutDashboard,
BookOpen,
FolderOpen,
TreePine,
Users,
MessageSquare,
Settings,
LogOut,
FileCheck,
AlertCircle,
Shield,
} from "lucide-react"
import { cn } from "@/lib/utils"
import { useAuth } from "@/hooks/use-auth"
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: "/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()
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">
<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>
)
}