import { Card } from '../ui/card'; import { TrendingDown } from 'lucide-react'; export interface FunnelStage { stage: string; count: number; color?: string; } export interface PipelineFunnelProps { stages: FunnelStage[]; title?: string; onStageClick?: (stage: string) => void; } export function PipelineFunnel({ stages, title = 'Pipeline Funnel', onStageClick, }: PipelineFunnelProps) { if (!stages || stages.length === 0) { return (

{title}

No pipeline data available

); } const maxCount = Math.max(...stages.map(s => s.count)); return (

{title}

{stages.map((stage, index) => { const percentage = maxCount > 0 ? (stage.count / maxCount) * 100 : 0; const stagePercentage = stages[0]?.count > 0 ? Math.round((stage.count / stages[0].count) * 100) : 0; const defaultColors = [ 'from-accent/70 to-accent', 'from-primary/50 to-primary/70', 'from-primary/70 to-primary/90', 'from-primary/90 to-primary', ]; const gradientColor = stage.color || defaultColors[index % defaultColors.length]; const nextStage = stages[index + 1]; const conversionRate = nextStage ? Math.round((nextStage.count / stage.count) * 100) : null; return (
onStageClick?.(stage.stage)} >
{stage.stage}
{stagePercentage}% of total {stage.count.toLocaleString()}
{conversionRate !== null && (
{conversionRate}% convert to next stage
)}
); })}
{stages.length >= 2 && (
Overall Conversion {Math.round((stages[stages.length - 1].count / stages[0].count) * 100)}% ({stages[0].stage} → {stages[stages.length - 1].stage})
)}
); }