Skip to content

Commit

Permalink
fix: improve downgrade flow in onboarding (#22436)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Zach Waterfield <[email protected]>
  • Loading branch information
3 people authored Jul 24, 2024
1 parent 0ff2c22 commit cbf16e8
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 24 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions frontend/src/lib/utils/eventUsageLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ export const eventUsageLogic = kea<eventUsageLogicType>([
reportTeamSettingChange: (name: string, value: any) => ({ name, value }),
reportActivationSideBarTaskClicked: (key: string) => ({ key }),
reportBillingUpgradeClicked: (plan: string) => ({ plan }),
reportBillingDowngradeClicked: (plan: string) => ({ plan }),
reportRoleCreated: (role: string) => ({ role }),
reportResourceAccessLevelUpdated: (resourceType: Resource, roleName: string, accessLevel: AccessLevel) => ({
resourceType,
Expand Down Expand Up @@ -1179,6 +1180,11 @@ export const eventUsageLogic = kea<eventUsageLogicType>([
plan,
})
},
reportBillingDowngradeClicked: ({ plan }) => {
posthog.capture('billing downgrade button clicked', {
plan,
})
},
reportRoleCreated: ({ role }) => {
posthog.capture('new role created', {
role,
Expand Down
27 changes: 18 additions & 9 deletions frontend/src/scenes/billing/AllProductsPlanComparison.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ export const AllProductsPlanComparison = ({
}
const { billing, redirectPath, timeRemainingInSeconds, timeTotalInSeconds } = useValues(billingLogic)
const { ref: planComparisonRef } = useResizeObserver()
const { reportBillingUpgradeClicked } = useActions(eventUsageLogic)
const { reportBillingUpgradeClicked, reportBillingDowngradeClicked } = useActions(eventUsageLogic)
const currentPlanIndex = plans.findIndex((plan) => plan.current_plan)
const { surveyID, comparisonModalHighlightedFeatureKey } = useValues(billingProductLogic({ product }))
const { reportSurveyShown, setSurveyResponse } = useActions(billingProductLogic({ product }))
const { surveyID, comparisonModalHighlightedFeatureKey, billingProductLoading } = useValues(
billingProductLogic({ product })
)
const { reportSurveyShown, setSurveyResponse, setBillingProductLoading } = useActions(
billingProductLogic({ product })
)
const { featureFlags } = useValues(featureFlagLogic)

const nonInclusionProducts = billing?.products.filter((p) => !p.inclusion_only) || []
Expand All @@ -164,6 +168,8 @@ export const AllProductsPlanComparison = ({
to={
plan.contact_support
? 'mailto:[email protected]?subject=Enterprise%20plan%20request'
: i < currentPlanIndex
? undefined // Downgrade action handled in onClick
: getUpgradeProductLink({
product,
redirectPath,
Expand All @@ -190,14 +196,17 @@ export const AllProductsPlanComparison = ({
}
onClick={() => {
if (!plan.current_plan) {
// TODO: add current plan key and new plan key
reportBillingUpgradeClicked(product.type)
}
if (plan.included_if == 'has_subscription' && !plan.current_plan && i < currentPlanIndex) {
setSurveyResponse(product.type, '$survey_response_1')
reportSurveyShown(UNSUBSCRIBE_SURVEY_ID, product.type)
setBillingProductLoading(product.type)
if (i < currentPlanIndex) {
setSurveyResponse(product.type, '$survey_response_1')
reportSurveyShown(UNSUBSCRIBE_SURVEY_ID, product.type)
reportBillingDowngradeClicked(product.type)
} else {
reportBillingUpgradeClicked(product.type)
}
}
}}
loading={billingProductLoading === product.type && !plan.current_plan && !plan.contact_support}
data-attr={`upgrade-${plan.name}`}
>
{plan.current_plan
Expand Down
27 changes: 18 additions & 9 deletions frontend/src/scenes/billing/PlanComparison.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,14 @@ export const PlanComparison = ({
const fullyFeaturedPlan = plans[plans.length - 1]
const { billing, redirectPath, timeRemainingInSeconds, timeTotalInSeconds } = useValues(billingLogic)
const { width, ref: planComparisonRef } = useResizeObserver()
const { reportBillingUpgradeClicked } = useActions(eventUsageLogic)
const { reportBillingUpgradeClicked, reportBillingDowngradeClicked } = useActions(eventUsageLogic)
const currentPlanIndex = plans.findIndex((plan) => plan.current_plan)
const { surveyID, comparisonModalHighlightedFeatureKey } = useValues(billingProductLogic({ product }))
const { reportSurveyShown, setSurveyResponse } = useActions(billingProductLogic({ product }))
const { surveyID, comparisonModalHighlightedFeatureKey, billingProductLoading } = useValues(
billingProductLogic({ product })
)
const { reportSurveyShown, setSurveyResponse, setBillingProductLoading } = useActions(
billingProductLogic({ product })
)
const { featureFlags } = useValues(featureFlagLogic)

const ctaAction = billing?.subscription_level === 'custom' ? 'Subscribe' : 'Upgrade'
Expand All @@ -135,6 +139,8 @@ export const PlanComparison = ({
to={
plan.contact_support
? 'mailto:[email protected]?subject=Enterprise%20plan%20request'
: i < currentPlanIndex
? undefined // Downgrade action handled in onClick
: getUpgradeProductLink({
product,
redirectPath,
Expand All @@ -161,14 +167,17 @@ export const PlanComparison = ({
}
onClick={() => {
if (!plan.current_plan) {
// TODO: add current plan key and new plan key
reportBillingUpgradeClicked(product.type)
}
if (plan.included_if == 'has_subscription' && !plan.current_plan && i < currentPlanIndex) {
setSurveyResponse(product.type, '$survey_response_1')
reportSurveyShown(UNSUBSCRIBE_SURVEY_ID, product.type)
setBillingProductLoading(product.type)
if (i < currentPlanIndex) {
setSurveyResponse(product.type, '$survey_response_1')
reportSurveyShown(UNSUBSCRIBE_SURVEY_ID, product.type)
reportBillingDowngradeClicked(product.type)
} else {
reportBillingUpgradeClicked(product.type)
}
}
}}
loading={billingProductLoading === product.type && !plan.current_plan && !plan.contact_support}
data-attr={`upgrade-${plan.name}`}
>
{plan.current_plan
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/scenes/billing/billingLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ export const billingLogic = kea<billingLogicType>([
},

deactivateProduct: async (key: string) => {
// clear upgrade params from URL
const currentURL = new URL(window.location.href)
currentURL.searchParams.delete('upgraded')
currentURL.searchParams.delete('products')
router.actions.push(currentURL.pathname + currentURL.search)

actions.resetUnsubscribeError()
try {
const response = await api.getResponse('api/billing/deactivate?products=' + key)
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/scenes/billing/billingProductLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,15 @@ export const billingProductLogic = kea<billingProductLogicType>([
})
actions.setSurveyID('')
},
deactivateProductSuccess: () => {
deactivateProductSuccess: async (_, breakpoint) => {
if (!values.unsubscribeError) {
const textAreaNotEmpty = values.surveyResponse['$survey_response']?.length > 0
textAreaNotEmpty
? actions.reportSurveySent(values.surveyID, values.surveyResponse)
: actions.reportSurveyDismissed(values.surveyID)
}
await breakpoint(200)
location.reload()
},
setScrollToProductKey: ({ scrollToProductKey }) => {
if (scrollToProductKey && scrollToProductKey === props.product.type) {
Expand Down
11 changes: 10 additions & 1 deletion frontend/src/scenes/onboarding/Onboarding.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Spinner } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { FEATURE_FLAGS, SESSION_REPLAY_MINIMUM_DURATION_OPTIONS } from 'lib/constants'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
Expand Down Expand Up @@ -87,7 +88,15 @@ const OnboardingWrapper = ({ children }: { children: React.ReactNode }): JSX.Ele
setAllSteps(steps)
}

return (currentOnboardingStep as JSX.Element) || <></>
if (!currentOnboardingStep) {
return (
<div className="flex items-center justify-center my-20">
<Spinner className="text-2xl text-muted w-10 h-10" />
</div>
)
}

return currentOnboardingStep || <></>
}

const ProductAnalyticsOnboarding = (): JSX.Element => {
Expand Down
11 changes: 7 additions & 4 deletions frontend/src/scenes/onboarding/OnboardingBillingStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const OnboardingBillingStep = ({
product: BillingProductV2Type
stepKey?: OnboardingStepKey
}): JSX.Element => {
const { billing, redirectPath } = useValues(billingLogic)
const { billing, redirectPath, billingLoading } = useValues(billingLogic)
const { productKey } = useValues(onboardingLogic)
const { reportBillingUpgradeClicked } = useActions(eventUsageLogic)

Expand All @@ -37,7 +37,7 @@ export const OnboardingBillingStep = ({
showSkip={!product.subscribed}
stepKey={stepKey}
continueOverride={
product?.subscribed ? undefined : (
product?.subscribed && !billingLoading ? undefined : (
<BillingUpgradeCTA
// TODO: redirect path won't work properly until navigation is properly set up
to={getUpgradeProductLink({
Expand All @@ -48,6 +48,7 @@ export const OnboardingBillingStep = ({
type="primary"
status="alt"
center
disabledReason={billingLoading && 'Please wait...'}
disableClientSideRouting
onClick={() => {
reportBillingUpgradeClicked(product.type)
Expand All @@ -59,7 +60,7 @@ export const OnboardingBillingStep = ({
)
}
>
{billing?.products && productKey && product ? (
{billing?.products && productKey && product && !billingLoading ? (
<div className="mt-6">
{product.subscribed && (
<div className="mb-8">
Expand Down Expand Up @@ -97,7 +98,9 @@ export const OnboardingBillingStep = ({
)}
</div>
) : (
<Spinner className="text-lg" />
<div className="flex items-center justify-center my-20">
<Spinner className="text-2xl text-muted w-10 h-10" />
</div>
)}
</OnboardingStep>
)
Expand Down

0 comments on commit cbf16e8

Please sign in to comment.