'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { useAuth } from '@/components/admin/auth-context'; import { adminApi } from '@/lib/admin-api'; import { FileText, Briefcase, Box, Layers, Image, BarChart3, Newspaper, Settings, Users, Bell, Clock, AlertCircle, CheckCircle, XCircle, Archive, } from 'lucide-react'; interface DashboardStats { models: number; items: number; zones: number; activeUsers: number; pendingReviews: number; unreadNotifications: number; modelItemCounts: Array<{ modelCode: string; count: number }>; statusCounts: Array<{ status: string; count: number }>; recentNotifications: Array<{ id: string; type: string; title: string; read: boolean; createdAt: string; }>; recentItems: Array<{ id: string; title: string; modelCode: string; status: string; updatedAt: string; }>; } const modelCards = [ { code: 'news', name: '新闻资讯', icon: Newspaper, color: 'bg-blue-50 text-blue-600' }, { code: 'case-study', name: '案例研究', icon: Briefcase, color: 'bg-amber-50 text-amber-600' }, { code: 'service', name: '服务管理', icon: Settings, color: 'bg-green-50 text-green-600' }, { code: 'product', name: '产品管理', icon: Box, color: 'bg-purple-50 text-purple-600' }, { code: 'solution', name: '解决方案', icon: Layers, color: 'bg-teal-50 text-teal-600' }, { code: 'hero-banner', name: 'Hero Banner', icon: Image, color: 'bg-rose-50 text-rose-600' }, { code: 'stat-item', name: '数据指标', icon: BarChart3, color: 'bg-indigo-50 text-indigo-600' }, ]; const MODEL_LABELS: Record = { news: '新闻资讯', 'case-study': '案例研究', service: '服务管理', product: '产品管理', solution: '解决方案', 'hero-banner': 'Hero Banner', 'stat-item': '数据指标', 'about-page': '关于我们', 'team-page': '团队介绍', 'contact-page': '联系我们', 'legal-page': '法律页面', 'standalone-product': '独立产品', }; const STATUS_LABELS: Record = { draft: '草稿', review: '待审核', published: '已发布', archived: '已归档', }; const STATUS_COLORS: Record = { draft: 'bg-gray-100 text-gray-700', review: 'bg-amber-100 text-amber-700', published: 'bg-green-100 text-green-700', archived: 'bg-red-100 text-red-700', }; const NOTIFICATION_TYPE_ICONS: Record = { review_pending: , review_approved: , review_rejected: , item_archived: , }; export default function AdminDashboardPage() { const { user, loading: authLoading } = useAuth(); const router = useRouter(); const [stats, setStats] = useState(null); const [fetching, setFetching] = useState(true); useEffect(() => { if (!authLoading && !user) { router.push('/admin/login'); return; } if (user) { adminApi.request('/api/admin/stats') .then((s) => setStats(s)) .catch(console.error) .finally(() => setFetching(false)); } }, [user, authLoading, router]); if (authLoading || (!user && typeof window !== 'undefined')) { return (
); } return (

仪表盘

欢迎回来,{user?.nickname || user?.username}

{/* Stats cards */}
{[ { label: '内容模型', value: stats?.models ?? '-', icon: FileText, color: 'bg-blue-50' }, { label: '内容条目', value: stats?.items ?? '-', icon: Layers, color: 'bg-purple-50' }, { label: '页面区域', value: stats?.zones ?? '-', icon: Briefcase, color: 'bg-amber-50' }, { label: '活跃用户', value: stats?.activeUsers ?? '-', icon: Users, color: 'bg-green-50' }, { label: '待审核', value: stats?.pendingReviews ?? '-', icon: AlertCircle, color: 'bg-red-50', highlight: (stats?.pendingReviews ?? 0) > 0, }, { label: '未读通知', value: stats?.unreadNotifications ?? '-', icon: Bell, color: 'bg-indigo-50', highlight: (stats?.unreadNotifications ?? 0) > 0, }, ].map((stat) => (

{stat.label}

{fetching ? '-' : stat.value}

))}
{/* Content status distribution */}

内容状态分布

{fetching ? (
加载中...
) : !stats?.statusCounts?.length ? (
暂无数据
) : (
{stats.statusCounts.map((s) => (
{STATUS_LABELS[s.status] || s.status} {s.count}
))}
)}
{/* Recent notifications */}

最近通知

{fetching ? (
加载中...
) : !stats?.recentNotifications?.length ? (
暂无通知
) : (
{stats.recentNotifications.map((n) => (
{NOTIFICATION_TYPE_ICONS[n.type] || }

{n.title}

{new Date(n.createdAt).toLocaleDateString('zh-CN')}

{!n.read &&
}
))}
)}
{/* Recent content updates */}

最近更新

{fetching ? (
加载中...
) : !stats?.recentItems?.length ? (
暂无更新
) : (
{stats.recentItems.map((item) => ( ))}
)}
{/* Quick links */}

内容管理

{modelCards.map((card) => { const count = stats?.modelItemCounts?.find((m) => m.modelCode === card.code)?.count; return ( ); })}
); }