improve(funnel): revert the revert of the ui (api still reverted)

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-11-23 23:55:11 +01:00
parent b0c8e25b0a
commit 222b54b907
8 changed files with 165 additions and 89 deletions

View File

@@ -29,7 +29,7 @@ interface PreviousDiffIndicatorProps {
children?: React.ReactNode;
inverted?: boolean;
className?: string;
size?: 'sm' | 'lg';
size?: 'sm' | 'lg' | 'md';
}
export function PreviousDiffIndicator({
@@ -80,6 +80,7 @@ export function PreviousDiffIndicator({
'flex size-4 items-center justify-center rounded-full',
variant,
size === 'lg' && 'size-8',
size === 'md' && 'size-6',
)}
>
{renderIcon()}

View File

@@ -39,15 +39,10 @@ export function Chart({
const { isEditMode } = useReportChartContext();
const mostDropoffs = findMostDropoffs(steps);
const lastStep = last(steps)!;
const prevLastStep = last(previous.steps);
const prevLastStep = previous?.steps ? last(previous.steps) : null;
return (
<div
className={cn(
'flex flex-col gap-4 @container',
isEditMode ? 'card' : '-m-4',
)}
>
<div className={cn('col gap-4 @container', isEditMode ? 'card' : '-m-4')}>
<div
className={cn(
'border-b border-border bg-def-100',
@@ -55,66 +50,49 @@ export function Chart({
)}
>
<div className="flex items-center gap-8 p-4 px-8">
<div className="flex flex-1 items-center gap-8">
<div className="flex flex-1 items-center gap-8 min-w-0">
<MetricCardNumber
label="Converted"
value={lastStep.count}
enhancer={
<PreviousDiffIndicator
size="lg"
size="md"
{...getPreviousMetric(lastStep.count, prevLastStep?.count)}
/>
}
/>
<MetricCardNumber
label="Percent"
value={`${totalSessions ? round((lastStep.count / totalSessions) * 100, 1) : 0}%`}
value={`${totalSessions ? round((lastStep.count / totalSessions) * 100, 2) : 0}%`}
enhancer={
<PreviousDiffIndicator
size="lg"
size="md"
{...getPreviousMetric(lastStep.count, prevLastStep?.count)}
/>
}
/>
<MetricCardNumber
className="flex-1"
label="Most dropoffs"
value={mostDropoffs.event.displayName}
enhancer={
<PreviousDiffIndicator
size="lg"
size="md"
{...getPreviousMetric(lastStep.count, prevLastStep?.count)}
/>
}
/>
</div>
<div className="hidden shrink-0 gap-2 @xl:flex">
{steps.map((step) => {
return (
<div
className="flex h-16 w-4 items-end overflow-hidden rounded bg-def-200"
key={step.event.id}
>
<div
className={cn(
'bg-foreground w-full',
step.event.id === mostDropoffs.event.id && 'bg-rose-500',
)}
style={{ height: `${step.percent}%` }}
/>
</div>
);
})}
</div>
</div>
</div>
<div className="flex flex-col divide-y divide-def-200">
<div className="col divide-y divide-def-200">
{steps.map((step, index) => {
const percent = (step.count / totalSessions) * 100;
const isMostDropoffs = mostDropoffs.event.id === step.event.id;
return (
<div
key={step.event.id}
className="flex flex-col gap-4 px-4 py-4 @2xl:flex-row @2xl:px-8"
className="col gap-12 px-4 py-4 @2xl:flex-row @2xl:px-8"
>
<div className="relative flex flex-1 flex-col gap-2 pl-8">
<ColorSquare className="absolute left-0 top-0.5">
@@ -123,27 +101,27 @@ export function Chart({
<div className="font-semibold mt-1">
{step.event.displayName}
</div>
<div className="flex items-center gap-8 text-sm">
<div className="grid grid-cols-4 max-w-lg gap-8 text-sm">
<TooltipComplete
disabled={!previous.steps[index]}
disabled={!previous?.steps?.[index]}
content={
<div className="flex items-center gap-2">
<span>
Last period:{' '}
<span className="font-mono">
{previous.steps[index]?.previousCount}
{previous?.steps?.[index]?.previousCount}
</span>
</span>
<PreviousDiffIndicator
{...getPreviousMetric(
step.previousCount,
previous.steps[index]?.previousCount,
previous?.steps?.[index]?.previousCount,
)}
/>
</div>
}
>
<div className="flex flex-col gap-2">
<div className="col gap-2">
<span className="text-xs text-muted-foreground">
Total:
</span>
@@ -155,26 +133,26 @@ export function Chart({
</div>
</TooltipComplete>
<TooltipComplete
disabled={!previous.steps[index]}
disabled={!previous?.steps?.[index]}
content={
<div className="flex items-center gap-2">
<span>
Last period:{' '}
<span className="font-mono">
{previous.steps[index]?.dropoffCount}
{previous?.steps?.[index]?.dropoffCount}
</span>
</span>
<PreviousDiffIndicator
inverted
{...getPreviousMetric(
step.dropoffCount,
previous.steps[index]?.dropoffCount,
previous?.steps?.[index]?.dropoffCount,
)}
/>
</div>
}
>
<div className="flex flex-col gap-2">
<div className="col gap-2">
<span className="text-xs text-muted-foreground">
Dropoff:
</span>
@@ -192,25 +170,25 @@ export function Chart({
</div>
</TooltipComplete>
<TooltipComplete
disabled={!previous.steps[index]}
disabled={!previous?.steps?.[index]}
content={
<div className="flex items-center gap-2">
<span>
Last period:{' '}
<span className="font-mono">
{previous.steps[index]?.count}
{previous?.steps?.[index]?.count}
</span>
</span>
<PreviousDiffIndicator
{...getPreviousMetric(
step.count,
previous.steps[index]?.count,
previous?.steps?.[index]?.count,
)}
/>
</div>
}
>
<div className="flex flex-col gap-2">
<div className="col gap-2">
<span className="text-xs text-muted-foreground">
Current:
</span>
@@ -219,12 +197,42 @@ export function Chart({
</div>
</div>
</TooltipComplete>
<TooltipComplete
disabled={!previous?.steps?.[index]}
content={
<div className="flex items-center gap-2">
<span>
Last period:{' '}
<span className="font-mono">
{previous?.steps?.[index]?.count}
</span>
</span>
<PreviousDiffIndicator
{...getPreviousMetric(
step.count,
previous?.steps?.[index]?.count,
)}
/>
</div>
}
>
<div className="col gap-2">
<span className="text-xs text-muted-foreground">
Percent:
</span>
<div className="flex items-center gap-4">
<span className="text-lg font-mono">
{Number.isNaN(percent) ? 0 : round(percent, 2)}%
</span>
</div>
</div>
</TooltipComplete>
</div>
</div>
<Progress
size="lg"
className={cn(
'w-full @2xl:w-1/2 text-white bg-def-200 mt-0.5 dark:text-black',
'w-full @2xl:w-1/4 text-white bg-def-200 mt-0.5 dark:text-black',
)}
innerClassName={cn(
'bg-primary',

View File

@@ -13,7 +13,16 @@ import { Chart } from './chart';
export function ReportFunnelChart() {
const {
report: { events, range, projectId, funnelWindow, funnelGroup },
report: {
events,
range,
projectId,
funnelWindow,
funnelGroup,
startDate,
endDate,
previous,
},
isLazyLoading,
} = useReportChartContext();
@@ -26,8 +35,10 @@ export function ReportFunnelChart() {
breakdowns: [],
funnelWindow,
funnelGroup,
previous: false,
previous,
metric: 'sum',
startDate,
endDate,
};
const res = api.chart.funnel.useQuery(input, {
keepPreviousData: true,

View File

@@ -122,19 +122,21 @@ export function MetricCardNumber({
label,
value,
enhancer,
className,
}: {
label: React.ReactNode;
value: React.ReactNode;
enhancer?: React.ReactNode;
className?: string;
}) {
return (
<div className="flex min-w-0 flex-col gap-2">
<div className={cn('flex min-w-0 flex-col gap-2', className)}>
<div className="flex items-center justify-between gap-2">
<div className="flex min-w-0 items-center gap-2 text-left">
<span className="truncate text-muted-foreground">{label}</span>
</div>
</div>
<div className="flex items-end justify-between">
<div className="flex items-end justify-between gap-4">
<div className="truncate font-mono text-3xl font-bold">{value}</div>
{enhancer}
</div>