diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.js b/services/web/app/src/Features/Subscription/SubscriptionController.js index cdf8bb5655..263cb0ca5b 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.js +++ b/services/web/app/src/Features/Subscription/SubscriptionController.js @@ -55,6 +55,7 @@ async function plansPage(req, res) { } return defaultValue } + const newPlansPageAssignmentV2 = await SplitTestHandler.promises.getAssignment( req, @@ -168,6 +169,12 @@ async function paymentPage(req, res) { refreshedPaymentPageAssignment && refreshedPaymentPageAssignment.variant === 'refreshed-payment-page' + await SplitTestHandler.promises.getAssignment( + req, + res, + 'student-check-modal' + ) + const template = useRefreshedPaymentPage ? 'subscriptions/new-refreshed' : useUpdatedPaymentPage diff --git a/services/web/app/views/subscriptions/_new_mixins.pug b/services/web/app/views/subscriptions/_new_mixins.pug new file mode 100644 index 0000000000..9e373ce7ce --- /dev/null +++ b/services/web/app/views/subscriptions/_new_mixins.pug @@ -0,0 +1,25 @@ +mixin studentCheckModal + script(type="text/ng-template", id="StudentCheckModalTemplate") + .modal-header + h3 #{translate("you_are_about_to_upgrade", {planName: translate("student_plan")})} + .modal-body + p.mb-0 + | !{translate("the_overleaf_student_plan_is_for_students_using_overleaf_during_their_studies", {}, ['strong'])}. + br + | #{translate("not_a_student_question")} + | #{translate("try_out_one_of_our_plans_instead")}. + .modal-footer + button.btn.btn-default( + event-tracking-mb="true" + event-tracking="student-check-button-click" + event-tracking-trigger="click" + event-segmentation='{"button": "plans"}' + ng-click="browsePlans()" + ) #{translate("browse_plans")} + button.btn.btn-success( + event-tracking-mb="true" + event-tracking="student-check-button-click" + event-tracking-trigger="click" + event-segmentation='{"button": "confirm"}' + ng-click="confirm()" + ) #{translate("i_confirm_that_i_am_a_student")} diff --git a/services/web/app/views/subscriptions/new-refreshed.pug b/services/web/app/views/subscriptions/new-refreshed.pug index 8a55e42ffe..22a60552f2 100644 --- a/services/web/app/views/subscriptions/new-refreshed.pug +++ b/services/web/app/views/subscriptions/new-refreshed.pug @@ -1,5 +1,7 @@ extends ../layout +include ./_new_mixins + block vars - var suppressNavbarRight = true - var suppressFooter = true @@ -358,3 +360,5 @@ block content ) p !{translate("for_visa_mastercard_and_discover", {}, ['strong', 'strong', 'strong'])} p !{translate("for_american_express", {}, ['strong', 'strong', 'strong'])} + + +studentCheckModal diff --git a/services/web/app/views/subscriptions/new-updated.pug b/services/web/app/views/subscriptions/new-updated.pug index 5fa22261a2..7d24d4024b 100644 --- a/services/web/app/views/subscriptions/new-updated.pug +++ b/services/web/app/views/subscriptions/new-updated.pug @@ -1,5 +1,7 @@ extends ../layout +include ./_new_mixins + block append meta meta(name="ol-countryCode" content=countryCode) meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey) @@ -355,3 +357,5 @@ block content ) p !{translate("for_visa_mastercard_and_discover", {}, ['strong', 'strong', 'strong'])} p !{translate("for_american_express", {}, ['strong', 'strong', 'strong'])} + + +studentCheckModal diff --git a/services/web/app/views/subscriptions/new.pug b/services/web/app/views/subscriptions/new.pug index 57da95e518..216f912b7b 100644 --- a/services/web/app/views/subscriptions/new.pug +++ b/services/web/app/views/subscriptions/new.pug @@ -1,5 +1,7 @@ extends ../layout +include ./_new_mixins + block append meta meta(name="ol-countryCode" content=countryCode) meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey) @@ -351,3 +353,5 @@ block content ) p !{translate("for_visa_mastercard_and_discover", {}, ['strong', 'strong', 'strong'])} p !{translate("for_american_express", {}, ['strong', 'strong', 'strong'])} + + +studentCheckModal diff --git a/services/web/frontend/js/main/new-subscription.js b/services/web/frontend/js/main/new-subscription.js index f3776da6fb..409444c21e 100644 --- a/services/web/frontend/js/main/new-subscription.js +++ b/services/web/frontend/js/main/new-subscription.js @@ -10,7 +10,14 @@ import getMeta from '../utils/meta' export default App.controller( 'NewSubscriptionController', - function ($scope, MultiCurrencyPricing, $http, $location, eventTracking) { + function ( + $scope, + $modal, + MultiCurrencyPricing, + $http, + $location, + eventTracking + ) { window.couponCode = $location.search().cc || '' window.plan_code = $location.search().planCode || '' window.ITMCampaign = $location.search().itm_campaign || '' @@ -35,6 +42,18 @@ export default App.controller( $scope.availableCurrencies = {} $scope.planCode = window.plan_code + const isStudentCheckModalEnabled = + getMeta('ol-splitTestVariants')?.['student-check-modal'] === 'enabled' + + if (isStudentCheckModalEnabled && $scope.planCode.includes('student')) { + $modal.open({ + templateUrl: 'StudentCheckModalTemplate', + controller: 'StudentCheckModalController', + backdrop: 'static', + size: 'dialog-centered', + }) + } + $scope.switchToStudent = function () { const currentPlanCode = window.plan_code const planCode = currentPlanCode.replace('collaborator', 'student') @@ -145,6 +164,7 @@ export default App.controller( }) .done() } + setupPricing() pricing.on('change', () => { @@ -757,3 +777,28 @@ export default App.controller( ] } ) + +App.controller( + 'StudentCheckModalController', + function ($scope, $modalInstance, eventTracking) { + $modalInstance.rendered.then(() => { + eventTracking.sendMB('student-check-displayed') + }) + + $scope.browsePlans = () => { + if (document.referrer?.includes('/user/subscription/choose-your-plan')) { + // redirect to interstitial page with `itm_referrer` param + window.location.assign( + '/user/subscription/choose-your-plan?itm_referrer=student-status-declined' + ) + } else { + // redirect to plans page with `itm_referrer` param + window.location.assign( + '/user/subscription/plans?itm_referrer=student-status-declined' + ) + } + } + + $scope.confirm = () => $modalInstance.dismiss('cancel') + } +) diff --git a/services/web/frontend/stylesheets/components/modals.less b/services/web/frontend/stylesheets/components/modals.less index 16a1a89cb5..c01d453f1d 100755 --- a/services/web/frontend/stylesheets/components/modals.less +++ b/services/web/frontend/stylesheets/components/modals.less @@ -47,6 +47,21 @@ margin: 10px; } +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - (30px * 2)); + + .modal-content { + width: 100%; + } + + &.modal-dialog { + margin-top: 30px; + margin-bottom: 30px; + } +} + // Actual modal .modal-content { position: relative; diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 791dbc7950..5a59a9f80c 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -1914,5 +1914,12 @@ "show_x_more_projects": "Show __x__ more projects", "showing_x_out_of_n_projects": "Showing __x__ out of __n__ projects.", "make_a_copy": "Make a copy", - "projects_list": "Projects list" + "projects_list": "Projects list", + "you_are_about_to_upgrade": "You are about to upgrade to the __planName__", + "student_plan": "Student Plan", + "the_overleaf_student_plan_is_for_students_using_overleaf_during_their_studies": "The Overleaf Student plan is for <0>students using Overleaf during their studies", + "not_a_student_question": "Not a student?", + "try_out_one_of_our_plans_instead": "Try out one of our plans instead", + "browse_plans": "Browse plans", + "i_confirm_that_i_am_a_student": "I confirm that I am a student" }