Add Today dashboard foundation with permission-aware KPI summary API.
Replace hardcoded Today cards with a backend summary endpoint and composable frontend widgets filtered by org type and tab permissions. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
47
frontend/src/components/today/KpiCard.tsx
Normal file
47
frontend/src/components/today/KpiCard.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
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;
|
||||
}
|
||||
|
||||
export function KpiCard({
|
||||
title,
|
||||
value,
|
||||
subtitle,
|
||||
icon: Icon,
|
||||
color = 'default',
|
||||
loading = false,
|
||||
}: KpiCardProps) {
|
||||
return (
|
||||
<Card className={colorClasses[color]}>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user