From d5b594d6f954d987e1e50846cd2c4932492528b7 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Wed, 18 Mar 2026 14:20:15 +0100 Subject: [PATCH] feat(funnels): update frontend types and API client for funnels v2 --- lib/api/funnels.ts | 71 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/lib/api/funnels.ts b/lib/api/funnels.ts index f5e2d51..cc1faf8 100644 --- a/lib/api/funnels.ts +++ b/lib/api/funnels.ts @@ -1,10 +1,18 @@ import apiRequest from './client' +export interface StepPropertyFilter { + key: string + operator: 'is' | 'is_not' | 'contains' | 'not_contains' + value: string +} + export interface FunnelStep { order: number name: string value: string type: string // "exact", "contains", "regex" + category?: 'page' | 'event' + property_filters?: StepPropertyFilter[] } export interface Funnel { @@ -13,15 +21,23 @@ export interface Funnel { name: string description: string steps: FunnelStep[] + conversion_window_value: number + conversion_window_unit: 'hours' | 'days' created_at: string updated_at: string } +export interface ExitPage { + path: string + visitors: number +} + export interface FunnelStepStats { step: FunnelStep visitors: number dropoff: number conversion: number + exit_pages: ExitPage[] } export interface FunnelStats { @@ -32,7 +48,27 @@ export interface FunnelStats { export interface CreateFunnelRequest { name: string description: string - steps: FunnelStep[] + steps: Omit[] + conversion_window_value?: number + conversion_window_unit?: 'hours' | 'days' +} + +export interface FunnelTrends { + dates: string[] + overall: number[] + steps: Record +} + +export interface FunnelBreakdownEntry { + value: string + visitors: number + conversion: number +} + +export interface FunnelBreakdown { + step: number + dimension: string + entries: FunnelBreakdownEntry[] } export async function listFunnels(siteId: string): Promise { @@ -64,10 +100,41 @@ export async function deleteFunnel(siteId: string, funnelId: string): Promise { +export async function getFunnelStats(siteId: string, funnelId: string, startDate?: string, endDate?: string, filters?: string): Promise { const params = new URLSearchParams() if (startDate) params.append('start_date', startDate) if (endDate) params.append('end_date', endDate) + if (filters) params.append('filters', filters) const queryString = params.toString() ? `?${params.toString()}` : '' return apiRequest(`/sites/${siteId}/funnels/${funnelId}/stats${queryString}`) } + +export async function getFunnelTrends( + siteId: string, funnelId: string, + startDate?: string, endDate?: string, + interval: string = 'day', filters?: string +): Promise { + const params = new URLSearchParams() + if (startDate) params.append('start_date', startDate) + if (endDate) params.append('end_date', endDate) + params.append('interval', interval) + if (filters) params.append('filters', filters) + const queryString = params.toString() ? `?${params.toString()}` : '' + return apiRequest(`/sites/${siteId}/funnels/${funnelId}/trends${queryString}`) +} + +export async function getFunnelBreakdown( + siteId: string, funnelId: string, + step: number, dimension: string, + startDate?: string, endDate?: string, + filters?: string +): Promise { + const params = new URLSearchParams() + params.append('step', step.toString()) + params.append('dimension', dimension) + if (startDate) params.append('start_date', startDate) + if (endDate) params.append('end_date', endDate) + if (filters) params.append('filters', filters) + const queryString = params.toString() ? `?${params.toString()}` : '' + return apiRequest(`/sites/${siteId}/funnels/${funnelId}/breakdown${queryString}`) +}