Просмотр исходного кода

Merge pull request #23350 from overleaf/mf-nudge-to-annual-test

[web] Implement "Nudge to annual" split test

GitOrigin-RevId: 8dcd042fc54ede601f6db95a61feebaf15c849b6
M Fahru 1 год назад
Родитель
Сommit
84c66d5eae

+ 4 - 0
services/web/frontend/extracted-translations.json

@@ -126,6 +126,7 @@
   "an_email_has_already_been_sent_to": "",
   "an_error_occured_while_restoring_project": "",
   "an_error_occurred_when_verifying_the_coupon_code": "",
+  "annual_discount": "",
   "anonymous": "",
   "anyone_with_link_can_edit": "",
   "anyone_with_link_can_view": "",
@@ -1376,6 +1377,7 @@
   "saml_missing_signature_error": "",
   "saml_response": "",
   "save": "",
+  "save_20_percent_when_you_switch_to_annual": "",
   "save_or_cancel-cancel": "",
   "save_or_cancel-or": "",
   "save_or_cancel-save": "",
@@ -1595,6 +1597,7 @@
   "sure_you_want_to_change_plan": "",
   "sure_you_want_to_delete": "",
   "sure_you_want_to_leave_group": "",
+  "switch_back_to_monthly_pay_20_more": "",
   "switch_plan": "",
   "switch_to_editor": "",
   "switch_to_pdf": "",
@@ -1979,6 +1982,7 @@
   "you_are_a_manager_of_publisher_x": "",
   "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "",
   "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "",
+  "you_are_now_saving_20_percent": "",
   "you_are_on_a_paid_plan_contact_support_to_find_out_more": "",
   "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "",
   "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "",

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

@@ -175,6 +175,10 @@
 
       h4 {
         margin-bottom: var(--spacing-06);
+
+        &:has(+ .payment-nudge-annual-button) {
+          margin-bottom: 0;
+        }
       }
 
       .features-list {
@@ -440,6 +444,16 @@
   }
 }
 
+.payment-nudge-annual-button {
+  margin: var(--spacing-02) 0 var(--spacing-06) 0;
+
+  @include body-sm;
+
+  button {
+    padding: 0;
+  }
+}
+
 .add-on-card {
   display: flex;
   align-items: center;

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

@@ -1837,6 +1837,7 @@
   "saml_response": "SAML Response",
   "save": "Save",
   "save_20_percent": "save 20%",
+  "save_20_percent_when_you_switch_to_annual": "Save 20% when you switch to annual",
   "save_or_cancel-cancel": "Cancel",
   "save_or_cancel-or": "or",
   "save_or_cancel-save": "Save",
@@ -2093,6 +2094,7 @@
   "sure_you_want_to_delete": "Are you sure you want to permanently delete the following files?",
   "sure_you_want_to_leave_group": "Are you sure you want to leave this group?",
   "sv": "Swedish",
+  "switch_back_to_monthly_pay_20_more": "Switch back to monthly (20% more)",
   "switch_plan": "Switch plan",
   "switch_to_editor": "Switch to editor",
   "switch_to_pdf": "Switch to PDF",
@@ -2537,6 +2539,7 @@
   "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are a <1>manager</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>.",
   "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "You are a <1>manager</1> of the <0>__planName__</0> group subscription <1>__groupName__</1> administered by <1>you (__adminEmail__</1>).",
   "you_are_currently_logged_in_as": "You are currently logged in as <b>__email__</b>.",
+  "you_are_now_saving_20_percent": "You are now saving 20%",
   "you_are_on_a_paid_plan_contact_support_to_find_out_more": "You’re on an __appName__ Paid plan. <0>Contact support</0> to find out more.",
   "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "You are on our <0>__planName__</0> plan as a <1>confirmed member</1> of <1>__institutionName__</1>",
   "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "You are on our <0>__planName__</0> plan as a <1>member</1> of the group subscription <1>__groupName__</1> administered by <1>__adminEmail__</1>",

+ 1 - 1
services/web/types/recurly/pricing/subscription.ts

@@ -5,7 +5,7 @@ import {
   Tax,
 } from 'recurly__recurly-js'
 
-interface Plan {
+export interface Plan {
   code: string
   name: string
   period: {

+ 14 - 11
services/web/types/subscription/payment-context-value.tsx

@@ -4,6 +4,18 @@ import { SubscriptionPricingStateTax } from 'recurly__recurly-js'
 import { SubscriptionPricingInstanceCustom } from '../recurly/pricing/subscription'
 import { currencies, CurrencyCode } from './currency'
 
+export type RecurlyPrice =
+  | {
+      subtotal: string
+      plan: string
+      addons: string
+      setup_fee: string
+      discount: string
+      tax: string
+      total: string
+    }
+  | undefined
+
 export type PricingFormState = {
   first_name: string
   last_name: string
@@ -35,17 +47,7 @@ export type PaymentContextValue = {
   pricing: React.MutableRefObject<SubscriptionPricingInstanceCustom | undefined>
   recurlyLoading: boolean
   recurlyLoadError: boolean
-  recurlyPrice:
-    | {
-        subtotal: string
-        plan: string
-        addons: string
-        setup_fee: string
-        discount: string
-        tax: string
-        total: string
-      }
-    | undefined
+  recurlyPrice: RecurlyPrice
   monthlyBilling: boolean | undefined
   taxes: SubscriptionPricingStateTax[]
   coupon:
@@ -71,4 +73,5 @@ export type PaymentContextValue = {
     React.SetStateAction<PaymentContextValue['studentConfirmationChecked']>
   >
   updatePlan: (newPlanCode: string) => void
+  showNudgeToAnnualText: boolean
 }