Medical
Pain Management Card - Patient Care
Monitor pain management programs and patient pain scores. Track pain relief interventions and patient comfort metrics.
Pain Management Card
The Pain Management Card Track patient pain levels and management interventions.
Preview
Installation
ash npx shadcn@latest add https://vectormotion.vercel.app/registry/pain-management-card.json
Pain Management Card
'use client'import React from 'react';import { Smile, Meh, Frown } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";import { BarChart, Bar, Cell, ResponsiveContainer } from 'recharts';function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}interface PainData { name: string; value: number; color: string; iconType: 'Smile' | 'Meh' | 'Frown'; [key: string]: any;}interface PainManagementCardProps { className?: string; title?: string; subtitle?: string; data?: PainData[];}const DEFAULT_DATA: PainData[] = [ { name: 'Mild', value: 40, color: '#10b981', iconType: 'Smile' }, // emerald { name: 'Mod', value: 45, color: '#f59e0b', iconType: 'Meh' }, // amber { name: 'Severe', value: 15, color: '#ef4444', iconType: 'Frown' }, // red];const DEFAULT_TITLE = "Pain Mgmt";const DEFAULT_SUBTITLE = "Score Distribution";const getIcon = (type: 'Smile' | 'Meh' | 'Frown') => { switch (type) { case 'Smile': return Smile; case 'Meh': return Meh; case 'Frown': return Frown; default: return Meh; }};export const PainManagementCard: React.FC<PainManagementCardProps> = ({ className = "", title = DEFAULT_TITLE, subtitle = DEFAULT_SUBTITLE, data = DEFAULT_DATA,}) => { const isInteractive = true; const index = 24; 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-purple-300 dark:hover:border-purple-700 hover:shadow-md" : "", className )} > <div className="p-5 flex flex-col h-full relative z-10"> <div className="mb-2 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-purple-500"></span> </span> <p className="text-sm text-muted-foreground font-medium"> {subtitle} </p> </div> </div> <div className="rounded-xl bg-purple-50 dark:bg-purple-900/20 p-2.5 text-purple-600 dark:text-purple-400 flex items-center justify-center ring-1 ring-purple-100 dark:ring-purple-800"> <Frown className="h-5 w-5" /> </div> </div> <div className="flex-1 flex flex-col justify-end"> <div className="h-28 w-full"> <ResponsiveContainer width="100%" height="100%"> <BarChart data={data}> <Bar dataKey="value" radius={[4, 4, 0, 0]}> {data.map((entry, index) => ( <Cell key={`cell-${index}`} fill={entry.color} /> ))} </Bar> </BarChart> </ResponsiveContainer> </div> <div className="flex justify-between items-center mt-2 px-1"> {data.map((item, i) => { const Icon = getIcon(item.iconType); return ( <div key={i} className="flex flex-col items-center"> <Icon className="h-3.5 w-3.5 text-muted-foreground mb-0.5" /> <span className="text-[10px] font-bold text-zinc-600 dark:text-zinc-300">{item.value}%</span> </div> ); })} </div> </div> </div> </motion.div> );};Usage
This component is a demo card displaying medical metrics with animated visualizations and dark mode support.
Prop
Type