refactor: standardize card styles and improve layout across dashboard components
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user