"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}
) : ( 暂无首页概览数据 )}
) }