Base para el flujo de ramas por cliente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
97 lines
2.0 KiB
TypeScript
97 lines
2.0 KiB
TypeScript
import type { ElementType } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
interface KpiCardProps {
|
|
title: string;
|
|
icon: ElementType;
|
|
value: string | number;
|
|
subtitle: string;
|
|
action?: { label: string; to: string };
|
|
}
|
|
|
|
export default function DashboardKpiCard({
|
|
title,
|
|
icon: Icon,
|
|
value,
|
|
subtitle,
|
|
action,
|
|
}: KpiCardProps) {
|
|
const navigate = useNavigate();
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
background: "var(--color-surface)",
|
|
border: "1px solid var(--color-border)",
|
|
borderRadius: "8px",
|
|
padding: "20px",
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
gap: "12px",
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
justifyContent: "space-between",
|
|
alignItems: "flex-start",
|
|
}}
|
|
>
|
|
<span
|
|
style={{
|
|
fontSize: "0.75rem",
|
|
fontWeight: 600,
|
|
color: "var(--color-text-muted)",
|
|
textTransform: "uppercase",
|
|
letterSpacing: "0.04em",
|
|
}}
|
|
>
|
|
{title}
|
|
</span>
|
|
<Icon
|
|
size={20}
|
|
style={{ color: "var(--color-text-muted)", flexShrink: 0 }}
|
|
/>
|
|
</div>
|
|
|
|
<span
|
|
style={{
|
|
fontSize: "2rem",
|
|
fontWeight: 700,
|
|
color: "var(--color-primary)",
|
|
lineHeight: 1,
|
|
}}
|
|
>
|
|
{value}
|
|
</span>
|
|
|
|
<span
|
|
style={{
|
|
fontSize: "0.75rem",
|
|
color: "var(--color-text-muted)",
|
|
}}
|
|
>
|
|
{subtitle}
|
|
</span>
|
|
|
|
{action && (
|
|
<button
|
|
onClick={() => navigate(action.to)}
|
|
style={{
|
|
background: "var(--color-primary)",
|
|
color: "#fff",
|
|
border: "none",
|
|
padding: "6px 12px",
|
|
fontSize: "0.75rem",
|
|
fontWeight: 500,
|
|
cursor: "pointer",
|
|
borderRadius: "4px",
|
|
alignSelf: "flex-start",
|
|
}}
|
|
>
|
|
{action.label}
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
} |