mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-09 00:59:02 +02:00
[Group Pricing] Add price change warning to cancellation flow (#22640)
* Add price change warning to cancellation flow * Fixes lint error from translated string * update pricing effective date --------- Co-authored-by: Kristina Hjertberg <kristina.hjertberg@overleaf.com> GitOrigin-RevId: d1b6982ff437d931144feffddcbddd96f5a3405b
This commit is contained in:
@@ -183,6 +183,8 @@
|
||||
"cancel": "",
|
||||
"cancel_add_on": "",
|
||||
"cancel_anytime": "",
|
||||
"cancel_group_price_warning": "",
|
||||
"cancel_group_price_warning_heading": "",
|
||||
"cancel_my_account": "",
|
||||
"cancel_my_subscription": "",
|
||||
"cancel_personal_subscription_first": "",
|
||||
|
||||
+48
-21
@@ -15,6 +15,9 @@ import ExtendTrialButton from './extend-trial-button'
|
||||
import { useLocation } from '../../../../../../../shared/hooks/use-location'
|
||||
import { debugConsole } from '@/utils/debugging'
|
||||
import OLButton from '@/features/ui/components/ol/ol-button'
|
||||
import moment from 'moment'
|
||||
import { getSplitTestVariant } from '@/utils/splitTestUtils'
|
||||
import OLNotification from '@/features/ui/components/ol/ol-notification'
|
||||
|
||||
const planCodeToDowngradeTo = 'paid-personal'
|
||||
|
||||
@@ -157,6 +160,8 @@ export function CancelSubscription() {
|
||||
isSuccessSecondaryAction ||
|
||||
isSuccessCancel
|
||||
|
||||
const groupPricingVariant = getSplitTestVariant('group-pricing-2025')
|
||||
|
||||
if (!personalSubscription || !('recurly' in personalSubscription)) return null
|
||||
|
||||
const showDowngrade = showDowngradeOption(
|
||||
@@ -171,6 +176,13 @@ export function CancelSubscription() {
|
||||
return <LoadingSpinner />
|
||||
}
|
||||
|
||||
const startDate = moment.utc(personalSubscription.recurly.account.created_at)
|
||||
const pricingChangeEffectiveDate = moment.utc('2025-01-08T12:00:00Z')
|
||||
const displayPricingWarning =
|
||||
groupPricingVariant === 'enabled' &&
|
||||
personalSubscription.plan.groupPlan &&
|
||||
startDate.isBefore(pricingChangeEffectiveDate)
|
||||
|
||||
async function handleCancelSubscription() {
|
||||
try {
|
||||
await runAsyncCancel(postJSON(cancelSubscriptionUrl))
|
||||
@@ -183,29 +195,44 @@ export function CancelSubscription() {
|
||||
const showExtendFreeTrial = userCanExtendTrial
|
||||
|
||||
return (
|
||||
<div className="text-center">
|
||||
<p>
|
||||
<strong>{t('wed_love_you_to_stay')}</strong>
|
||||
</p>
|
||||
<>
|
||||
{displayPricingWarning && (
|
||||
<OLNotification
|
||||
type="warning"
|
||||
content={
|
||||
<>
|
||||
<h2 className="pricing-warning-heading">
|
||||
{t('cancel_group_price_warning_heading')}
|
||||
</h2>
|
||||
<p>{t('cancel_group_price_warning')}</p>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<div className="text-center">
|
||||
<p>
|
||||
<strong>{t('wed_love_you_to_stay')}</strong>
|
||||
</p>
|
||||
|
||||
{(isErrorCancel || isErrorSecondaryAction) && <GenericErrorAlert />}
|
||||
{(isErrorCancel || isErrorSecondaryAction) && <GenericErrorAlert />}
|
||||
|
||||
<NotCancelOption
|
||||
showExtendFreeTrial={showExtendFreeTrial}
|
||||
showDowngrade={showDowngrade}
|
||||
isButtonDisabled={isButtonDisabled}
|
||||
isLoadingSecondaryAction={isLoadingSecondaryAction}
|
||||
isSuccessSecondaryAction={isSuccessSecondaryAction}
|
||||
planToDowngradeTo={planToDowngradeTo}
|
||||
runAsyncSecondaryAction={runAsyncSecondaryAction}
|
||||
/>
|
||||
<NotCancelOption
|
||||
showExtendFreeTrial={showExtendFreeTrial}
|
||||
showDowngrade={showDowngrade}
|
||||
isButtonDisabled={isButtonDisabled}
|
||||
isLoadingSecondaryAction={isLoadingSecondaryAction}
|
||||
isSuccessSecondaryAction={isSuccessSecondaryAction}
|
||||
planToDowngradeTo={planToDowngradeTo}
|
||||
runAsyncSecondaryAction={runAsyncSecondaryAction}
|
||||
/>
|
||||
|
||||
<ConfirmCancelSubscriptionButton
|
||||
showNoThanks={showExtendFreeTrial || showDowngrade}
|
||||
onClick={handleCancelSubscription}
|
||||
disabled={isButtonDisabled}
|
||||
isLoading={isSuccessCancel || isLoadingCancel}
|
||||
/>
|
||||
</div>
|
||||
<ConfirmCancelSubscriptionButton
|
||||
showNoThanks={showExtendFreeTrial || showDowngrade}
|
||||
onClick={handleCancelSubscription}
|
||||
disabled={isButtonDisabled}
|
||||
isLoading={isSuccessCancel || isLoadingCancel}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -298,3 +298,11 @@ a.row-link {
|
||||
color: @content-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
.pricing-warning-heading {
|
||||
font-size: @font-size-03;
|
||||
font-weight: 600;
|
||||
font-family: @font-family-sans-serif;
|
||||
margin-top: 0;
|
||||
color: @content-primary-on-dark-bg;
|
||||
}
|
||||
|
||||
@@ -410,3 +410,9 @@
|
||||
@include body-lg;
|
||||
}
|
||||
}
|
||||
|
||||
.pricing-warning-heading {
|
||||
@include body-base;
|
||||
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -248,6 +248,8 @@
|
||||
"cancel": "Cancel",
|
||||
"cancel_add_on": "Cancel add-on",
|
||||
"cancel_anytime": "We’re confident that you’ll love __appName__, but if not you can cancel anytime. We’ll give you your money back, no questions asked, if you let us know within 30 days.",
|
||||
"cancel_group_price_warning": "Our per-user prices are increasing in 2025. Keep your current rate for existing and new users by staying with us.",
|
||||
"cancel_group_price_warning_heading": "Don’t lose your current pricing",
|
||||
"cancel_my_account": "Cancel my subscription",
|
||||
"cancel_my_subscription": "Cancel my subscription",
|
||||
"cancel_personal_subscription_first": "You already have an individual subscription, would you like us to cancel this first before joining the group licence?",
|
||||
|
||||
@@ -49,6 +49,7 @@ export const annualActiveSubscription: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -90,6 +91,7 @@ export const annualActiveSubscriptionEuro: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -130,6 +132,7 @@ export const annualActiveSubscriptionPro: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -171,6 +174,7 @@ export const pastDueExpiredSubscription: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'true', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -212,6 +216,7 @@ export const canceledSubscription: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'true', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -253,6 +258,7 @@ export const pendingSubscriptionChange: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -305,6 +311,7 @@ export const groupActiveSubscription: GroupSubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
@@ -351,6 +358,7 @@ export const groupActiveSubscriptionWithPendingLicenseChange: GroupSubscription
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: {
|
||||
_: 'false',
|
||||
$: {
|
||||
@@ -415,6 +423,7 @@ export const trialSubscription: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'fake@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: {
|
||||
_: 'false',
|
||||
$: {
|
||||
@@ -487,6 +496,7 @@ export const trialCollaboratorSubscription: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'foo@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: {
|
||||
_: 'false',
|
||||
$: {
|
||||
@@ -537,6 +547,7 @@ export const monthlyActiveCollaborator: RecurlySubscription = {
|
||||
activeCoupons: [],
|
||||
account: {
|
||||
email: 'foo@example.com',
|
||||
created_at: '2024-12-31T09:40:27.000Z',
|
||||
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
|
||||
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
|
||||
},
|
||||
|
||||
@@ -26,6 +26,7 @@ type Recurly = {
|
||||
activeCoupons: any[] // TODO: confirm type in array
|
||||
account: {
|
||||
email: string
|
||||
created_at: string
|
||||
// data via Recurly API
|
||||
has_canceled_subscription: {
|
||||
_: 'false' | 'true'
|
||||
|
||||
Reference in New Issue
Block a user