refactor: standardize card styles and improve layout across dashboard components

This commit is contained in:
mlogclub
2026-06-21 10:09:52 +08:00
parent ff2e2e3962
commit fe5041191f
20 changed files with 91 additions and 74 deletions
+3 -3
View File
@@ -32,14 +32,14 @@ export function AlertList({ alerts }: AlertListProps) {
const t = useI18n()
return (
<Card>
<Card className="rounded-md shadow-none">
<CardHeader>
<CardTitle>{t("dashboardHome.riskAlerts")}</CardTitle>
<CardDescription>{t("dashboardHome.riskAlertsDescription")}</CardDescription>
</CardHeader>
<CardContent className="space-y-3">
{alerts.length === 0 ? (
<div className="rounded-2xl border border-dashed px-4 py-10 text-center">
<div className="rounded-md border border-dashed px-4 py-10 text-center">
<ShieldAlertIcon className="mx-auto mb-3 size-8 text-muted-foreground" />
<div className="text-sm font-medium">{t("dashboardHome.noRiskTitle")}</div>
<div className="mt-1 text-sm text-muted-foreground">
@@ -49,7 +49,7 @@ export function AlertList({ alerts }: AlertListProps) {
) : (
alerts.map((item) => (
<Link key={item.id} href={item.link} className="block">
<div className="rounded-2xl border p-4 transition-colors hover:border-primary/40">
<div className="rounded-md border p-4 transition-colors hover:border-primary/40">
<div className="flex items-start justify-between gap-3">
<div>
<div className="flex items-center gap-2">
@@ -22,8 +22,8 @@ function LoadingCards() {
return (
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-6">
{Array.from({ length: 6 }).map((_, index) => (
<Card key={index}>
<CardContent className="space-y-3 p-6">
<Card key={index} className="rounded-md shadow-none">
<CardContent className="space-y-3 p-4">
<Skeleton className="h-4 w-24" />
<Skeleton className="h-8 w-20" />
<Skeleton className="h-4 w-full" />
@@ -72,7 +72,7 @@ export function DashboardHome() {
]
return (
<div className="flex flex-1 flex-col gap-6 p-4 lg:p-6">
<div className="flex flex-1 flex-col gap-4 p-4 lg:p-5">
<div className="flex flex-col gap-3 xl:flex-row xl:items-start xl:justify-between">
<div>
<h1 className="text-2xl font-semibold tracking-tight">{t("dashboardHome.title")}</h1>
@@ -82,7 +82,7 @@ export function DashboardHome() {
</p>
</div>
<div className="flex flex-wrap items-center gap-2">
<div className="rounded-xl border bg-muted/30 p-1">
<div className="rounded-md border bg-background p-1">
{rangeOptions.map((item) => (
<Button
key={item.value}
@@ -122,37 +122,37 @@ export function DashboardHome() {
<div className="grid gap-4 xl:grid-cols-[1.15fr_0.85fr]">
<TeamLoadPanel agentStats={data.agentStats} />
<Card>
<CardContent className="grid gap-4 p-6 sm:grid-cols-2">
<div className="rounded-2xl border bg-muted/30 p-4">
<Card className="rounded-md shadow-none">
<CardContent className="grid gap-3 p-4 sm:grid-cols-2">
<div className="rounded-md border bg-background px-3 py-2.5">
<div className="text-sm text-muted-foreground">{t("dashboardHome.enabledAiAgents")}</div>
<div className="mt-2 text-3xl font-semibold">{data.aiStats.enabledAiAgents}</div>
<div className="mt-1 text-2xl font-semibold">{data.aiStats.enabledAiAgents}</div>
</div>
<div className="rounded-2xl border bg-muted/30 p-4">
<div className="rounded-md border bg-background px-3 py-2.5">
<div className="text-sm text-muted-foreground">{t("dashboardHome.enabledChannels")}</div>
<div className="mt-2 text-3xl font-semibold">{data.aiStats.enabledChannels}</div>
<div className="mt-1 text-2xl font-semibold">{data.aiStats.enabledChannels}</div>
</div>
<div className="rounded-2xl border bg-muted/30 p-4">
<div className="rounded-md border bg-background px-3 py-2.5">
<div className="text-sm text-muted-foreground">{t("dashboardHome.todayKnowledgeRetrieves")}</div>
<div className="mt-2 text-3xl font-semibold">
<div className="mt-1 text-2xl font-semibold">
{data.aiStats.todayKnowledgeRetrieves}
</div>
</div>
<div className="rounded-2xl border bg-muted/30 p-4">
<div className="rounded-md border bg-background px-3 py-2.5">
<div className="text-sm text-muted-foreground">{t("dashboardHome.todayKnowledgeRetrieveFailRate")}</div>
<div className="mt-2 text-3xl font-semibold">
<div className="mt-1 text-2xl font-semibold">
{data.aiStats.todayKnowledgeRetrieveFailRate.toFixed(1)}%
</div>
</div>
<div className="rounded-2xl border bg-muted/30 p-4">
<div className="rounded-md border bg-background px-3 py-2.5">
<div className="text-sm text-muted-foreground">{t("dashboardHome.todaySkillRunFailCount")}</div>
<div className="mt-2 text-3xl font-semibold">
<div className="mt-1 text-2xl font-semibold">
{data.aiStats.todaySkillRunFailCount}
</div>
</div>
<div className="rounded-2xl border bg-muted/30 p-4">
<div className="rounded-md border bg-background px-3 py-2.5">
<div className="text-sm text-muted-foreground">{t("dashboardHome.todayAiHandoffCount")}</div>
<div className="mt-2 text-3xl font-semibold">
<div className="mt-1 text-2xl font-semibold">
{data.aiStats.todayAiHandoffCount}
</div>
</div>
@@ -163,7 +163,7 @@ export function DashboardHome() {
<AlertList alerts={data.alerts} />
</>
) : (
<Card>
<Card className="rounded-md shadow-none">
<CardContent className="flex min-h-60 items-center justify-center p-6 text-sm text-muted-foreground">
{t("dashboardHome.empty")}
</CardContent>
@@ -75,7 +75,7 @@ export function SummaryCards({ summary }: SummaryCardsProps) {
const t = useI18n()
return (
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-6">
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-5">
{cards.map((item) => {
const Icon = item.icon
const rawValue = summary[item.key]
@@ -86,18 +86,18 @@ export function SummaryCards({ summary }: SummaryCardsProps) {
return (
<Link key={item.key} href={item.link}>
<Card className="h-full transition-colors hover:border-primary/40">
<CardHeader className="flex flex-row items-start justify-between space-y-0 pb-3">
<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">
<div className="space-y-1">
<CardTitle className="text-sm font-medium">{t(item.titleKey)}</CardTitle>
<CardDescription>{t(item.descriptionKey)}</CardDescription>
</div>
<div className="rounded-full bg-primary/10 p-2 text-primary">
<div className="rounded-md bg-muted p-2 text-muted-foreground">
<Icon className="size-4" />
</div>
</CardHeader>
<CardContent>
<div className="text-3xl font-semibold tracking-tight">{value}</div>
<CardContent className="px-4 pb-4">
<div className="text-2xl font-semibold tracking-tight">{value}</div>
</CardContent>
</Card>
</Link>
@@ -29,7 +29,7 @@ export function TeamLoadPanel({ agentStats }: TeamLoadPanelProps) {
const t = useI18n()
return (
<Card>
<Card className="rounded-md shadow-none">
<CardHeader>
<CardTitle>{t("dashboardHome.teamLoad")}</CardTitle>
<CardDescription>
@@ -42,12 +42,12 @@ export function TeamLoadPanel({ agentStats }: TeamLoadPanelProps) {
</CardHeader>
<CardContent className="space-y-4">
{agentStats.teamLoads.length === 0 ? (
<div className="rounded-xl border border-dashed px-4 py-8 text-center text-sm text-muted-foreground">
<div className="rounded-md border border-dashed px-4 py-8 text-center text-sm text-muted-foreground">
{t("dashboardHome.noTeamData")}
</div>
) : (
agentStats.teamLoads.map((item) => (
<div key={item.teamId} className="rounded-2xl border p-4">
<div key={item.teamId} className="rounded-md border p-4">
<div className="flex flex-wrap items-center justify-between gap-3">
<div>
<div className="flex items-center gap-2">
@@ -86,19 +86,19 @@ export function TeamLoadPanel({ agentStats }: TeamLoadPanelProps) {
</div>
<div className="mt-4 grid gap-3 text-sm md:grid-cols-2 xl:grid-cols-4">
<div className="rounded-xl bg-muted/40 px-3 py-2">
<div className="rounded-md bg-muted/35 px-3 py-2">
<div className="text-muted-foreground">{t("dashboardHome.waiting")}</div>
<div className="mt-1 text-lg font-semibold">{item.waitingConversations}</div>
</div>
<div className="rounded-xl bg-muted/40 px-3 py-2">
<div className="rounded-md bg-muted/35 px-3 py-2">
<div className="text-muted-foreground">{t("dashboardHome.processing")}</div>
<div className="mt-1 text-lg font-semibold">{item.processingConversations}</div>
</div>
<div className="rounded-xl bg-muted/40 px-3 py-2">
<div className="rounded-md bg-muted/35 px-3 py-2">
<div className="text-muted-foreground">{t("dashboardHome.capacity")}</div>
<div className="mt-1 text-lg font-semibold">{item.maxConcurrentCapacity}</div>
</div>
<div className="rounded-xl bg-muted/40 px-3 py-2">
<div className="rounded-md bg-muted/35 px-3 py-2">
<div className="text-muted-foreground">{t("dashboardHome.busyAgents")}</div>
<div className="mt-1 text-lg font-semibold">{item.busyAgents}</div>
</div>
@@ -58,7 +58,7 @@ export function TrendPanel({
return (
<div className="grid gap-4 xl:grid-cols-[1.5fr_0.9fr]">
<Card>
<Card className="rounded-md shadow-none">
<CardHeader>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
@@ -90,7 +90,7 @@ export function TrendPanel({
</CardContent>
</Card>
<Card>
<Card className="rounded-md shadow-none">
<CardHeader>
<CardTitle>{t("dashboardHome.statusDistribution")}</CardTitle>
<CardDescription>{t("dashboardHome.statusDistributionDescription")}</CardDescription>