import { formatCount, formatRate, formatWindow, funnelStateLabel } from "./format"; import { Section } from "./section"; import type { FunnelData, StatusNotice, ThemeName, ViewState } from "./types"; export type CauseWiseFunnelProps = { funnel?: FunnelData | null; theme?: ThemeName; state?: ViewState; error?: StatusNotice | null; className?: string; headingLevel?: 2 | 3; }; export function CauseWiseFunnel({ funnel, theme, state = "ready", error, className, headingLevel, }: CauseWiseFunnelProps) { const stateLabel = funnelStateLabel(funnel?.displayState); const windowLabel = formatWindow(funnel?.conversionWindow); const steps = funnel?.steps?.filter(isStep) ?? []; const entry = funnel?.entryVisitors ?? 0; return ( {funnel ? ( <> Entered {formatCount(funnel.entryVisitors)} Completed {formatCount(funnel.completionCount)} Completion rate {formatRate(funnel.overallConversionRate)} {stateLabel ? Status: {stateLabel} : null} {funnel.isActive === false ? Inactive : null} {windowLabel ? Window: {windowLabel} : null} {funnel.medianConversionTime ? Median time: {funnel.medianConversionTime} : null} {funnel.largestDropOff ? ( Largest drop-off: {funnel.largestDropOff.name} {funnel.largestDropOff.dropoffCount != null ? ` (${formatCount(funnel.largestDropOff.dropoffCount)})` : ""} ) : null} {steps.length > 0 ? ( {steps.map((step) => { const width = entry > 0 ? Math.max(4, Math.round((step.visitors / entry) * 100)) : 4; return ( {step.name} {formatCount(step.visitors)} visitors {step.continuedPct == null ? "" : `, ${formatRate(step.continuedPct)} from previous`} ); })} ) : ( Step detail was not included. Pass funnel analytics steps to show each stage. )} > ) : null} ); } function isStep(value: unknown): value is NonNullable[number] { if (!value || typeof value !== "object") return false; const step = value as Record; return typeof step.stepId === "string" && typeof step.name === "string" && typeof step.visitors === "number"; }
Step detail was not included. Pass funnel analytics steps to show each stage.