Files
stats/apps/start/src/components/report-chart/funnel/index.tsx
2026-02-06 08:22:57 +00:00

83 lines
2.0 KiB
TypeScript

import { useTRPC } from '@/integrations/trpc/react';
import type { RouterOutputs } from '@/trpc/client';
import { useQuery } from '@tanstack/react-query';
import { AspectContainer } from '../aspect-container';
import { ReportChartEmpty } from '../common/empty';
import { ReportChartError } from '../common/error';
import { ReportChartLoading } from '../common/loading';
import { useReportChartContext } from '../context';
import { useVisibleFunnelBreakdowns } from '@/hooks/use-visible-funnel-breakdowns';
import { Chart, Summary } from './chart';
import { BreakdownList } from './breakdown-list';
export function ReportFunnelChart() {
const { isLazyLoading, report, shareId } = useReportChartContext();
const trpc = useTRPC();
const res = useQuery(
trpc.chart.funnel.queryOptions(
{
...report,
shareId,
},
{
enabled: !isLazyLoading && report.series.length > 0,
},
),
);
// Hook for limiting which breakdowns are shown in the chart only
const { breakdowns: visibleBreakdowns, setVisibleSeries } =
useVisibleFunnelBreakdowns(res.data?.current ?? [], 10);
if (isLazyLoading || res.isLoading) {
return <Loading />;
}
if (res.isError) {
return <Error />;
}
if (!res.data || res.data.current.length === 0) {
return <Empty />;
}
const hasBreakdowns = res.data.current.length > 1;
return (
<div className="col gap-4">
{hasBreakdowns && <Summary data={res.data} />}
<Chart data={res.data} visibleBreakdowns={visibleBreakdowns} />
<BreakdownList
data={res.data}
visibleSeriesIds={visibleBreakdowns.map((b) => b.id)}
setVisibleSeries={setVisibleSeries}
/>
</div>
);
}
function Loading() {
return (
<AspectContainer>
<ReportChartLoading />
</AspectContainer>
);
}
function Error() {
return (
<AspectContainer>
<ReportChartError />
</AspectContainer>
);
}
function Empty() {
return (
<AspectContainer>
<ReportChartEmpty />
</AspectContainer>
);
}