Vector Motion
Medical

Patient Admissions Card - Hospital Admissions

Monitor patient admission processes and registration. Track admission flow and bed assignments.

Patient Admissions Card

The Patient Admissions Card Monitor patient admission rates and trends.

Preview

Installation

ash npx shadcn@latest add https://vectormotion.vercel.app/registry/patient-admissions-card.json

Patient Admissions Card
'use client'import React from 'react';import { Users, ArrowRight, TrendingUp } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";import { AreaChart, Area, ResponsiveContainer, XAxis, YAxis, Tooltip } from 'recharts';function cn(...inputs: ClassValue[]) {  return twMerge(clsx(inputs));}interface TrendData {  day: string;  value: number;  [key: string]: any;}interface PatientAdmissionsCardProps {  className?: string;  title?: string;  subtitle?: string;  totalAdmissions?: number;  trendPercentage?: string;  trendDirection?: 'up' | 'down';  trendLabel?: string;  data?: TrendData[];  avatars?: string[];  recentArrivalsCount?: number;}const DEFAULT_TREND_DATA: TrendData[] = [  { day: 'Mon', value: 18 },  { day: 'Tue', value: 22 },  { day: 'Wed', value: 20 },  { day: 'Thu', value: 24 },  { day: 'Fri', value: 28 },  { day: 'Sat', value: 25 },  { day: 'Sun', value: 30 },];const DEFAULT_AVATARS = [  "https://i.pravatar.cc/150?u=1",  "https://i.pravatar.cc/150?u=2",  "https://i.pravatar.cc/150?u=3",  "https://i.pravatar.cc/150?u=4"];const DEFAULT_TITLE = "Admissions";const DEFAULT_SUBTITLE = "Patient In-take Today";const DEFAULT_TOTAL_ADMISSIONS = 30;const DEFAULT_TREND_PERCENTAGE = "+12%";const DEFAULT_TREND_LABEL = "Daily Target Met";const DEFAULT_RECENT_ARRIVALS_COUNT = 8;export const PatientAdmissionsCard: React.FC<PatientAdmissionsCardProps> = ({  className = "",  title = DEFAULT_TITLE,  subtitle = DEFAULT_SUBTITLE,  totalAdmissions = DEFAULT_TOTAL_ADMISSIONS,  trendPercentage = DEFAULT_TREND_PERCENTAGE,  trendDirection = 'up',  trendLabel = DEFAULT_TREND_LABEL,  data = DEFAULT_TREND_DATA,  avatars = DEFAULT_AVATARS,  recentArrivalsCount = DEFAULT_RECENT_ARRIVALS_COUNT,}) => {  const isInteractive = true;  const index = 1;  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-blue-400 dark:hover:border-blue-600 hover:shadow-md" : "",        className      )}    >      <div className="p-5 flex flex-col h-full relative z-10">        <div className="flex items-start justify-between mb-4">          <div>            <h3 className="font-bold text-lg text-foreground">              {title}            </h3>            <p className="text-sm text-muted-foreground mt-1">              {subtitle}            </p>          </div>          <div className="rounded-xl bg-blue-500/10 p-2.5 text-blue-500 flex items-center justify-center ring-1 ring-blue-100 dark:ring-blue-800">            <Users className="h-5 w-5" />          </div>        </div>        <div className="flex items-end justify-between mb-6">          <div>            <div className="flex items-baseline gap-2">              <motion.div                initial={{ opacity: 0, y: 10 }}                animate={{ opacity: 1, y: 0 }}                className="text-4xl font-bold text-foreground tracking-tight"              >                {totalAdmissions}              </motion.div>              <span className="text-sm font-medium text-emerald-500 flex items-center gap-0.5 bg-emerald-500/10 px-1.5 py-0.5 rounded-full border border-emerald-100 dark:border-emerald-800/30">                <TrendingUp className="h-3 w-3" />                {trendPercentage}              </span>            </div>            <p className="text-xs text-muted-foreground font-medium mt-1">{trendLabel}</p>          </div>          <div className="h-12 w-24">            <ResponsiveContainer width="100%" height="100%">              <AreaChart data={data}>                <defs>                  <linearGradient id="admissionGradient" x1="0" y1="0" x2="0" y2="1">                    <stop offset="5%" stopColor="#3b82f6" stopOpacity={0.3} />                    <stop offset="95%" stopColor="#3b82f6" stopOpacity={0} />                  </linearGradient>                </defs>                <Area type="monotone" dataKey="value" stroke="#3b82f6" strokeWidth={2} fill="url(#admissionGradient)" />              </AreaChart>            </ResponsiveContainer>          </div>        </div>        <div className="mt-auto space-y-4">          <div>            <p className="text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider">Recent Arrivals</p>            <div className="flex items-center -space-x-2 overflow-hidden py-1">              {avatars.map((src, i) => (                <motion.img                  key={i}                  initial={{ opacity: 0, x: -10 }}                  animate={{ opacity: 1, x: 0 }}                  transition={{ delay: i * 0.1 }}                  src={src}                  alt="Patient"                  className="inline-block h-9 w-9 rounded-full ring-2 ring-white dark:ring-zinc-900 object-cover shadow-sm"                />              ))}              <motion.div                initial={{ opacity: 0, scale: 0.8 }}                animate={{ opacity: 1, scale: 1 }}                transition={{ delay: 0.4 }}                className="flex h-9 w-9 items-center justify-center rounded-full ring-2 ring-white dark:ring-zinc-900 bg-zinc-100 dark:bg-zinc-800 text-xs font-bold text-zinc-600 dark:text-zinc-300"              >                +{recentArrivalsCount}              </motion.div>            </div>          </div>          <button className="w-full py-2.5 flex items-center justify-center gap-2 rounded-xl bg-muted hover:bg-blue-50 dark:hover:bg-blue-900/20 text-xs font-semibold text-zinc-600 dark:text-zinc-300 hover:text-blue-600 dark:hover:text-blue-400 transition-all group border border-zinc-200 dark:border-zinc-700/50">            View Admission Log            <ArrowRight className="h-3.5 w-3.5 group-hover:translate-x-0.5 transition-transform" />          </button>        </div>      </div>    </motion.div>  );};

Usage

This component is a demo card displaying medical metrics with animated visualizations and dark mode support.

Prop

Type