'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 (
);
}
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}
pushModal('FunnelStepDetails', {
...input,
step: index + 1,
})
}
>
Inspect
);
})}
);
}