Vector Motion
Medical

Telemedicine Queue Card - Virtual Care

Monitor telemedicine queue and virtual appointment status. Track telehealth wait times and utilization.

Telemedicine Queue Card

The Telemedicine Queue Card Track telemedicine appointment queue and virtual visit status.

Preview

Installation

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

Telemedicine Queue Card
'use client'import React from 'react';import { Video, User, Clock, MoreVertical } from 'lucide-react';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";function cn(...inputs: ClassValue[]) {   return twMerge(clsx(inputs));}interface QueueItem {   id: string;   label: string;   waitTime: string;   [key: string]: any;}interface ActiveSession {   name: string;   condition: string;}interface TelemedicineQueueCardProps {   className?: string;   title?: string;   subtitle?: string;   activeSession?: ActiveSession;   queue?: QueueItem[];}const DEFAULT_ACTIVE_SESSION: ActiveSession = {   name: "James M.",   condition: "Flu Symptoms",};const DEFAULT_QUEUE: QueueItem[] = [   { id: '#420', label: 'Waitlist', waitTime: '5m' },   { id: '#421', label: 'Waitlist', waitTime: '15m' },];const DEFAULT_TITLE = "Virtual Queue";const DEFAULT_SUBTITLE = "Telehealth Status";export const TelemedicineQueueCard: React.FC<TelemedicineQueueCardProps> = ({   className = "",   title = DEFAULT_TITLE,   subtitle = DEFAULT_SUBTITLE,   activeSession = DEFAULT_ACTIVE_SESSION,   queue = DEFAULT_QUEUE,}) => {   const isInteractive = true;   const index = 9;   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-cyan-300 dark:hover:border-cyan-700 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-cyan-500"></span>                     </span>                     <p className="text-sm text-muted-foreground font-medium">                        {subtitle}                     </p>                  </div>               </div>               <div className="rounded-xl bg-cyan-50 dark:bg-cyan-900/20 p-2.5 text-cyan-600 dark:text-cyan-400 flex items-center justify-center ring-1 ring-cyan-100 dark:ring-cyan-800">                  <Video className="h-5 w-5" />               </div>            </div>            <div className="flex-1 space-y-4">               {/* Active Session Card */}               <div className="relative overflow-hidden bg-cyan-500 text-white p-3 rounded-xl shadow-sm">                  <div className="flex justify-between items-start mb-2">                     <span className="inline-flex items-center gap-1.5 bg-white/20 px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-wider">                        <span className="h-1.5 w-1.5 bg-green-400 rounded-full animate-pulse" /> Live                     </span>                     <Clock className="h-3.5 w-3.5 opacity-80" />                  </div>                  <div className="flex items-center gap-3">                     <div className="h-8 w-8 rounded-full bg-white/20 flex items-center justify-center font-bold text-sm border border-white/30">                        <User className="h-4 w-4" />                     </div>                     <div>                        <p className="text-sm font-bold">{activeSession.name}</p>                        <p className="text-xs opacity-80">{activeSession.condition}</p>                     </div>                  </div>                  {/* Abstract waveform visual */}                  <div className="absolute -bottom-2 right-0 left-0 flex gap-1 justify-end opacity-20 px-2">                     {[1, 2, 3, 4, 5, 6].map(i => (                        <motion.div                           key={i}                           animate={{ height: [4, 12, 6, 16, 8] }}                           transition={{ duration: 1.5, repeat: Infinity, delay: i * 0.1 }}                           className="w-1 bg-white rounded-t-full"                        />                     ))}                  </div>               </div>               {/* Queue List */}               <div>                  <p className="text-xs font-semibold text-muted-foreground mb-2 uppercase tracking-wide px-1">Up Next</p>                  <div className="space-y-2">                     {queue.map((item, i) => (                        <div key={i} className="flex items-center justify-between p-2 rounded-lg bg-muted/30 border border-border/50">                           <div className="flex items-center gap-2">                              <div className="h-6 w-6 rounded-full bg-zinc-200 dark:bg-zinc-700 flex items-center justify-center text-[10px] text-muted-foreground font-bold">                                 {item.id}                              </div>                              <span className="text-sm font-medium text-foreground">{item.label}</span>                           </div>                           <span className="text-xs text-muted-foreground font-medium">{item.waitTime}</span>                        </div>                     ))}                  </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