Skip to content

Commit a0638c6

Browse files
committed
fix: funnels UI
1 parent 4191a6f commit a0638c6

File tree

4 files changed

+57
-43
lines changed

4 files changed

+57
-43
lines changed

apps/api/src/query/builders/sessions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export const SessionsBuilders: Record<string, SimpleQueryConfig> = {
205205
COALESCE(se.events, []) as events
206206
FROM session_list sl
207207
LEFT JOIN session_events se ON sl.session_id = se.session_id
208-
${combinedWhereClause ? `WHERE ${combinedWhereClause.replace('AND ', '')}` : ''}
208+
${combinedWhereClause}
209209
ORDER BY sl.first_visit DESC
210210
`,
211211
params: {

apps/api/src/query/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,5 +288,5 @@ export function buildWhereClause(conditions?: string[]): string {
288288
const safeClauses = conditions.filter(
289289
(clause) => !UNSAFE_CLAUSE_REGEX.test(clause)
290290
);
291-
return `AND (${safeClauses.join(' AND ')})`;
291+
return `WHERE (${safeClauses.join(' AND ')})`;
292292
}

apps/dashboard/app/(main)/websites/[id]/funnels/_components/funnel-analytics.tsx

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,40 +56,32 @@ export function FunnelAnalytics({
5656
return referrer || null;
5757
}, [selectedReferrer, referrerAnalytics]);
5858

59-
// Use selected referrer data if available, otherwise use main analytics data
6059
const displayData = selectedReferrerData
6160
? {
6261
total_users_entered: selectedReferrerData.total_users,
6362
total_users_completed: selectedReferrerData.completed_users,
6463
overall_conversion_rate: selectedReferrerData.conversion_rate,
65-
avg_completion_time: 0, // Not available in referrer analytics
64+
avg_completion_time: 0,
6665
avg_completion_time_formatted: '0s',
6766
biggest_dropoff_step: 1,
6867
biggest_dropoff_rate: 100 - selectedReferrerData.conversion_rate,
69-
steps_analytics: [
70-
{
71-
step_number: 1,
72-
step_name: 'Landing Page',
73-
users: selectedReferrerData.total_users,
74-
total_users: selectedReferrerData.total_users,
75-
conversion_rate: 100,
76-
dropoffs: 0,
77-
dropoff_rate: 0,
78-
avg_time_to_complete: 0,
79-
},
80-
{
81-
step_number: 2,
82-
step_name: 'Completed',
83-
users: selectedReferrerData.completed_users,
84-
total_users: selectedReferrerData.total_users,
85-
conversion_rate: selectedReferrerData.conversion_rate,
86-
dropoffs:
87-
selectedReferrerData.total_users -
88-
selectedReferrerData.completed_users,
89-
dropoff_rate: 100 - selectedReferrerData.conversion_rate,
90-
avg_time_to_complete: 0,
91-
},
92-
],
68+
steps_analytics: data?.steps_analytics?.map((step, index) => ({
69+
...step,
70+
users: index === 0
71+
? selectedReferrerData.total_users
72+
: selectedReferrerData.completed_users,
73+
total_users: selectedReferrerData.total_users,
74+
conversion_rate: index === 0
75+
? 100
76+
: selectedReferrerData.conversion_rate,
77+
dropoffs: index === 0
78+
? 0
79+
: selectedReferrerData.total_users - selectedReferrerData.completed_users,
80+
dropoff_rate: index === 0
81+
? 0
82+
: 100 - selectedReferrerData.conversion_rate,
83+
avg_time_to_complete: 0,
84+
})) || [],
9385
}
9486
: data;
9587

packages/rpc/src/lib/analytics-utils.ts

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,35 @@ const buildStepQuery = (
132132
const referrerSelectCustom = includeReferrer ? ", '' as referrer" : '';
133133

134134
return `
135+
WITH filtered_sessions AS (
136+
SELECT DISTINCT session_id
137+
FROM analytics.events
138+
WHERE client_id = {websiteId:String}
139+
AND time >= parseDateTimeBestEffort({startDate:String})
140+
AND time <= parseDateTimeBestEffort({endDate:String})
141+
AND event_name = {${targetKey}:String}${filterConditions}
142+
),
143+
session_referrers AS (
144+
SELECT
145+
session_id,
146+
argMin(referrer, time) as session_referrer
147+
FROM analytics.events
148+
WHERE client_id = {websiteId:String}
149+
AND time >= parseDateTimeBestEffort({startDate:String})
150+
AND time <= parseDateTimeBestEffort({endDate:String})
151+
AND event_name = 'screen_view'
152+
AND referrer != ''
153+
GROUP BY session_id
154+
)
135155
SELECT
136156
${stepIndex + 1} as step_number,
137157
{${stepNameKey}:String} as step_name,
138158
session_id,
139-
MIN(first_occurrence) as first_occurrence${referrerSelect}
159+
MIN(first_occurrence) as first_occurrence${includeReferrer ? ', COALESCE(sr.session_referrer, \'\') as referrer' : ''}
140160
FROM (
141161
SELECT
142162
session_id,
143-
time as first_occurrence${includeReferrer ? ', referrer' : ''}
163+
time as first_occurrence
144164
FROM analytics.events
145165
WHERE client_id = {websiteId:String}
146166
AND time >= parseDateTimeBestEffort({startDate:String})
@@ -150,15 +170,17 @@ const buildStepQuery = (
150170
UNION ALL
151171
152172
SELECT
153-
session_id,
154-
timestamp as first_occurrence${referrerSelectCustom}
155-
FROM analytics.custom_events
156-
WHERE client_id = {websiteId:String}
157-
AND timestamp >= parseDateTimeBestEffort({startDate:String})
158-
AND timestamp <= parseDateTimeBestEffort({endDate:String})
159-
AND event_name = {${targetKey}:String}
160-
)
161-
GROUP BY session_id`;
173+
ce.session_id,
174+
ce.timestamp as first_occurrence
175+
FROM analytics.custom_events ce
176+
INNER JOIN filtered_sessions fs ON ce.session_id = fs.session_id
177+
WHERE ce.client_id = {websiteId:String}
178+
AND ce.timestamp >= parseDateTimeBestEffort({startDate:String})
179+
AND ce.timestamp <= parseDateTimeBestEffort({endDate:String})
180+
AND ce.event_name = {${targetKey}:String}
181+
)${includeReferrer ? `
182+
LEFT JOIN session_referrers sr ON session_id = sr.session_id` : ''}
183+
GROUP BY session_id${includeReferrer ? ', sr.session_referrer' : ''}`;
162184
};
163185

164186
const processSessionEvents = (
@@ -220,7 +242,7 @@ const calculateStepCounts = (
220242
): Map<number, Set<string>> => {
221243
const stepCounts = new Map<number, Set<string>>();
222244

223-
for (const [sessionId, events] of sessionEvents) {
245+
for (const [sessionId, events] of Array.from(sessionEvents.entries())) {
224246
events.sort((a, b) => a.first_occurrence - b.first_occurrence);
225247
let currentStep = 1;
226248

@@ -674,7 +696,7 @@ const calculateReferrerStepCounts = (
674696
): Map<number, Set<string>> => {
675697
const stepCounts = new Map<number, Set<string>>();
676698

677-
for (const sessionId of group.sessionIds) {
699+
for (const sessionId of Array.from(group.sessionIds)) {
678700
const events = sessionEvents
679701
.get(sessionId)
680702
?.sort((a, b) => a.first_occurrence - b.first_occurrence);
@@ -863,7 +885,7 @@ export const processFunnelAnalyticsByReferrer = async (
863885
}
864886
>();
865887

866-
for (const [sessionId, events] of sessionEvents) {
888+
for (const [sessionId, events] of Array.from(sessionEvents.entries())) {
867889
if (events.length > 0) {
868890
const referrer = events[0].referrer || 'Direct';
869891
const parsed = parseReferrer(referrer);
@@ -878,7 +900,7 @@ export const processFunnelAnalyticsByReferrer = async (
878900

879901
const referrerAnalytics: ReferrerAnalytics[] = [];
880902

881-
for (const [groupKey, group] of referrerGroups) {
903+
for (const [groupKey, group] of Array.from(referrerGroups.entries())) {
882904
const analytics = processReferrerGroup(
883905
groupKey,
884906
group,

0 commit comments

Comments
 (0)