Files
ai-agent/web/app/dashboard/_components/summary-cards.tsx
T

109 lines
3.2 KiB
TypeScript
Raw Normal View History

2026-04-09 10:01:23 +08:00
"use client"
import Link from "next/link"
import {
BotMessageSquareIcon,
CircleDashedIcon,
HeadsetIcon,
SparklesIcon,
WavesIcon,
} from "lucide-react"
import type { DashboardOverview } from "@/lib/api/dashboard"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
2026-05-25 12:06:15 +08:00
import { useI18n } from "@/i18n/provider"
2026-04-09 10:01:23 +08:00
type SummaryCardsProps = {
summary: DashboardOverview["summary"]
}
type SummaryCardItem = {
key: keyof DashboardOverview["summary"]
2026-05-25 12:06:15 +08:00
titleKey: string
descriptionKey: string
2026-04-09 10:01:23 +08:00
link: string
icon: typeof BotMessageSquareIcon
format?: (value: number) => string
}
const cards: SummaryCardItem[] = [
{
key: "todayNewConversations",
2026-05-25 12:06:15 +08:00
titleKey: "dashboardHome.summaryTodayNewConversations",
descriptionKey: "dashboardHome.summaryTodayNewConversationsDescription",
link: "/dashboard/conversations",
2026-04-09 10:01:23 +08:00
icon: BotMessageSquareIcon,
},
{
key: "processingConversations",
2026-05-25 12:06:15 +08:00
titleKey: "dashboardHome.summaryProcessingConversations",
descriptionKey: "dashboardHome.summaryProcessingConversationsDescription",
link: "/dashboard/conversations",
2026-04-09 10:01:23 +08:00
icon: WavesIcon,
},
{
key: "pendingDispatchConversations",
2026-05-25 12:06:15 +08:00
titleKey: "dashboardHome.summaryPendingDispatchConversations",
descriptionKey: "dashboardHome.summaryPendingDispatchConversationsDescription",
link: "/dashboard/conversations",
2026-04-09 10:01:23 +08:00
icon: CircleDashedIcon,
},
{
key: "onlineAgents",
2026-05-25 12:06:15 +08:00
titleKey: "dashboardHome.summaryOnlineAgents",
descriptionKey: "dashboardHome.summaryOnlineAgentsDescription",
link: "/dashboard/agents",
2026-04-09 10:01:23 +08:00
icon: HeadsetIcon,
},
{
key: "aiServiceRate",
2026-05-25 12:06:15 +08:00
titleKey: "dashboardHome.summaryAiServiceRate",
descriptionKey: "dashboardHome.summaryAiServiceRateDescription",
link: "/dashboard/ai-agents",
2026-04-09 10:01:23 +08:00
icon: SparklesIcon,
format: (value: number) => `${value.toFixed(1)}%`,
},
]
export function SummaryCards({ summary }: SummaryCardsProps) {
2026-05-25 12:06:15 +08:00
const t = useI18n()
2026-04-09 10:01:23 +08:00
return (
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-5">
2026-04-09 10:01:23 +08:00
{cards.map((item) => {
const Icon = item.icon
const rawValue = summary[item.key]
const value =
typeof item.format === "function"
? item.format(Number(rawValue))
: Number(rawValue).toLocaleString()
return (
<Link key={item.key} href={item.link}>
<Card className="h-full rounded-md shadow-none transition-colors hover:border-primary/40">
<CardHeader className="flex flex-row items-start justify-between space-y-0 p-4 pb-2">
2026-04-09 10:01:23 +08:00
<div className="space-y-1">
2026-05-25 12:06:15 +08:00
<CardTitle className="text-sm font-medium">{t(item.titleKey)}</CardTitle>
<CardDescription>{t(item.descriptionKey)}</CardDescription>
2026-04-09 10:01:23 +08:00
</div>
<div className="rounded-md bg-muted p-2 text-muted-foreground">
2026-04-09 10:01:23 +08:00
<Icon className="size-4" />
</div>
</CardHeader>
<CardContent className="px-4 pb-4">
<div className="text-2xl font-semibold tracking-tight">{value}</div>
2026-04-09 10:01:23 +08:00
</CardContent>
</Card>
</Link>
)
})}
</div>
)
}