Medical
Revenue Billing Card - Medical Billing
Monitor healthcare revenue and billing operations. Track claims submission and revenue collection.
Revenue Billing Card
The Revenue Billing Card Track medical billing revenue and collection metrics.
Preview
Installation
ash npx shadcn@latest add https://vectormotion.vercel.app/registry/revenue-billing-card.json
Revenue Billing Card
'use client'import React from 'react';import { DollarSign, FileText, TrendingUp, TrendingDown, ArrowUpRight } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";import { BarChart, Bar, ResponsiveContainer, XAxis, Tooltip, Cell } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}interface ClaimsData { name: string; claims: number; denied: number; [key: string]: any;}interface RevenueBillingCardProps { className?: string; title?: string; subtitle?: string; totalRevenue?: string; revenueGrowth?: string; totalClaimsLabel?: string; pendingClaims?: number; avgAR?: string; data?: ClaimsData[];}const DEFAULT_DATA: ClaimsData[] = [ { name: 'M', claims: 4000, denied: 240 }, { name: 'T', claims: 3000, denied: 139 }, { name: 'W', claims: 2000, denied: 980 }, { name: 'T', claims: 2780, denied: 390 }, { name: 'F', claims: 1890, denied: 480 }, { name: 'S', claims: 2390, denied: 380 }, { name: 'S', claims: 3490, denied: 430 },];const DEFAULT_TITLE = "Revenue Cycle";const DEFAULT_SUBTITLE = "Daily Performance";const DEFAULT_TOTAL_REVENUE = "$42.5k";const DEFAULT_REVENUE_GROWTH = "8%";const DEFAULT_TOTAL_CLAIMS_LABEL = "Total Claims Submitted";const DEFAULT_PENDING_CLAIMS = 142;const DEFAULT_AVG_AR = "18d";export const RevenueBillingCard: React.FC<RevenueBillingCardProps> = ({ className = "", title = DEFAULT_TITLE, subtitle = DEFAULT_SUBTITLE, totalRevenue = DEFAULT_TOTAL_REVENUE, revenueGrowth = DEFAULT_REVENUE_GROWTH, totalClaimsLabel = DEFAULT_TOTAL_CLAIMS_LABEL, pendingClaims = DEFAULT_PENDING_CLAIMS, avgAR = DEFAULT_AVG_AR, data = DEFAULT_DATA,}) => { const isInteractive = true; const index = 10; return ( <motion.div layoutId={isInteractive ? `card-${index}-${title}` : undefined} transition={{ duration: 0.4, ease: "easeOut" }} className={cn( "relative overflow-hidden rounded-2xl border border-border bg-card text-card-foreground shadow-sm transition-all flex flex-col h-full", isInteractive ? "hover:border-primary/50 hover:shadow-md" : "", className )} > <div className="p-5 flex flex-col h-full relative z-10"> <div className="mb-4 flex items-start justify-between"> <div> <h3 className="font-bold text-lg text-foreground"> {title} </h3> <div className="flex items-center gap-1.5 mt-1"> <span className="relative flex h-2 w-2"> <span className="relative inline-flex rounded-full h-2 w-2 bg-emerald-500"></span> </span> <p className="text-sm text-muted-foreground font-medium"> {subtitle} </p> </div> </div> <div className="rounded-xl bg-emerald-500/10 p-2.5 text-emerald-500 flex items-center justify-center ring-1 ring-emerald-100 dark:ring-emerald-800"> <DollarSign className="h-5 w-5" /> </div> </div> <div className="flex-1 flex flex-col justify-between"> <div className="flex items-end justify-between mb-4"> <div> <div className="flex items-baseline gap-1"> <span className="text-3xl font-bold text-foreground tracking-tight">{totalRevenue}</span> <span className="text-sm font-medium text-emerald-500 bg-emerald-500/10 px-1.5 rounded flex items-center transform translate-y-[-2px]"> <ArrowUpRight className="h-3 w-3 mr-0.5" /> {revenueGrowth} </span> </div> <p className="text-xs text-muted-foreground font-medium mt-0.5">{totalClaimsLabel}</p> </div> </div> <div className="h-24 w-full mb-4"> <ResponsiveContainer width="100%" height="100%"> <BarChart data={data} barSize={6}> <Tooltip cursor={{ fill: 'transparent' }} contentStyle={{ borderRadius: '8px', border: 'none', boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)' }} labelStyle={{ display: 'none' }} /> <Bar dataKey="claims" stackId="a" fill="#10b981" radius={[0, 0, 4, 4]} /> <Bar dataKey="denied" stackId="a" fill="#f43f5e" radius={[4, 4, 0, 0]} /> </BarChart> </ResponsiveContainer> </div> <div className="grid grid-cols-2 gap-3"> <div className="p-2.5 bg-muted rounded-xl border border-border flex items-center gap-3"> <div className="h-8 w-8 rounded-lg bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 flex items-center justify-center"> <FileText className="h-4 w-4" /> </div> <div> <div className="text-sm font-bold text-foreground">{pendingClaims}</div> <div className="text-[10px] text-muted-foreground font-medium uppercase tracking-wide">Pending</div> </div> </div> <div className="p-2.5 bg-muted rounded-xl border border-border flex items-center gap-3"> <div className="h-8 w-8 rounded-lg bg-indigo-100 dark:bg-indigo-900/30 text-indigo-600 flex items-center justify-center"> <Clock className="h-4 w-4" /> </div> <div> <div className="text-sm font-bold text-foreground">{avgAR}</div> <div className="text-[10px] text-muted-foreground font-medium uppercase tracking-wide">Avg AR</div> </div> </div> </div> </div> </div> </motion.div> );};// Icon overridefunction Clock(props: any) { return ( <svg {...props} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" > <circle cx="12" cy="12" r="10" /> <polyline points="12 6 12 12 16 14" /> </svg> )}Usage
This component is a demo card displaying medical metrics with animated visualizations and dark mode support.
Prop
Type