'use client'; import { ColorSquare } from '@/components/color-square'; import { AutoSizer } from '@/components/react-virtualized-auto-sizer'; import { Progress } from '@/components/ui/progress'; import { Widget, WidgetBody } from '@/components/widget'; import { pushModal } from '@/modals'; import { useSelector } from '@/redux'; import type { RouterOutputs } from '@/trpc/client'; import { cn } from '@/utils/cn'; import { round } from '@/utils/math'; import { getChartColor } from '@/utils/theme'; import { AlertCircleIcon } from 'lucide-react'; import { last } from 'ramda'; import { Cell, Pie, PieChart } from 'recharts'; import type { IChartInput } from '@openpanel/validation'; import { useChartContext } from '../chart/ChartProvider'; const findMostDropoffs = ( steps: RouterOutputs['chart']['funnel']['current']['steps'] ) => { return steps.reduce((acc, step) => { if (step.dropoffCount > acc.dropoffCount) { return step; } return acc; }); }; function InsightCard({ title, children, }: { title: string; children: React.ReactNode; }) { return (
{title}
{children}
); } type Props = RouterOutputs['chart']['funnel'] & { input: IChartInput; }; export function FunnelSteps({ current: { steps, totalSessions }, previous, input, }: Props) { const { editMode } = useChartContext(); const mostDropoffs = findMostDropoffs(steps); const lastStep = last(steps)!; const prevLastStep = last(previous.steps)!; const hasIncreased = lastStep.percent > prevLastStep.percent; const withWidget = (children: React.ReactNode) => { if (editMode) { return (
{children}
); } return children; }; return withWidget(
{({ width }) => { const height = width; return (
{round(lastStep.percent, 2)}%
); }}
Insights
{lastStep.count} of {totalSessions} {round(lastStep.percent, 2)}% compared to {round(prevLastStep.percent, 2)}% {mostDropoffs.event.displayName} lost {mostDropoffs.dropoffCount} sessions
{steps.map((step, index) => { const percent = (step.count / totalSessions) * 100; const isMostDropoffs = mostDropoffs.event.id === step.event.id; return (
{step.event.id}
{step.event.displayName.replace(/_/g, ' ')}
Total: {step.previousCount}
Dropoff: {isMostDropoffs && } {step.dropoffCount}
Current:
{step.count}
); })}
); }