Vector Motion
Medical

Ambulance Status Card - Emergency Services

Monitor ambulance fleet status and emergency response availability. Track vehicle locations and response times.

Ambulance Status Card

The Ambulance Status Card Monitor ambulance fleet status and availability in real-time.

Preview

Installation

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

Ambulance Status Card
'use client'import React from 'react';import { Truck, MapPin, Navigation, Clock } 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 UnitData {   id: string;   status: string;   type: string;   dispatchId: string;   eta: string;   distance: string;   progress: number;}interface AmbulanceStatusCardProps {   className?: string;   title?: string;   subtitle?: string;   activeUnit?: UnitData;   availableUnits?: {      bls: number;      als: number;      critical: number;   };}const DEFAULT_ACTIVE_UNIT: UnitData = {   id: "42",   status: "IN TRANSIT",   type: "Emergency Response",   dispatchId: "Dispatch #8921",   eta: "4 min",   distance: "1.2 mi",   progress: 75};const DEFAULT_AVAILABLE_UNITS = {   bls: 18,   als: 5,   critical: 2};const DEFAULT_TITLE = "Ambulance";const DEFAULT_SUBTITLE = "Fleet Status";export const AmbulanceStatusCard: React.FC<AmbulanceStatusCardProps> = ({   className = "",   title = DEFAULT_TITLE,   subtitle = DEFAULT_SUBTITLE,   activeUnit = DEFAULT_ACTIVE_UNIT,   availableUnits = DEFAULT_AVAILABLE_UNITS}) => {   const isInteractive = true;   const index = 20;   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-red-300 dark:hover:border-red-700 hover:shadow-md" : "",            className         )}      >         <div className="absolute top-0 right-0 w-32 h-32 bg-red-500/5 rounded-full blur-3xl -mr-16 -mt-16 pointer-events-none" />         <div className="p-5 flex flex-col h-full relative z-10">            <div className="mb-5 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="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>                        <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-red-50 dark:bg-red-900/20 p-2.5 text-red-600 dark:text-red-400 flex items-center justify-center ring-1 ring-red-100 dark:ring-red-800">                  <Truck className="h-5 w-5" />               </div>            </div>            <div className="flex-1 space-y-4">               {/* Active Unit Card */}               <div className="bg-muted rounded-xl p-3 border border-zinc-100 dark:border-zinc-700 relative overflow-hidden">                  <div className="flex justify-between items-start mb-3">                     <div className="flex items-center gap-2">                        <div className="h-8 w-8 rounded-lg bg-white dark:bg-zinc-800 shadow-sm flex items-center justify-center text-red-500 border border-zinc-200 dark:border-zinc-700">                           <span className="text-xs font-bold">{activeUnit.id}</span>                        </div>                        <div>                           <p className="text-sm font-bold text-foreground">{activeUnit.type}</p>                           <p className="text-xs text-muted-foreground">{activeUnit.dispatchId}</p>                        </div>                     </div>                     <span className="text-[10px] font-bold text-red-600 dark:text-red-400 bg-red-100 dark:bg-red-900/30 px-2 py-1 rounded-full animate-pulse">                        {activeUnit.status}                     </span>                  </div>                  {/* Pseudo Map Visualization */}                  <div className="flex items-center gap-3 relative">                     <div className="flex flex-col items-center gap-1">                        <Navigation className="h-3 w-3 text-blue-500 fill-blue-500" />                        <div className="w-0.5 h-8 bg-zinc-200 dark:bg-zinc-700 relative">                           <motion.div                              className="absolute top-0 left-0 w-full bg-blue-500"                              initial={{ height: "0%" }}                              animate={{ height: "100%" }}                              transition={{ duration: 2, repeat: Infinity }}                           />                        </div>                        <MapPin className="h-3 w-3 text-red-500" />                     </div>                     <div className="flex-1 space-y-2">                        <div className="flex justify-between text-xs font-medium">                           <span className="text-zinc-600 dark:text-muted-foreground flex items-center gap-1"><Clock className="h-3 w-3" /> ETA {activeUnit.eta}</span>                           <span className="text-foreground">{activeUnit.distance}</span>                        </div>                        <div className="h-1.5 w-full bg-zinc-200 dark:bg-zinc-700 rounded-full overflow-hidden">                           <motion.div                              className="h-full bg-blue-500 rounded-full"                              initial={{ width: "30%" }}                              animate={{ width: `${activeUnit.progress}%` }}                              transition={{ duration: 30, ease: "linear" }}                           />                        </div>                     </div>                  </div>               </div>               {/* Available Units Summary */}               <div className="flex items-center justify-between px-1">                  <div className="flex items-center gap-2">                     <div className="flex -space-x-1.5">                        <div className="h-6 w-6 rounded-full bg-zinc-100 dark:bg-zinc-800 border border-white dark:border-zinc-900 flex items-center justify-center text-[10px] font-bold text-muted-foreground">{availableUnits.bls}</div>                        <div className="h-6 w-6 rounded-full bg-zinc-100 dark:bg-zinc-800 border border-white dark:border-zinc-900 flex items-center justify-center text-[10px] font-bold text-muted-foreground">{availableUnits.als < 10 ? `0${availableUnits.als}` : availableUnits.als}</div>                        <div className="h-6 w-6 rounded-full bg-zinc-100 dark:bg-zinc-800 border border-white dark:border-zinc-900 flex items-center justify-center text-[10px] font-bold text-muted-foreground">+{availableUnits.critical}</div>                     </div>                     <span className="text-xs text-muted-foreground font-medium">Available</span>                  </div>                  <button className="text-[10px] font-semibold text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 bg-blue-500/10 px-2 py-1 rounded border border-blue-100 dark:border-blue-900/50 transition-colors">                     View Map                  </button>               </div>            </div>         </div>      </motion.div>   );};

Usage

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

Prop

Type