From a9ab2475077f752697f2af2f7956968b3a532c3a Mon Sep 17 00:00:00 2001 From: Kristina <7614497+khjrtbrg@users.noreply.github.com> Date: Mon, 9 Feb 2026 15:40:33 +0100 Subject: [PATCH] [web] add notification message to the dashboard for migrated subscriptions (#31429) GitOrigin-RevId: 12c14020b9e43e6544bdbd363fd2bc0d4051c80b --- .../Subscription/PaymentProviderEntities.mjs | 2 ++ .../SubscriptionViewModelBuilder.mjs | 2 ++ .../web/frontend/extracted-translations.json | 1 + .../dashboard/states/active/active.tsx | 26 ++++++++++++++----- services/web/locales/en.json | 1 + .../subscription/fixtures/subscriptions.ts | 17 ++++++++++++ .../SubscriptionViewModelBuilder.test.mjs | 1 + .../subscription/dashboard/subscription.ts | 1 + 8 files changed, 44 insertions(+), 7 deletions(-) diff --git a/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs b/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs index da7057ad39..ea9857c9e1 100644 --- a/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs +++ b/services/web/app/src/Features/Subscription/PaymentProviderEntities.mjs @@ -53,6 +53,7 @@ export class PaymentProviderSubscription { * @param {Date|null} [props.pausePeriodStart] * @param {Date|null} [props.pausePeriodEnd] * @param {number|null} [props.remainingPauseCycles] + * @param {boolean} [props.isMigratedFromRecurly] */ constructor(props) { this.id = props.id @@ -80,6 +81,7 @@ export class PaymentProviderSubscription { this.pausePeriodStart = props.pausePeriodStart ?? null this.pausePeriodEnd = props.pausePeriodEnd ?? null this.remainingPauseCycles = props.remainingPauseCycles ?? null + this.isMigratedFromRecurly = props.isMigratedFromRecurly ?? false } /** diff --git a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs index 73c3088bf8..3d2ee09e72 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.mjs @@ -305,6 +305,8 @@ async function buildUsersSubscriptionViewModel(user, locale = 'en') { remainingPauseCycles: paymentRecord.subscription.remainingPauseCycles, isEligibleForPause, isEligibleForGroupPlan: !isInTrial, + isMigratedFromRecurly: + paymentRecord.subscription.isMigratedFromRecurly ?? false, } const isMonthlyCollaboratorPlan = diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index baa106df64..5c9a600d7e 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -2203,6 +2203,7 @@ "view_only_reviewer_downgraded": "", "view_options": "", "view_payment_portal": "", + "view_payment_portal_disclaimer": "", "view_pdf": "", "view_your_invoices": "", "viewer": "", diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx index 6cc3c7f935..30b7d3384d 100644 --- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx +++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/active.tsx @@ -164,13 +164,25 @@ export function ActiveSubscription({ ) : ( - - {t('view_payment_portal')} - + <> + + {t('view_payment_portal')} + + {subscription.payment.isMigratedFromRecurly && ( +

+ + ]} // eslint-disable-line react/jsx-key, jsx-a11y/anchor-has-content + /> + +

+ )} + )}
diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 4e4ceda79d..b7c0645ba5 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -2752,6 +2752,7 @@ "view_only_reviewer_downgraded": "View only. Upgrade to restore review access.", "view_options": "View options", "view_payment_portal": "View invoices and billing details", + "view_payment_portal_disclaimer": "You might have older invoices prior to February 2026. Please <0>contact support if you need to get access to these.", "view_pdf": "View PDF", "view_source": "View Source", "view_your_invoices": "View your invoices", diff --git a/services/web/test/frontend/features/subscription/fixtures/subscriptions.ts b/services/web/test/frontend/features/subscription/fixtures/subscriptions.ts index 9f6795ee71..39f8e0e339 100644 --- a/services/web/test/frontend/features/subscription/fixtures/subscriptions.ts +++ b/services/web/test/frontend/features/subscription/fixtures/subscriptions.ts @@ -55,6 +55,7 @@ export const annualActiveSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -101,6 +102,7 @@ export const annualActiveSubscriptionWithCoupons: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -145,6 +147,7 @@ export const pendingPausedSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -189,6 +192,7 @@ export const pausedSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -234,6 +238,7 @@ export const annualActiveSubscriptionWithAddons: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, addOns: [{ addOnCode: 'assistant', quantity: 1, unitAmountInCents: 10000 }], } @@ -278,6 +283,7 @@ export const annualActiveSubscriptionEuro: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: true, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -320,6 +326,7 @@ export const annualActiveSubscriptionPro: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: true, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -363,6 +370,7 @@ export const pastDueExpiredSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: true, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -406,6 +414,7 @@ export const canceledSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: true, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -456,6 +465,7 @@ export const pendingAddOnChange: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, pendingPlan: { planCode: 'collaborator-annual', @@ -506,6 +516,7 @@ export const pendingSubscriptionChange: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, pendingPlan: { planCode: 'professional-annual', @@ -560,6 +571,7 @@ export const groupActiveSubscription: GroupSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -607,6 +619,7 @@ export const groupProfessionalActiveSubscription: GroupSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -657,6 +670,7 @@ export const groupActiveSubscriptionWithPendingLicenseChange: GroupSubscription isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, pendingPlan: { planCode: 'group_collaborator_10_enterprise', @@ -709,6 +723,7 @@ export const trialSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -772,6 +787,7 @@ export const trialCollaboratorSubscription: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: true, isEligibleForDowngradeUpsell: false, + isMigratedFromRecurly: false, }, } @@ -814,5 +830,6 @@ export const monthlyActiveCollaborator: PaidSubscription = { isEligibleForGroupPlan: true, isEligibleForPause: true, isEligibleForDowngradeUpsell: true, + isMigratedFromRecurly: false, }, } diff --git a/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs b/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs index d87ae4bf24..30dc76c20c 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs +++ b/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilder.test.mjs @@ -721,6 +721,7 @@ describe('SubscriptionViewModelBuilder', function () { isEligibleForGroupPlan: true, isEligibleForPause: false, isEligibleForDowngradeUpsell: true, + isMigratedFromRecurly: false, }) }) diff --git a/services/web/types/subscription/dashboard/subscription.ts b/services/web/types/subscription/dashboard/subscription.ts index b1d03a46dd..a8d9b3d819 100644 --- a/services/web/types/subscription/dashboard/subscription.ts +++ b/services/web/types/subscription/dashboard/subscription.ts @@ -56,6 +56,7 @@ type PaymentProviderRecord = { isEligibleForPause: boolean isEligibleForGroupPlan: boolean isEligibleForDowngradeUpsell: boolean + isMigratedFromRecurly: boolean } export type GroupPolicy = {