Invoice KPI Card
ManpowerHub metric card with sparkline trend chart.
import { InvoiceKpiCard } from "@/registry/new-york/items/manpowerhub-invoice-kpi/components/invoice-kpi";
export function ManpowerhubInvoiceKpiBasic() { return ( <div className="grid grid-cols-2 gap-3 p-4 lg:grid-cols-4"> <InvoiceKpiCard label="Total invoices" value="22" sublabel="All PI records in the system" trendData={[18, 19, 19, 20, 20, 21, 22]} accent="neutral" /> <InvoiceKpiCard label="Pending approval" value="6" sublabel="Awaiting sign-off" trendData={[2, 3, 4, 3, 5, 5, 6]} accent="amber" /> <InvoiceKpiCard label="Total billed" value={<span className="text-[var(--brand)]">AED 60,481.00</span>} sublabel="Sum of grant totals (AED)" trendData={[42000, 44000, 48000, 51000, 55000, 58000, 60481]} accent="brand" /> <InvoiceKpiCard label="VAT collected" value="AED 1,380.00" sublabel="Total VAT across all invoices" trendData={[900, 980, 1050, 1100, 1180, 1280, 1380]} accent="neutral" /> </div> );}Installation
Section titled “Installation”This installation provides support for all official Shadcn icon libraries. The component is otherwise identical to the non-experimental installation.
Icon support is experimental and may not be fully stable since it uses internal Shadcn APIs.
This component relies on other items which must be installed first.
Install the following dependencies.
Copy and paste the following code into your project.
components/ui/invoice-kpi.tsx
"use client";
import * as React from "react";import { Area, AreaChart, ResponsiveContainer } from "recharts";
import { cn } from "@/lib/utils";
const accentColors = { brand: "var(--brand)", amber: "var(--amber)", red: "var(--red)", neutral: "var(--text-3)",} as const;
export interface InvoiceKpiCardProps extends React.ComponentProps<"div"> { label: string; value: React.ReactNode; sublabel?: string; trendData: number[]; accent?: keyof typeof accentColors;}
function InvoiceKpiCard({ className, label, value, sublabel, trendData, accent = "brand", ...props}: InvoiceKpiCardProps) { const id = React.useId(); const color = accentColors[accent]; const data = trendData.map((v, i) => ({ i, v }));
return ( <div data-slot="invoice-kpi-card" className={cn( "cursor-default rounded-[var(--r-lg)] border border-border bg-card p-4 transition-[border-color,box-shadow] hover:border-[var(--color-border-strong)] hover:shadow-[var(--shadow)] md:px-[18px] md:py-4", className, )} {...props} > <div className="mb-2 flex items-start justify-between gap-2"> <span className="text-[11px] font-medium uppercase tracking-[0.4px] text-[var(--text-3)]"> {label} </span> <div className="shrink-0"> <ResponsiveContainer width={80} height={32}> <AreaChart data={data} margin={{ top: 2, right: 0, left: 0, bottom: 2 }} > <defs> <linearGradient id={`invoice-kpi-grad-${id}`} x1="0" y1="0" x2="0" y2="1" > <stop offset="0%" stopColor={color} stopOpacity={0.35} /> <stop offset="100%" stopColor={color} stopOpacity={0} /> </linearGradient> </defs> <Area type="monotone" dataKey="v" stroke={color} strokeWidth={1.5} fill={`url(#invoice-kpi-grad-${id})`} dot={false} isAnimationActive={false} /> </AreaChart> </ResponsiveContainer> </div> </div> <div className="mb-1.5 text-[26px] leading-none font-extrabold tracking-[-0.5px] text-foreground"> {value} </div> {sublabel ? ( <p className="text-[11.5px] text-[var(--text-3)]">{sublabel}</p> ) : null} </div> );}
export { InvoiceKpiCard };Update the import paths to match your project setup.
Install the ManpowerHub theme first, then add this component:
npx shadcn@latest add https://woxcn-registry.woxware.io/r/manpowerhub-invoice-kpi.jsonPass a trendData array of 7 numbers and an accent to control the sparkline color (brand, amber, red, or neutral).