"use client"
import { useCallback, useEffect, useState } from "react"
import { RefreshCwIcon } from "lucide-react"
import { toast } from "sonner"
import { Button } from "@/components/ui/button"
import { Skeleton } from "@/components/ui/skeleton"
import { Card, CardContent } from "@/components/ui/card"
import {
fetchDashboardOverview,
type DashboardOverview,
type DashboardRange,
} from "@/lib/api/dashboard"
import { SummaryCards } from "./_components/summary-cards"
import { TrendPanel } from "./_components/trend-panel"
import { TeamLoadPanel } from "./_components/team-load-panel"
import { AlertList } from "./_components/alert-list"
const rangeOptions: Array<{ value: DashboardRange; label: string }> = [
{ value: "today", label: "今天" },
{ value: "7d", label: "近 7 天" },
{ value: "30d", label: "近 30 天" },
]
function LoadingCards() {
return (
{Array.from({ length: 6 }).map((_, index) => (
))}
)
}
export default function DashboardPage() {
const [range, setRange] = useState("7d")
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [refreshing, setRefreshing] = useState(false)
const loadData = useCallback(
async (nextRange: DashboardRange, showRefreshing = false) => {
if (showRefreshing) {
setRefreshing(true)
} else {
setLoading(true)
}
try {
const result = await fetchDashboardOverview(nextRange)
setData(result)
} catch (error) {
toast.error(error instanceof Error ? error.message : "加载首页概览失败")
} finally {
setLoading(false)
setRefreshing(false)
}
},
[]
)
useEffect(() => {
void loadData(range)
}, [loadData, range])
return (
后台总览
聚焦会话接待、工单处理、客服负载与 AI 运行状态
{data ? `,更新于 ${data.generatedAt}` : ""}
{rangeOptions.map((item) => (
))}
{loading && !data ? (
) : data ? (
<>
启用中的 AI Agent
{data.aiStats.enabledAiAgents}
启用中的接入渠道
{data.aiStats.enabledChannels}
今日知识检索次数
{data.aiStats.todayKnowledgeRetrieves}
今日检索失败率
{data.aiStats.todayKnowledgeRetrieveFailRate.toFixed(1)}%
今日 Skill 失败次数
{data.aiStats.todaySkillRunFailCount}
今日 AI 转人工次数
{data.aiStats.todayAiHandoffCount}
>
) : (
暂无首页概览数据
)}
)
}