"use client"; import { useEffect, useState } from "react"; import { format } from "date-fns"; import LineChart from "@/components/admin/LineChart"; interface Stats { userCount: number; workspaceCount: number; projectCount: number; roomCount: number; } interface ActivityStats { dau: Array<{ date: string; dau: number }>; mau: number; totalLogins: number; last24h: number; } interface RecentUser { uid: string; username: string; display_name: string | null; created_at: string; } interface RecentWorkspace { id: string; slug: string; name: string; plan: string; memberCount: number; } interface RecentProject { id: string; name: string; workspaceName: string | null; memberCount: number; } interface PlanDist { plan: string; count: number; } const PLAN_LABELS: Record = { free: "免费", starter: "入门", pro: "专业", enterprise: "企业", unknown: "未知", }; export default function DashboardPage() { const [stats, setStats] = useState(null); const [recentUsers, setRecentUsers] = useState([]); const [recentWorkspaces, setRecentWorkspaces] = useState([]); const [recentProjects, setRecentProjects] = useState([]); const [planDistribution, setPlanDistribution] = useState([]); const [activity, setActivity] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { Promise.all([ fetch("/api/platform/stats").then((r) => r.json()), fetch("/api/platform/activity-stats").then((r) => r.json()), ]) .then(([statsData, activityData]) => { if (statsData.stats) setStats(statsData.stats); if (statsData.recentUsers) setRecentUsers(statsData.recentUsers); if (statsData.recentWorkspaces) setRecentWorkspaces(statsData.recentWorkspaces); if (statsData.recentProjects) setRecentProjects(statsData.recentProjects); if (statsData.planDistribution) setPlanDistribution(statsData.planDistribution); if (activityData.dau) setActivity(activityData); }) .catch(console.error) .finally(() => setLoading(false)); }, []); const totalWorkspaces = planDistribution.reduce((sum, p) => sum + p.count, 0); return (

仪表盘

平台概览

{loading ? (
加载中...
) : stats ? ( <>
{stats.userCount.toLocaleString()}
用户总数
{stats.workspaceCount.toLocaleString()}
Workspace 总数
{stats.projectCount.toLocaleString()}
项目总数
{stats.roomCount.toLocaleString()}
聊天室总数
{/* DAU Trend Chart */} {activity && activity.dau.length > 0 && (

DAU 趋势(近30天)

MAU: {activity.mau} 总登录: {activity.totalLogins.toLocaleString()} 近24h: {activity.last24h}
({ date: d.date, value: d.dau }))} label="DAU" color="#6366f1" width={700} height={180} />
)} {/* Workspace Plan Distribution */} {planDistribution.length > 0 && (

Workspace 计划分布

{planDistribution.map((p) => (
{PLAN_LABELS[p.plan] || p.plan} {p.count} ({totalWorkspaces > 0 ? ((p.count / totalWorkspaces) * 100).toFixed(1) : 0}%)
))}
)}

近期注册用户

{recentUsers.length === 0 ? (
暂无数据
) : (
{recentUsers.map((u) => ( ))}
用户名 显示名 注册时间
{u.username} {u.display_name || "-"} {format(new Date(u.created_at), "yyyy-MM-dd")}
)}

近期 Workspace

{recentWorkspaces.length === 0 ? (
暂无数据
) : (
{recentWorkspaces.map((w) => ( ))}
名称 计划 成员
{w.name} {PLAN_LABELS[w.plan] || w.plan} {w.memberCount}
)}
{recentProjects.length > 0 && (

近期项目

{recentProjects.map((p) => ( ))}
名称 所属 Workspace 成员
{p.name} {p.workspaceName || } {p.memberCount}
)} ) : (
无法加载统计数据
)}
); }