Improve landing performance and analytics funnel

This commit is contained in:
2569718930@qq.com
2026-05-30 19:50:50 +08:00
parent 3fcda3f3cd
commit 9bcfd9d1eb
15 changed files with 336 additions and 95 deletions
+31 -1
View File
@@ -196,19 +196,49 @@ export function AccountCenter() {
useEffect(() => {
if (!authIsAuthenticated || !authUserId) return;
const actorKey = authUserId.toLowerCase();
const subscriptionPlanCode = String(backend?.subscription_plan_code || "").trim();
const subscriptionSource = String(backend?.subscription_source || "").trim();
const trialSubscription = Boolean(
backend?.subscription_is_trial === true ||
subscriptionPlanCode.toLowerCase().includes("trial") ||
subscriptionSource.toLowerCase().includes("trial"),
);
if (markAnalyticsOnce(`signup_completed:${actorKey}`, "local")) {
trackAppEvent("signup_completed", {
entry: "account_center",
user_id: authUserId,
});
}
if (markAnalyticsOnce(`signup_success:${actorKey}`, "local")) {
trackAppEvent("signup_success", {
entry: "account_center",
user_id: authUserId,
});
}
if (markAnalyticsOnce(`dashboard_active:${actorKey}`, "session")) {
trackAppEvent("dashboard_active", {
entry: "account_center",
user_id: authUserId,
});
}
}, [authIsAuthenticated, authUserId]);
if (trialSubscription && markAnalyticsOnce(`trial_created:${actorKey}`, "local")) {
trackAppEvent("trial_created", {
entry: "account_center",
user_id: authUserId,
subscription_plan_code: subscriptionPlanCode || null,
subscription_source: subscriptionSource || null,
subscription_expires_at: backend?.subscription_expires_at || null,
subscription_is_trial: backend?.subscription_is_trial === true,
});
}
}, [
authIsAuthenticated,
authUserId,
backend?.subscription_expires_at,
backend?.subscription_is_trial,
backend?.subscription_plan_code,
backend?.subscription_source,
]);
// ── Idle callback effect ──────────────────────────────
useEffect(() => {
@@ -203,6 +203,27 @@ export function runTests() {
accountCenterSource.includes('trackAppEvent("dashboard_active"'),
"account center must emit signup_completed and dashboard_active so the ops funnel has top-of-funnel data",
);
assert(
appAnalyticsSource.includes('| "landing_view"') &&
appAnalyticsSource.includes('| "enter_terminal"') &&
appAnalyticsSource.includes('| "login_start"') &&
appAnalyticsSource.includes('| "signup_success"') &&
appAnalyticsSource.includes('| "trial_created"') &&
appAnalyticsSource.includes('| "payment_start"') &&
appAnalyticsSource.includes('| "payment_success"'),
"app analytics must expose the standard growth funnel event names",
);
assert(
accountCenterSource.includes('trackAppEvent("signup_success"') &&
accountCenterSource.includes('trackAppEvent("trial_created"') &&
accountCenterSource.includes("subscription_is_trial"),
"account center must emit signup_success and trial_created for the standard funnel",
);
assert(
paymentFlowSource.includes('trackAppEvent("payment_start"') &&
paymentFlowSource.includes('trackAppEvent("payment_success"'),
"payment flow must emit payment_start and payment_success alongside legacy checkout events",
);
assert(
accountCenterSource.includes("isSubscriptionUnknown") &&
accountCenterSource.includes("subscriptionStatusLabel") &&
+14 -6
View File
@@ -174,6 +174,14 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
const planList = paymentConfig?.plans || [];
const effectivePlanList = planList;
const selectedPlan = effectivePlanList.find((plan) => plan.plan_code === selectedPlanCode) || effectivePlanList[0];
const trackPaymentStart = useCallback((payload: Record<string, unknown>) => {
trackAppEvent("checkout_started", payload);
trackAppEvent("payment_start", payload);
}, []);
const trackPaymentSuccess = useCallback((payload: Record<string, unknown>) => {
trackAppEvent("checkout_succeeded", payload);
trackAppEvent("payment_success", payload);
}, []);
const availableChainList: PaymentChainOption[] = useMemo(() => {
const configured = Array.isArray(paymentConfig?.chains) ? paymentConfig?.chains || [] : [];
@@ -345,7 +353,7 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
if (status === "confirmed") {
setPaymentError("");
setPaymentInfo(copy.paymentConfirmed.replace("{txHash}", shortAddress(txHash)));
trackAppEvent("checkout_succeeded", {
trackPaymentSuccess({
entry: "account_center",
plan_code: selectedPlan?.plan_code || "pro_monthly",
intent_id: intentId,
@@ -363,7 +371,7 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
}
throw new Error(copy.paymentPendingTimeout);
},
[loadPaymentSnapshot, refreshEntitlementAfterPayment, selectedPlan?.plan_code],
[loadPaymentSnapshot, refreshEntitlementAfterPayment, selectedPlan?.plan_code, trackPaymentSuccess],
);
// ── createIntentAndPay ──────────────────────────────────
@@ -484,7 +492,7 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
const intentId = String(created.intent?.intent_id || "");
const txPayload = created.tx_payload;
if (!intentId || !txPayload?.to || !txPayload?.data) throw new Error(copy.intentPayloadInvalid);
trackAppEvent("checkout_started", {
trackPaymentStart({
entry: "account_center",
plan_code: selectedPlan?.plan_code || "pro_monthly",
intent_id: intentId,
@@ -582,7 +590,7 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
}
setPaymentInfo(copy.paymentConfirmed.replace("{txHash}", shortAddress(txHashNorm)));
trackAppEvent("checkout_succeeded", {
trackPaymentSuccess({
entry: "account_center",
plan_code: selectedPlan?.plan_code || "pro_monthly",
intent_id: intentId,
@@ -676,7 +684,7 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
.replace("{chain}", chainName)
.replace("{receiver}", shortAddress(direct.receiver_address)),
);
trackAppEvent("checkout_started", {
trackPaymentStart({
entry: "account_center_manual_transfer",
plan_code: selectedPlan?.plan_code || "pro_monthly",
intent_id: intentId,
@@ -739,7 +747,7 @@ export function usePaymentFlow(params: UsePaymentFlowParams) {
setManualPayment(null);
setManualTxHash("");
setTxValidation({ loading: false, checked: false });
trackAppEvent("checkout_succeeded", {
trackPaymentSuccess({
entry: "account_center_manual_transfer",
plan_code: selectedPlan?.plan_code || "pro_monthly",
intent_id: intentIdVal,