feat(analytics): add behavior and payment funnel tracking
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
import type { LoginStatus } from "@/data/dto/auth";
|
||||
import { behaviorAnalytics } from "@/lib/analytics";
|
||||
import { ROUTES } from "@/router/routes";
|
||||
import { useAppNavigator } from "@/router/use-app-navigator";
|
||||
import type { ChatUpgradeReason } from "@/stores/chat/chat-state";
|
||||
@@ -33,6 +36,27 @@ export function useChatMessageLimitBanner({
|
||||
const navigator = useAppNavigator();
|
||||
const isVip = useUserSelector((state) => state.context.isVip);
|
||||
const view = getInsufficientCreditsMessageLimitView(loginStatus);
|
||||
const visible = shouldShowMessageLimitBanner({
|
||||
upgradePromptVisible,
|
||||
upgradeReason,
|
||||
});
|
||||
const trackedVisibleRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!visible) {
|
||||
trackedVisibleRef.current = false;
|
||||
return;
|
||||
}
|
||||
if (trackedVisibleRef.current) return;
|
||||
trackedVisibleRef.current = true;
|
||||
behaviorAnalytics.paywallShown(
|
||||
{
|
||||
entryPoint: "chat_input",
|
||||
triggerReason: "insufficient_credits",
|
||||
},
|
||||
{ isVip },
|
||||
);
|
||||
}, [isVip, visible]);
|
||||
|
||||
function unlock(): void {
|
||||
if (view.action === "auth") {
|
||||
@@ -43,15 +67,16 @@ export function useChatMessageLimitBanner({
|
||||
navigator.openSubscription({
|
||||
type: getInsufficientCreditsSubscriptionType(isVip),
|
||||
returnTo: "chat",
|
||||
analytics: {
|
||||
entryPoint: "chat_input",
|
||||
triggerReason: "insufficient_credits",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
...view,
|
||||
visible: shouldShowMessageLimitBanner({
|
||||
upgradePromptVisible,
|
||||
upgradeReason,
|
||||
}),
|
||||
visible,
|
||||
unlock,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { shallowEqual } from "@xstate/react";
|
||||
|
||||
import type { ChatLockType } from "@/data/schemas/chat";
|
||||
import { behaviorAnalytics } from "@/lib/analytics";
|
||||
import {
|
||||
consumePendingChatUnlock,
|
||||
peekPendingChatUnlock,
|
||||
@@ -60,6 +61,7 @@ export function useChatUnlockNavigationFlow({
|
||||
}: UseChatUnlockNavigationFlowInput): UseChatUnlockNavigationFlowOutput {
|
||||
const navigator = useAppNavigator();
|
||||
const isVip = useUserSelector((state) => state.context.isVip);
|
||||
const trackedPaywallRef = useRef<string | null>(null);
|
||||
const chatState = useChatSelector(
|
||||
(state) => ({
|
||||
historyLoaded: state.context.historyLoaded,
|
||||
@@ -77,6 +79,22 @@ export function useChatUnlockNavigationFlow({
|
||||
enabled,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!unlockPaywallRequest) return;
|
||||
const requestKey = `${unlockPaywallRequest.displayMessageId}:${unlockPaywallRequest.clientLockId ?? ""}`;
|
||||
if (trackedPaywallRef.current === requestKey) return;
|
||||
trackedPaywallRef.current = requestKey;
|
||||
behaviorAnalytics.paywallShown(
|
||||
{
|
||||
entryPoint: "chat_unlock",
|
||||
triggerReason: unlockPaywallRequest.promotion
|
||||
? "ad_landing"
|
||||
: "insufficient_credits",
|
||||
},
|
||||
{ isVip },
|
||||
);
|
||||
}, [isVip, unlockPaywallRequest]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
if (!chatState.historyLoaded || !navigator.isAuthenticatedUser) return;
|
||||
@@ -172,6 +190,12 @@ export function useChatUnlockNavigationFlow({
|
||||
promotion: unlockPaywallRequest.promotion,
|
||||
returnUrl,
|
||||
type: getInsufficientCreditsSubscriptionType(isVip),
|
||||
analytics: {
|
||||
entryPoint: "chat_unlock",
|
||||
triggerReason: unlockPaywallRequest.promotion
|
||||
? "ad_landing"
|
||||
: "insufficient_credits",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,14 @@ export function useFirstRechargeOfferBanner({
|
||||
}
|
||||
|
||||
function claim(): void {
|
||||
navigator.openSubscription({ type: "vip", returnTo: "chat" });
|
||||
navigator.openSubscription({
|
||||
type: "vip",
|
||||
returnTo: "chat",
|
||||
analytics: {
|
||||
entryPoint: "chat_offer_banner",
|
||||
triggerReason: "vip_cta",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user