mirror of
https://github.com/paperclipai/paperclip
synced 2026-03-25 11:21:48 +00:00
54 lines
1.4 KiB
TypeScript
54 lines
1.4 KiB
TypeScript
import type { LucideIcon } from "lucide-react";
|
|
import type { ReactNode } from "react";
|
|
import { Link } from "@/lib/router";
|
|
|
|
interface MetricCardProps {
|
|
icon: LucideIcon;
|
|
value: string | number;
|
|
label: string;
|
|
description?: ReactNode;
|
|
to?: string;
|
|
onClick?: () => void;
|
|
}
|
|
|
|
export function MetricCard({ icon: Icon, value, label, description, to, onClick }: MetricCardProps) {
|
|
const isClickable = !!(to || onClick);
|
|
|
|
const inner = (
|
|
<div className={`h-full px-4 py-4 sm:px-5 sm:py-5 rounded-lg transition-colors${isClickable ? " hover:bg-accent/50 cursor-pointer" : ""}`}>
|
|
<div className="flex items-start justify-between gap-3">
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-2xl sm:text-3xl font-semibold tracking-tight">
|
|
{value}
|
|
</p>
|
|
<p className="text-xs sm:text-sm font-medium text-muted-foreground mt-1">
|
|
{label}
|
|
</p>
|
|
{description && (
|
|
<div className="text-xs text-muted-foreground/70 mt-1.5 hidden sm:block">{description}</div>
|
|
)}
|
|
</div>
|
|
<Icon className="h-4 w-4 text-muted-foreground/50 shrink-0 mt-1.5" />
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
if (to) {
|
|
return (
|
|
<Link to={to} className="no-underline text-inherit h-full" onClick={onClick}>
|
|
{inner}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
if (onClick) {
|
|
return (
|
|
<div className="h-full" onClick={onClick}>
|
|
{inner}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return inner;
|
|
}
|