feat(analytics): add behavior and payment funnel tracking
This commit is contained in:
@@ -3,8 +3,14 @@ import { useEffect, useMemo, useRef } from "react";
|
||||
|
||||
import { BackButton } from "@/app/_components";
|
||||
import { Checkbox, MobileShell } from "@/app/_components/core";
|
||||
import { usePaymentPlanAnalytics } from "@/app/_hooks/use-payment-plan-analytics";
|
||||
import { AppConstants } from "@/core/app_constants";
|
||||
import type { PayChannel } from "@/data/dto/payment";
|
||||
import {
|
||||
behaviorAnalytics,
|
||||
getDefaultPaymentAnalyticsContext,
|
||||
type PaymentAnalyticsContext,
|
||||
} from "@/lib/analytics";
|
||||
import { useUserState } from "@/stores/user/user-context";
|
||||
|
||||
import {
|
||||
@@ -34,6 +40,7 @@ export interface SubscriptionScreenProps {
|
||||
shouldResumePendingOrder?: boolean;
|
||||
returnTo?: "chat" | null;
|
||||
initialPayChannel?: PayChannel | null;
|
||||
analyticsContext?: PaymentAnalyticsContext;
|
||||
}
|
||||
|
||||
export function SubscriptionScreen({
|
||||
@@ -41,6 +48,7 @@ export function SubscriptionScreen({
|
||||
shouldResumePendingOrder = false,
|
||||
returnTo = null,
|
||||
initialPayChannel = null,
|
||||
analyticsContext: providedAnalyticsContext,
|
||||
}: SubscriptionScreenProps) {
|
||||
const userState = useUserState();
|
||||
const countryCode = userState.currentUser?.countryCode;
|
||||
@@ -64,6 +72,9 @@ export function SubscriptionScreen({
|
||||
initialPayChannel: resolvedInitialPayChannel,
|
||||
});
|
||||
const canSubscribeVip = subscriptionType === "vip";
|
||||
const analyticsContext =
|
||||
providedAnalyticsContext ??
|
||||
getDefaultPaymentAnalyticsContext(subscriptionType);
|
||||
|
||||
const vipOfferPlans = useMemo(
|
||||
() => toVipOfferPlanViews(payment.plans),
|
||||
@@ -73,6 +84,17 @@ export function SubscriptionScreen({
|
||||
() => toCoinsOfferPlanViews(payment.plans),
|
||||
[payment.plans],
|
||||
);
|
||||
const displayedPlans = useMemo(() => {
|
||||
const displayedPlanIds = [
|
||||
...(canSubscribeVip ? vipOfferPlans : []),
|
||||
...directCoinsPlans,
|
||||
].map((plan) => plan.id);
|
||||
return displayedPlanIds.flatMap((planId) => {
|
||||
const plan = payment.plans.find((item) => item.planId === planId);
|
||||
return plan ? [plan] : [];
|
||||
});
|
||||
}, [canSubscribeVip, directCoinsPlans, payment.plans, vipOfferPlans]);
|
||||
usePaymentPlanAnalytics(displayedPlans, analyticsContext);
|
||||
const firstRechargeOffer = useMemo(
|
||||
() =>
|
||||
getFirstRechargeOfferView({
|
||||
@@ -95,6 +117,12 @@ export function SubscriptionScreen({
|
||||
const canActivate =
|
||||
selectedPlan !== null && payment.agreed && !isPaymentBusy;
|
||||
|
||||
const handleSelectPlan = (planId: string) => {
|
||||
const plan = payment.plans.find((item) => item.planId === planId);
|
||||
if (plan) behaviorAnalytics.planClick(plan, analyticsContext);
|
||||
paymentDispatch({ type: "PaymentPlanSelected", planId });
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isPaymentBusy) return;
|
||||
|
||||
@@ -160,6 +188,7 @@ export function SubscriptionScreen({
|
||||
className={styles.backSlot}
|
||||
onClick={handleBackClick}
|
||||
variant="soft"
|
||||
analyticsKey="subscription.back"
|
||||
/>
|
||||
</header>
|
||||
|
||||
@@ -187,23 +216,13 @@ export function SubscriptionScreen({
|
||||
<SubscriptionVipOfferSection
|
||||
plans={vipOfferPlans}
|
||||
selectedPlanId={payment.selectedPlanId || selectedPlan?.id || null}
|
||||
onSelectPlan={(planId) =>
|
||||
paymentDispatch({
|
||||
type: "PaymentPlanSelected",
|
||||
planId,
|
||||
})
|
||||
}
|
||||
onSelectPlan={handleSelectPlan}
|
||||
/>
|
||||
) : null}
|
||||
<SubscriptionCoinsOfferSection
|
||||
plans={directCoinsPlans}
|
||||
selectedPlanId={payment.selectedPlanId || selectedPlan?.id || null}
|
||||
onSelectPlan={(planId) =>
|
||||
paymentDispatch({
|
||||
type: "PaymentPlanSelected",
|
||||
planId,
|
||||
})
|
||||
}
|
||||
onSelectPlan={handleSelectPlan}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user