Ver Fonte

Merge pull request #24148 from overleaf/revert-24066-ds-group-discount-2

Revert "Group plans - Reintroduce 10% discount for group plans (part 2)"

GitOrigin-RevId: 2d8a8d117222daa997e4d0632a9e7235559a8b8c
Davinder Singh há 1 ano atrás
pai
commit
37dc516ea2

+ 0 - 9
services/web/app/src/Features/Subscription/SubscriptionController.js

@@ -48,14 +48,6 @@ async function userSubscriptionPage(req, res) {
 
   await SplitTestHandler.promises.getAssignment(req, res, 'pause-subscription')
 
-  const groupPricingDiscount = await SplitTestHandler.promises.getAssignment(
-    req,
-    res,
-    'group-discount-10'
-  )
-
-  const showGroupDiscount = groupPricingDiscount.variant === 'enabled'
-
   const { variant: flexibleLicensingVariant } =
     await SplitTestHandler.promises.getAssignment(
       req,
@@ -175,7 +167,6 @@ async function userSubscriptionPage(req, res) {
     managedGroupSubscriptions,
     managedInstitutions,
     managedPublishers,
-    showGroupDiscount,
     currentInstitutionsWithLicence,
     canUseFlexibleLicensing:
       personalSubscription?.plan?.canUseFlexibleLicensing,

+ 0 - 1
services/web/app/views/subscriptions/dashboard-react.pug

@@ -23,7 +23,6 @@ block append meta
 	meta(name="ol-plans", data-type="json" content=plans)
 	meta(name="ol-groupSettingsAdvertisedFor", data-type="json" content=groupSettingsAdvertisedFor)
 	meta(name="ol-canUseFlexibleLicensing", data-type="boolean", content=canUseFlexibleLicensing)
-	meta(name="ol-showGroupDiscount", data-type="boolean", content=showGroupDiscount)
 	meta(name="ol-groupSettingsEnabledFor", data-type="json" content=groupSettingsEnabledFor)
 	meta(name="ol-user" data-type="json" content=user)
 	if (personalSubscription && personalSubscription.recurly)

+ 3 - 2
services/web/frontend/extracted-translations.json

@@ -137,7 +137,6 @@
   "anyone_with_link_can_view": "",
   "app_on_x": "",
   "appearance": "",
-  "apply_educational_discount_description_with_group_discount": "",
   "apply_suggestion": "",
   "archive": "",
   "archive_projects": "",
@@ -200,6 +199,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": "",
@@ -889,6 +890,7 @@
   "let_us_know_what_you_think": "",
   "lets_get_those_premium_features": "",
   "library": "",
+  "license_for_educational_purposes_confirmation": "",
   "limited_document_history": "",
   "limited_offer": "",
   "limited_to_n_editors": "",
@@ -1414,7 +1416,6 @@
   "save_or_cancel-cancel": "",
   "save_or_cancel-or": "",
   "save_or_cancel-save": "",
-  "save_x_or_more": "",
   "saving": "",
   "saving_notification_with_seconds": "",
   "search": "",

+ 21 - 0
services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-plan/cancel-subscription.tsx

@@ -15,6 +15,8 @@ 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 OLNotification from '@/features/ui/components/ol/ol-notification'
 
 const planCodeToDowngradeTo = 'paid-personal'
 
@@ -170,6 +172,12 @@ 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 =
+    personalSubscription.plan.groupPlan &&
+    startDate.isBefore(pricingChangeEffectiveDate)
+
   async function handleCancelSubscription() {
     try {
       await runAsyncCancel(postJSON(cancelSubscriptionUrl))
@@ -183,6 +191,19 @@ export function CancelSubscription() {
 
   return (
     <>
+      {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>

+ 14 - 9
services/web/frontend/js/features/subscription/components/dashboard/states/active/change-plan/modals/change-to-group-modal.tsx

@@ -118,7 +118,6 @@ export function ChangeToGroupModal() {
   const { modal: contactModal, showModal: showContactModal } =
     useContactUsModal({ autofillProjectUrl: false })
   const groupPlans = getMeta('ol-groupPlans')
-  const showGroupDiscount = getMeta('ol-showGroupDiscount')
   const personalSubscription = getMeta('ol-subscription') as RecurlySubscription
   const [error, setError] = useState(false)
   const [inflight, setInflight] = useState(false)
@@ -173,11 +172,6 @@ export function ChangeToGroupModal() {
         <OLModalHeader closeButton>
           <OLModalTitle className="lh-sm">
             {t('customize_your_group_subscription')}
-            {showGroupDiscount && (
-              <p className="group-subscription-modal-title-discount">
-                {t('save_x_or_more', { percentage: '10%' })}
-              </p>
-            )}
           </OLModalTitle>
         </OLModalHeader>
 
@@ -265,9 +259,20 @@ export function ChangeToGroupModal() {
                         setGroupPlanToChangeToUsage('enterprise')
                       }
                     }}
-                    label={t(
-                      'apply_educational_discount_description_with_group_discount'
-                    )}
+                    label={
+                      <Trans
+                        i18nKey="license_for_educational_purposes_confirmation"
+                        values={{ percent: educationalPercentDiscount }}
+                        shouldUnescape
+                        tOptions={{ interpolation: { escapeValue: true } }}
+                        components={[
+                          /* eslint-disable-next-line react/jsx-key */
+                          <strong />,
+                          /* eslint-disable-next-line react/jsx-key */
+                          <br />,
+                        ]}
+                      />
+                    }
                   />
                 </form>
               </div>

+ 0 - 1
services/web/frontend/js/utils/meta.ts

@@ -194,7 +194,6 @@ export interface Meta {
   'ol-showAiErrorAssistant': boolean
   'ol-showBrlGeoBanner': boolean
   'ol-showCouponField': boolean
-  'ol-showGroupDiscount': boolean
   'ol-showGroupsAndEnterpriseBanner': boolean
   'ol-showInrGeoBanner': boolean
   'ol-showLATAMBanner': boolean

+ 0 - 7
services/web/frontend/stylesheets/bootstrap-5/pages/subscription.scss

@@ -37,13 +37,6 @@
  *  MODALS
  */
 
-.group-subscription-modal-title-discount {
-  @include body-base;
-
-  margin-top: var(--spacing-02);
-  margin-bottom: unset;
-}
-
 .group-subscription-modal {
   .circle {
     font-size: var(--font-size-06);

+ 3 - 1
services/web/locales/en.json

@@ -261,6 +261,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?",
@@ -1170,6 +1172,7 @@
   "libraries": "Libraries",
   "library": "Library",
   "license": "License",
+  "license_for_educational_purposes_confirmation": "<0>__percent__% educational discount</0><1/>I confirm this subscription is for educational purposes (applies to students or faculty using __appName__ for teaching)",
   "limited_document_history": "Limited document history",
   "limited_to_n_editors": "Limited to __count__ editor",
   "limited_to_n_editors_per_project": "Limited to __count__ editor per project",
@@ -1873,7 +1876,6 @@
   "save_or_cancel-cancel": "Cancel",
   "save_or_cancel-or": "or",
   "save_or_cancel-save": "Save",
-  "save_x_or_more": "Save __percentage__ or more",
   "saving": "Saving",
   "saving_notification_with_seconds": "Saving __docname__... (__seconds__ seconds of unsaved changes)",
   "search": "Search",

+ 5 - 4
services/web/test/frontend/features/subscription/components/dashboard/states/active/change-plan/change-plan.test.tsx

@@ -322,7 +322,7 @@ describe('<ChangePlanModal />', function () {
     const standardPlanCollaboratorText = '10 collaborators per project'
     const professionalPlanCollaboratorText = 'Unlimited collaborators'
     const educationInputLabel =
-      'Get a total of 40% off for groups using Overleaf for teaching'
+      '40% educational discountI confirm this subscription is for educational purposes (applies to students or faculty using Overleaf for teaching)'
 
     let modal: HTMLElement
     async function openModal() {
@@ -368,14 +368,15 @@ describe('<ChangePlanModal />', function () {
       expect(sizeSelect.value).to.equal('10')
       const sizeOption = within(sizeSelect).getAllByRole('option')
       expect(sizeOption.length).to.equal(groupPlans.sizes.length)
-      within(modal).getByText(
-        'Get a total of 40% off for groups using Overleaf for teaching'
-      )
+      within(modal).getByText('40% educational discount')
 
       const educationalCheckbox = within(modal).getByRole(
         'checkbox'
       ) as HTMLInputElement
       expect(educationalCheckbox.checked).to.be.false
+      within(modal).getByText(
+        'I confirm this subscription is for educational purposes (applies to students or faculty using Overleaf for teaching)'
+      )
 
       within(modal).getByText(
         'Your new subscription will be billed immediately to your current payment method.'