import { useState, useEffect } from 'react' import { Outlet, Link, useLocation, useNavigate } from 'react-router-dom' import { LayoutDashboard, Users, CreditCard, Settings, LogOut, Wallet, BookOpen, GitMerge, Crown, GraduationCap, Calendar, User, ShieldCheck, ChevronDown, ChevronUp, } from 'lucide-react' import { get, post } from '@/api/client' import { clearAdminToken } from '@/api/auth' // 主菜单(核心运营 3 项) const primaryMenuItems = [ { icon: LayoutDashboard, label: '数据概览', href: '/dashboard' }, { icon: BookOpen, label: '内容管理', href: '/content' }, { icon: Users, label: '用户管理', href: '/users' }, ] // 折叠区「更多」(字典类 + 业务) const moreMenuItems = [ { icon: Crown, label: 'VIP 角色', href: '/vip-roles' }, { icon: User, label: '作者详情', href: '/author-settings' }, { icon: ShieldCheck, label: '管理员', href: '/admin-users' }, { icon: GraduationCap, label: '导师管理', href: '/mentors' }, { icon: Calendar, label: '导师预约', href: '/mentor-consultations' }, { icon: Wallet, label: '推广中心', href: '/distribution' }, { icon: GitMerge, label: '匹配记录', href: '/match-records' }, { icon: CreditCard, label: '推广设置', href: '/referral-settings' }, ] export function AdminLayout() { const location = useLocation() const navigate = useNavigate() const [mounted, setMounted] = useState(false) const [authChecked, setAuthChecked] = useState(false) const [moreExpanded, setMoreExpanded] = useState(false) useEffect(() => { setMounted(true) }, []) useEffect(() => { const inMore = moreMenuItems.some((item) => location.pathname === item.href) if (inMore) setMoreExpanded(true) }, [location.pathname]) useEffect(() => { if (!mounted) return setAuthChecked(false) let cancelled = false get<{ success?: boolean }>('/api/admin') .then((data) => { if (cancelled) return if (data && (data as { success?: boolean }).success !== false) { setAuthChecked(true) } else { navigate('/login', { replace: true }) } }) .catch(() => { if (!cancelled) navigate('/login', { replace: true }) }) return () => { cancelled = true } }, [mounted, navigate]) const handleLogout = async () => { clearAdminToken() try { await post('/api/admin/logout', {}) } catch { // 忽略登出接口失败,本地已清 token } navigate('/login', { replace: true }) } if (!mounted || !authChecked) { return (
Soul创业派对