From d3def551ae5824aa9bd1d2cd24ad8d5e01b40b17 Mon Sep 17 00:00:00 2001 From: Kristina <7614497+khjrtbrg@users.noreply.github.com> Date: Tue, 28 Oct 2025 15:40:43 +0100 Subject: [PATCH] [web] improve messaging when upgrading from standalone add-on to premium plan + add-on (#29330) * update userCanStartTrial to consider standalone add-ons * display correct disabled message on hover * display error message on preview plan purchase page GitOrigin-RevId: 57c4e4267c1fd0ea892df8c0f5443ad74847147c --- .../Subscription/SubscriptionController.mjs | 15 ++++++++++++- .../views/subscriptions/preview-change.pug | 5 +++++ .../web/frontend/extracted-translations.json | 1 + .../preview-subscription-change/root.tsx | 2 ++ .../trial-disabled-notification.tsx | 21 +++++++++++++++++++ services/web/frontend/js/utils/meta.ts | 1 + services/web/locales/en.json | 3 ++- 7 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 services/web/frontend/js/features/subscription/components/preview-subscription-change/trial-disabled-notification.tsx diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.mjs b/services/web/app/src/Features/Subscription/SubscriptionController.mjs index 1a04cc49d5..b19c300260 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionController.mjs @@ -747,7 +747,19 @@ async function previewSubscription(req, res, next) { } // TODO: use PaymentService to fetch plan information const plan = await RecurlyClient.promises.getPlan(planCode) - const userId = SessionManager.getLoggedInUserId(req.session) + const user = SessionManager.getSessionUser(req.session) + const userId = user?._id + + let trialDisabledReason + if (planCode.includes('_free_trial')) { + const trialEligibility = ( + await Modules.promises.hooks.fire('userCanStartTrial', user) + )?.[0] + if (!trialEligibility.canStartTrial) { + trialDisabledReason = trialEligibility.disabledReason + } + } + const subscriptionChange = await SubscriptionHandler.promises.previewSubscriptionChange( userId, @@ -770,6 +782,7 @@ async function previewSubscription(req, res, next) { res.render('subscriptions/preview-change', { changePreview, redirectedPaymentErrorCode: req.query.errorCode, + trialDisabledReason, }) } diff --git a/services/web/app/views/subscriptions/preview-change.pug b/services/web/app/views/subscriptions/preview-change.pug index 96029d5926..1e125c982b 100644 --- a/services/web/app/views/subscriptions/preview-change.pug +++ b/services/web/app/views/subscriptions/preview-change.pug @@ -16,6 +16,11 @@ block append meta data-type='string' content=redirectedPaymentErrorCode ) + meta( + name='ol-trialDisabledReason' + data-type='string' + content=trialDisabledReason + ) block content main#main-content.content.content-alt diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index ecd74cf69d..b57e69c976 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -2284,6 +2284,7 @@ "youre_adding_x_licenses_to_your_plan_giving_you_a_total_of_y_licenses": "", "youre_already_setup_for_sso": "", "youre_joining": "", + "youre_not_eligible_for_a_free_trial": "", "youre_on_free_trial_which_ends_on": "", "youre_signed_in_as_logout": "", "youve_added_more_licenses": "", diff --git a/services/web/frontend/js/features/subscription/components/preview-subscription-change/root.tsx b/services/web/frontend/js/features/subscription/components/preview-subscription-change/root.tsx index c54d10c9a6..76b5470f27 100644 --- a/services/web/frontend/js/features/subscription/components/preview-subscription-change/root.tsx +++ b/services/web/frontend/js/features/subscription/components/preview-subscription-change/root.tsx @@ -23,6 +23,7 @@ import { useFeatureFlag } from '@/shared/context/split-test-context' import PaymentErrorNotification from '@/features/subscription/components/shared/payment-error-notification' import handleStripePaymentAction from '../../util/handle-stripe-payment-action' import RedirectedPaymentErrorNotification from '../shared/redirected-payment-error-notification' +import TrialDisabledNotification from './trial-disabled-notification' function PreviewSubscriptionChange() { const preview = getMeta( @@ -101,6 +102,7 @@ function PreviewSubscriptionChange() { + {preview.change.type === 'add-on-purchase' ? (

diff --git a/services/web/frontend/js/features/subscription/components/preview-subscription-change/trial-disabled-notification.tsx b/services/web/frontend/js/features/subscription/components/preview-subscription-change/trial-disabled-notification.tsx new file mode 100644 index 0000000000..1b9b143caa --- /dev/null +++ b/services/web/frontend/js/features/subscription/components/preview-subscription-change/trial-disabled-notification.tsx @@ -0,0 +1,21 @@ +import { useTranslation } from 'react-i18next' +import OLNotification from '@/shared/components/ol/ol-notification' +import getMeta from '@/utils/meta' + +export default function TrialDisabledNotification() { + const { t } = useTranslation() + const trialDisabledReason = getMeta('ol-trialDisabledReason') + + if (!trialDisabledReason) { + return null + } + + return ( + + ) +} diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts index 7bb10ec133..020e19a41b 100644 --- a/services/web/frontend/js/utils/meta.ts +++ b/services/web/frontend/js/utils/meta.ts @@ -300,6 +300,7 @@ export interface Meta { 'ol-translationLoadErrorMessage': string 'ol-translationMaintenance': string 'ol-translationUnableToJoin': string + 'ol-trialDisabledReason': string | undefined 'ol-usGovBannerVariant': USGovBannerVariant 'ol-useShareJsHash': boolean 'ol-user': User diff --git a/services/web/locales/en.json b/services/web/locales/en.json index a90d6db9f2..54425e969b 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -2844,12 +2844,13 @@ "youre_adding_x_licenses_to_your_plan_giving_you_a_total_of_y_licenses": "You’re adding <0>__adding__ licenses to your plan giving you a total of <1>__total__ licenses.", "youre_already_setup_for_sso": "You’re already set up for SSO", "youre_joining": "You’re joining", + "youre_not_eligible_for_a_free_trial": "You’re not eligible for a free trial. Upgrade to start using premium features.", "youre_on_free_trial_which_ends_on": "You’re on a free trial which ends on <0>__date__.", "youre_signed_in_as_logout": "You’re signed in as <0>__email__. <1>Log out.", "youre_signed_up": "You’re signed up", "youve_added_more_licenses": "You’ve added more license(s)!", "youve_added_x_more_licenses_to_your_subscription_invite_people": "You’ve added __users__ more license(s) to your subscription. <0>Invite people.", - "youve_already_used_your_free_tial": "You’ve already used your free trial. Upgrade to continue using premium features.", + "youve_already_used_your_free_trial": "You’ve already used your free trial. Upgrade to continue using premium features.", "youve_lost_collaboration_access": "You’ve lost collaboration access", "youve_paused_your_subscription": "Your <0>__planName__ subscription is paused until <0>__reactivationDate__, then it’ll automatically unpause. You can unpause early at any time.", "youve_unlinked_all_users": "You’ve unlinked all users",