'use client'; import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; import { CardSkeleton } from '@/components/shared/loading-skeleton'; import { EmptyState } from '@/components/shared/empty-state'; import { ChartCard } from './chart-card'; import { useFunnel } from './use-analytics'; import type { DateRange } from '@/lib/services/analytics.service'; const STAGE_LABELS: Record = { open: 'Open', details_sent: 'Details Sent', in_communication: 'In Communication', visited: 'Visited', signed_eoi_nda: 'Signed EOI/NDA', deposit_10pct: 'Deposit 10%', contract: 'Contract', completed: 'Completed', }; interface Props { range: DateRange; } export function PipelineFunnelChart({ range }: Props) { const { data, isLoading } = useFunnel(range); const stages = data?.stages ?? []; const chartData = stages.map((s) => ({ stage: STAGE_LABELS[s.stage] ?? s.stage, count: s.count, conversionPct: s.conversionPct, })); const allZero = stages.every((s) => s.count === 0); function toCsv(): string | null { if (!stages.length) return null; const header = 'stage,count,conversion_pct'; const rows = stages.map((s) => `${s.stage},${s.count},${s.conversionPct}`); return [header, ...rows].join('\n'); } return ( {isLoading ? ( ) : allZero ? ( ) : ( { const pct = (item?.payload as { conversionPct?: number } | undefined) ?.conversionPct; return [`${value} (${pct ?? 0}%)`, 'Count']; }} /> )} ); }