Files
dyolink/frontend/src/components/today/KpiCard.tsx
Admin 3f2b332bd3 Add Today action lists and clickable KPI links (Phase 3).
Show upcoming appointments for the rest of today and link each KPI card to its relevant dashboard tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 00:48:35 +03:30

63 lines
1.9 KiB
TypeScript

import { Link } from '@/i18n/navigation';
import { Card } from '@/components/ui/shared/Card';
import type { KpiCardColor } from '@/components/today/widget-registry';
import type { LucideIcon } from 'lucide-react';
const colorClasses: Record<KpiCardColor, string> = {
blue: '!bg-purpose-visit-bg !text-purpose-visit-fg !border-purpose-visit-border',
yellow: '!bg-badge-warning-bg !text-badge-warning-fg !border-badge-warning-border',
green: '!bg-badge-success-bg !text-badge-success-fg !border-badge-success-border',
red: '!bg-badge-danger-bg !text-badge-danger-fg !border-badge-danger-border',
purple: '!bg-purpose-consultation-bg !text-purpose-consultation-fg !border-purpose-consultation-border',
default: '',
};
interface KpiCardProps {
title: string;
value: string;
subtitle?: string | null;
icon?: LucideIcon;
color?: KpiCardColor;
loading?: boolean;
href?: string;
}
export function KpiCard({
title,
value,
subtitle,
icon: Icon,
color = 'default',
loading = false,
href,
}: KpiCardProps) {
const card = (
<Card
className={`${colorClasses[color]} ${href && !loading ? 'transition-opacity hover:opacity-90' : ''}`}
>
<div className="flex items-start justify-between gap-3">
<p className="text-sm font-medium">{title}</p>
{Icon ? <Icon className="h-4 w-4 shrink-0 opacity-80" aria-hidden /> : null}
</div>
{loading ? (
<div className="mt-2 h-8 w-16 animate-pulse rounded bg-current/10" />
) : (
<p className="text-2xl font-bold mt-2">{value}</p>
)}
{subtitle ? (
<p className="text-xs opacity-80 mt-1">{subtitle}</p>
) : null}
</Card>
);
if (href && !loading) {
return (
<Link href={href} className="block focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60 rounded-[var(--radius-lg)]">
{card}
</Link>
);
}
return card;
}