diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/billing/index.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/billing/index.tsx index 25e338dcd6..5612e04d59 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/billing/index.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/billing/index.tsx @@ -224,7 +224,16 @@ const SubscriptionSettings = () => { > setOpenCancelModal(true)} + onClick={() => { + mixpanel.track('PlanChangeStarted', { + segment: 'settings panel', + module: 'billing subscription list', + control: 'plan cancel action', + type: proSubscription.plan, + category: proSubscription.recurring, + }); + setOpenCancelModal(true); + }} className="dangerous-setting" name={t[ 'com.affine.payment.billing-setting.cancel-subscription' @@ -369,10 +378,21 @@ const PaymentMethodUpdater = () => { const ResumeSubscription = () => { const t = useI18n(); const [open, setOpen] = useState(false); + const subscription = useService(SubscriptionService).subscription; + const handleClick = useCallback(() => { + setOpen(true); + mixpanel.track('PlanChangeStarted', { + segment: 'settings panel', + module: 'pricing plan list', + control: 'plan resume action', + type: subscription.pro$.value?.plan, + category: subscription.pro$.value?.recurring, + }); + }, [subscription.pro$.value?.plan, subscription.pro$.value?.recurring]); return ( - diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/actions.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/actions.tsx index 737b921059..6d58ed354b 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/actions.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/actions.tsx @@ -1,4 +1,5 @@ import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; +import { mixpanel } from '@affine/core/utils'; import { useService } from '@toeverything/infra'; import { nanoid } from 'nanoid'; import type { PropsWithChildren } from 'react'; @@ -33,6 +34,13 @@ export const CancelAction = ({ // refresh idempotency key setIdempotencyKey(nanoid()); onOpenChange(false); + mixpanel.track('ChangePlanSucceeded', { + segment: 'settings panel', + module: 'pricing plan list', + control: 'plan cancel action', + type: subscription.pro$.value?.plan, + category: subscription.pro$.value?.recurring, + }); } finally { setIsMutating(false); } @@ -78,6 +86,13 @@ export const ResumeAction = ({ // refresh idempotency key setIdempotencyKey(nanoid()); onOpenChange(false); + mixpanel.track('ChangePlanSucceeded', { + segment: 'settings panel', + module: 'pricing plan list', + control: 'plan resume action', + type: subscription.pro$.value?.plan, + category: subscription.pro$.value?.recurring, + }); } finally { setIsMutating(false); } diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/cancel.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/cancel.tsx index e665dad692..9bcbb5e989 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/cancel.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/cancel.tsx @@ -1,6 +1,7 @@ import { Button, type ButtonProps, useConfirmModal } from '@affine/component'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { SubscriptionService } from '@affine/core/modules/cloud'; +import { mixpanel } from '@affine/core/utils'; import { SubscriptionPlan } from '@affine/graphql'; import { useI18n } from '@affine/i18n'; import { useService } from '@toeverything/infra'; @@ -17,6 +18,12 @@ export const AICancel = ({ ...btnProps }: AICancelProps) => { const { openConfirmModal } = useConfirmModal(); const cancel = useAsyncCallback(async () => { + mixpanel.track('PlanChangeStarted', { + segment: 'settings panel', + control: 'plan cancel action', + type: subscription.ai$.value?.plan, + category: subscription.ai$.value?.recurring, + }); openConfirmModal({ title: t['com.affine.payment.ai.action.cancel.confirm.title'](), description: @@ -40,6 +47,10 @@ export const AICancel = ({ ...btnProps }: AICancelProps) => { SubscriptionPlan.AI ); setIdempotencyKey(nanoid()); + mixpanel.track('ChangePlanSucceeded', { + segment: 'settings panel', + control: 'plan cancel action', + }); } finally { setMutating(false); } diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/resume.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/resume.tsx index 2c3ab7a037..bb15a1c3ba 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/resume.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/resume.tsx @@ -6,6 +6,7 @@ import { } from '@affine/component'; import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks'; import { SubscriptionService } from '@affine/core/modules/cloud'; +import { mixpanel } from '@affine/core/utils'; import { SubscriptionPlan } from '@affine/graphql'; import { useI18n } from '@affine/i18n'; import { SingleSelectSelectSolidIcon } from '@blocksuite/icons/rc'; @@ -26,6 +27,13 @@ export const AIResume = ({ ...btnProps }: AIResumeProps) => { const { openConfirmModal } = useConfirmModal(); const resume = useAsyncCallback(async () => { + mixpanel.track('PlanChangeStarted', { + segment: 'settings panel', + control: 'plan resume action', + type: subscription.ai$.value?.plan, + category: subscription.ai$.value?.recurring, + }); + openConfirmModal({ title: t['com.affine.payment.ai.action.resume.confirm.title'](), description: @@ -43,6 +51,10 @@ export const AIResume = ({ ...btnProps }: AIResumeProps) => { idempotencyKey, SubscriptionPlan.AI ); + mixpanel.track('ChangePlanSucceeded', { + segment: 'settings panel', + control: 'plan resume action', + }); notify({ icon: , iconColor: cssVar('processingColor'), diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/subscribe.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/subscribe.tsx index 355470e899..9e6dd547c8 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/subscribe.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/ai/actions/subscribe.tsx @@ -42,7 +42,7 @@ export const AISubscribe = ({ ...btnProps }: AISubscribeProps) => { const subscribe = useAsyncCallback(async () => { setMutating(true); - mixpanel.track('plan upgrade started', { + mixpanel.track('PlanUpgradeStarted', { category: SubscriptionRecurring.Yearly, type: SubscriptionPlan.AI, }); diff --git a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/plan-card.tsx b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/plan-card.tsx index 6fca8d5566..823779959b 100644 --- a/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/plan-card.tsx +++ b/packages/frontend/core/src/components/affine/setting-modal/general-setting/plans/plan-card.tsx @@ -167,11 +167,23 @@ const CurrentPlan = () => { const Downgrade = ({ disabled }: { disabled?: boolean }) => { const t = useI18n(); const [open, setOpen] = useState(false); + const subscription = useService(SubscriptionService).subscription; const tooltipContent = disabled ? t['com.affine.payment.downgraded-tooltip']() : null; + const handleClick = useCallback(() => { + setOpen(true); + mixpanel.track('PlanChangeStarted', { + segment: 'settings panel', + module: 'pricing plan list', + control: 'billing cancel action', + type: subscription.pro$.value?.plan, + category: subscription.pro$.value?.recurring, + }); + }, [subscription.pro$.value?.plan, subscription.pro$.value?.recurring]); + return ( @@ -179,7 +191,7 @@ const Downgrade = ({ disabled }: { disabled?: boolean }) => {