E-Commerce
Sales Funnel Card - Conversion Tracking
Visualize complete sales funnel from awareness to conversion. Track funnel drop-off and optimize each stage.
Sales Funnel Card
The Sales Funnel Card Visualize conversion funnel from visitors to purchases.
Preview
Installation
ash npx shadcn@latest add https://vectormotion.vercel.app/registry/sales-funnel-card.json
Sales Funnel Card
'use client';import React from "react";import { Filter, Users } 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 FunnelStage { stage: string; count: number; percentage: number; color: string; [key: string]: any;}interface SalesFunnelCardProps { className?: string; title?: string; description?: string; overallConversion?: string; funnelStages?: FunnelStage[];}const DEFAULT_TITLE = "Sales Funnel";const DEFAULT_DESCRIPTION = "Conversion Flow";const DEFAULT_OVERALL_CONVERSION = "6.0%";const DEFAULT_FUNNEL_STAGES: FunnelStage[] = [ { stage: "Visitors", count: 10000, percentage: 100, color: "bg-blue-500" }, { stage: "Product Views", count: 5000, percentage: 50, color: "bg-purple-500", }, { stage: "Add to Cart", count: 2000, percentage: 20, color: "bg-indigo-500", }, { stage: "Checkout", count: 800, percentage: 8, color: "bg-violet-500" }, { stage: "Purchase", count: 600, percentage: 6, color: "bg-emerald-500" },];export const SalesFunnelCard: React.FC<SalesFunnelCardProps> = ({ className = "", title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, overallConversion = DEFAULT_OVERALL_CONVERSION, funnelStages = DEFAULT_FUNNEL_STAGES,}) => { const isInteractive = true; const index = 4; return ( <motion.div layoutId={isInteractive ? `card-${index}-${title}` : undefined} transition={{ duration: 0.4, ease: "easeOut" }} className={cn( "relative overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-6 shadow-sm transition-all flex flex-col group", isInteractive ? "cursor-pointer hover:border-zinc-300 dark:hover:border-zinc-700" : "", className, )} > <div className="mb-4 flex items-start justify-between relative z-10"> <div> <h3 className="font-semibold text-lg tracking-tight text-foreground"> {title} </h3> {description && ( <p className="text-sm text-muted-foreground mt-1">{description}</p> )} </div> <div className="rounded-full bg-zinc-100 dark:bg-zinc-800 p-2 text-foreground flex items-center justify-center"> <Filter className="h-5 w-5 text-indigo-500" /> </div> </div> <div className="relative z-10 flex-1"> <div className="space-y-2"> {funnelStages.map((stage, idx) => ( <div key={idx}> <div className="flex justify-between items-center mb-1"> <span className="text-sm font-medium text-foreground"> {stage.stage} </span> <div className="flex items-center gap-2"> <span className="text-sm font-bold text-foreground"> {stage.count.toLocaleString()} </span> <span className="text-xs text-muted-foreground"> ({stage.percentage}%) </span> </div> </div> <motion.div initial={{ width: 0 }} animate={{ width: `${stage.percentage}%` }} transition={{ duration: 0.8, delay: idx * 0.1 }} className={`h-8 ${stage.color} rounded-lg flex items-center justify-center`} style={{ minWidth: "60px" }} > {idx < funnelStages.length - 1 && ( <span className="text-xs text-white font-medium"> {( (funnelStages[idx + 1].count / stage.count) * 100 ).toFixed(1)} % → </span> )} </motion.div> </div> ))} </div> <div className="mt-4 pt-4 border-t border-border"> <div className="flex justify-between items-center"> <span className="text-sm text-muted-foreground"> Overall Conversion </span> <span className="text-lg font-bold text-emerald-500"> {overallConversion} </span> </div> </div> </div> </motion.div> );};Usage
This component is a data-rich dashboard card displaying e-commerce metrics with animated visualizations and dark mode support. Perfect for dashboards, landing pages, and analytics interfaces.
Prop
Type