feat: add PostHog event tracking for feature opt-in banner and dialog (#27579)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
4367028492
commit
5804cc4fb0
3 files changed
+63
-2
No files matched your search
@@ -3,7 +3,8 @@
|
||||
import type { OptInFeatureConfig } from "@calcom/features/feature-opt-in/config";
|
||||
import { getOptInFeatureConfig, shouldDisplayFeatureAt } from "@calcom/features/feature-opt-in/config";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import posthog from "posthog-js";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
getFeatureOptInTimestamp,
|
||||
isFeatureDismissed,
|
||||
@@ -28,6 +29,12 @@ type FeatureOptInMutations = {
|
||||
invalidateQueries: () => void;
|
||||
};
|
||||
|
||||
type FeatureOptInTrackingData = {
|
||||
enableFor: "user" | "organization" | "teams";
|
||||
teamCount?: number;
|
||||
autoOptIn: boolean;
|
||||
};
|
||||
|
||||
type UseFeatureOptInBannerResult = {
|
||||
shouldShow: boolean;
|
||||
isLoading: boolean;
|
||||
@@ -41,6 +48,7 @@ type UseFeatureOptInBannerResult = {
|
||||
dismiss: () => void;
|
||||
markOptedIn: () => void;
|
||||
mutations: FeatureOptInMutations;
|
||||
trackFeatureEnabled: (data: FeatureOptInTrackingData) => void;
|
||||
};
|
||||
|
||||
function isFeatureOptedIn(featureId: string): boolean {
|
||||
@@ -108,7 +116,12 @@ function useFeatureOptInBanner(featureId: string): UseFeatureOptInBannerResult {
|
||||
]
|
||||
);
|
||||
|
||||
const hasBannerShownBeenTracked = useRef(false);
|
||||
|
||||
const dismiss = useCallback(() => {
|
||||
posthog.capture("feature_opt_in_banner_dismissed", {
|
||||
feature_slug: featureId,
|
||||
});
|
||||
setFeatureDismissed(featureId);
|
||||
setIsDismissed(true);
|
||||
}, [featureId]);
|
||||
@@ -119,13 +132,28 @@ function useFeatureOptInBanner(featureId: string): UseFeatureOptInBannerResult {
|
||||
}, [featureId]);
|
||||
|
||||
const openDialog = useCallback(() => {
|
||||
posthog.capture("feature_opt_in_banner_try_it_clicked", {
|
||||
feature_slug: featureId,
|
||||
});
|
||||
setIsDialogOpen(true);
|
||||
}, []);
|
||||
}, [featureId]);
|
||||
|
||||
const closeDialog = useCallback(() => {
|
||||
setIsDialogOpen(false);
|
||||
}, []);
|
||||
|
||||
const trackFeatureEnabled = useCallback(
|
||||
(data: FeatureOptInTrackingData) => {
|
||||
posthog.capture("feature_opt_in_enabled", {
|
||||
feature_slug: featureId,
|
||||
enable_for: data.enableFor,
|
||||
team_count: data.teamCount,
|
||||
auto_opt_in: data.autoOptIn,
|
||||
});
|
||||
},
|
||||
[featureId]
|
||||
);
|
||||
|
||||
const shouldShow = useMemo(() => {
|
||||
if (isDismissed) return false;
|
||||
if (isOptedIn) return false;
|
||||
@@ -137,6 +165,15 @@ function useFeatureOptInBanner(featureId: string): UseFeatureOptInBannerResult {
|
||||
return eligibilityQuery.data.status === "can_opt_in";
|
||||
}, [isDismissed, isOptedIn, featureConfig, eligibilityQuery.isLoading, eligibilityQuery.data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (shouldShow && !hasBannerShownBeenTracked.current) {
|
||||
hasBannerShownBeenTracked.current = true;
|
||||
posthog.capture("feature_opt_in_banner_shown", {
|
||||
feature_slug: featureId,
|
||||
});
|
||||
}
|
||||
}, [shouldShow, featureId]);
|
||||
|
||||
return {
|
||||
shouldShow,
|
||||
isLoading: eligibilityQuery.isLoading,
|
||||
@@ -150,6 +187,7 @@ function useFeatureOptInBanner(featureId: string): UseFeatureOptInBannerResult {
|
||||
dismiss,
|
||||
markOptedIn,
|
||||
mutations,
|
||||
trackFeatureEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user