From d0352a949217ab1ebc9f8dbaee8f33ded3919b90 Mon Sep 17 00:00:00 2001 From: M Fahru Date: Thu, 19 May 2022 05:13:25 -0400 Subject: [PATCH] Add new analytics events in the new plans page and update analytics event in the current plans page (#7639) GitOrigin-RevId: 71a4e7b0b041bbe7ea6df11cad28857978c77e4e --- .../Subscription/SubscriptionController.js | 1 + .../plans-marketing/_group_plan_modal.pug | 14 +++- .../v2/_cards_controls_tables.pug | 29 +++++++- .../plans-marketing/v2/_mixins.pug | 72 +++++++++++++++---- .../js/features/event-tracking/index.js | 7 ++ .../subscription/plans-v2/plans-v2-main.js | 9 ++- .../js/pages/user/subscription/plans.js | 12 +++- .../frontend/stylesheets/app/plans-v2.less | 1 + services/web/locales/en.json | 3 +- 9 files changed, 125 insertions(+), 23 deletions(-) diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.js b/services/web/app/src/Features/Subscription/SubscriptionController.js index e934908e21..c07099259b 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.js +++ b/services/web/app/src/Features/Subscription/SubscriptionController.js @@ -95,6 +95,7 @@ async function plansPage(req, res) { groupPlans: GroupPlansData, groupPlanModalOptions, groupPlanModalDefaults, + newPlansPageVariantV2, useNewPlanName, initialLocalizedGroupPrice: SubscriptionHelper.generateInitialLocalizedGroupPrice( diff --git a/services/web/app/views/subscriptions/plans-marketing/_group_plan_modal.pug b/services/web/app/views/subscriptions/plans-marketing/_group_plan_modal.pug index c8f5a379d6..b8f08fe756 100644 --- a/services/web/app/views/subscriptions/plans-marketing/_group_plan_modal.pug +++ b/services/web/app/views/subscriptions/plans-marketing/_group_plan_modal.pug @@ -58,7 +58,14 @@ div.modal.fade(tabindex="-1" role="dialog" data-ol-group-plan-modal) .form-group label(for='size') | Number of users - select.form-control(id="size") + select.form-control( + id="size" + event-tracking="groups-modal-group-size" + event-tracking-mb="true" + event-tracking-trigger="click" + event-tracking-element="select" + event-segmentation='{"plans-page-layout-v2": "' + (newPlansPageVariantV2 ? 'new-plans-page' : 'default') + '"}' + ) for size in groupPlanModalOptions.sizes option( value=size @@ -81,6 +88,11 @@ div.modal.fade(tabindex="-1" role="dialog" data-ol-group-plan-modal) id="usage" type="checkbox" autocomplete="off" + event-tracking="groups-modal-edu-discount" + event-tracking-mb="true" + event-tracking-trigger="click" + event-tracking-element="checkbox" + event-segmentation='{"plans-page-layout-v2": "' + (newPlansPageVariantV2 ? 'new-plans-page' : 'default') + '"}' ) span This license is for educational purposes (applies to students or faculty using Overleaf for teaching) diff --git a/services/web/app/views/subscriptions/plans-marketing/v2/_cards_controls_tables.pug b/services/web/app/views/subscriptions/plans-marketing/v2/_cards_controls_tables.pug index 298b67f1fa..a6220d0b0f 100644 --- a/services/web/app/views/subscriptions/plans-marketing/v2/_cards_controls_tables.pug +++ b/services/web/app/views/subscriptions/plans-marketing/v2/_cards_controls_tables.pug @@ -3,17 +3,35 @@ include ./_mixins .row.plans-v2-top-switch .col-xs-12 ul.nav.plans-v2-nav - li.active.plans-v2-top-switch-individual(data-ol-plans-v2-view-tab='individual') + li.active.plans-v2-top-switch-individual( + data-ol-plans-v2-view-tab='individual' + event-tracking="plans-page-toggle-plan" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "individual", "plans-page-layout-v2": "new-plans-page"}' + ) a.btn.btn-default-outline( href="#" ) #{translate("indvidual_plans")} - li.plans-v2-top-switch-group(data-ol-plans-v2-view-tab='group') + li.plans-v2-top-switch-group( + data-ol-plans-v2-view-tab='group' + event-tracking="plans-page-toggle-plan" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "group", "plans-page-layout-v2": "new-plans-page"}' + ) a.btn.btn-default-outline( href="#" ) span #{translate("group_plans")} span (save 30% or more) - li.plans-v2-top-switch-student(data-ol-plans-v2-view-tab='student') + li.plans-v2-top-switch-student( + data-ol-plans-v2-view-tab='student' + event-tracking="plans-page-toggle-plan" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "student", "plans-page-layout-v2": "new-plans-page"}' + ) a.btn.btn-default-outline( href="#" ) #{translate("student_plans")} @@ -26,6 +44,11 @@ include ./_mixins type="checkbox" role="switch" autocomplete="off" + event-tracking="plans-page-toggle-period" + event-tracking-mb="true" + event-tracking-trigger="click" + event-tracking-element="checkbox" + event-segmentation='{"plans-page-layout-v2": "new-plans-page"}' ) span .plans-v2-m-a-switch-annual-text-container diff --git a/services/web/app/views/subscriptions/plans-marketing/v2/_mixins.pug b/services/web/app/views/subscriptions/plans-marketing/v2/_mixins.pug index 7eb0607ada..cb5d30c4c5 100644 --- a/services/web/app/views/subscriptions/plans-marketing/v2/_mixins.pug +++ b/services/web/app/views/subscriptions/plans-marketing/v2/_mixins.pug @@ -41,7 +41,7 @@ mixin table_individual(period) p.plans-v2-table-th-content-title #{translate("professional")} +table_head_price('professional', period) .plans-v2-table-btn-buy-container-mobile - +btn_buy_individual_professional() + +btn_buy_individual_professional(period) ul.plans-v2-table-th-content-benefit li !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})} li #{translate("all_premium_features")} @@ -119,7 +119,7 @@ mixin table_group | per user / year .plans-v2-table-btn-buy-container-mobile +btn_buy_group_collaborator() - small.plans-v2-table-th-content-additional-link !{translate("or_contact_us", {}, [{name: 'a', attrs: {href: '/for/enterprises/sales-contact', target: '_blank'}}])} + +additional_link_group('group_collaborator') ul.plans-v2-table-th-content-benefit li #{translate("up_to")} !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})} li @@ -127,7 +127,7 @@ mixin table_group span  #{translate("total_per_year_lowercase")} .plans-v2-table-btn-buy-container-desktop +btn_buy_group_collaborator() - small.plans-v2-table-th-content-additional-link !{translate("or_contact_us", {}, [{name: 'a', attrs: {href: '/for/enterprises/sales-contact', target: '_blank'}}])} + +additional_link_group('group_collaborator') th.plans-v2-table-green-highlighted div.plans-v2-table-th-content @@ -142,7 +142,7 @@ mixin table_group | per user / year .plans-v2-table-btn-buy-container-mobile +btn_buy_group_professional() - small.plans-v2-table-th-content-additional-link !{translate("or_contact_us", {}, [{name: 'a', attrs: {href: '/for/enterprises/sales-contact', target: '_blank'}}])} + +additional_link_group('group_professional') ul.plans-v2-table-th-content-benefit li #{translate("unlimited_collaborators_in_each_project")} li @@ -150,7 +150,7 @@ mixin table_group span  #{translate("total_per_year_lowercase")} .plans-v2-table-btn-buy-container-desktop +btn_buy_group_professional() - small.plans-v2-table-th-content-additional-link !{translate("or_contact_us", {}, [{name: 'a', attrs: {href: '/for/enterprises/sales-contact', target: '_blank'}}])} + +additional_link_group('group_professional') th div.plans-v2-table-th-content @@ -164,7 +164,14 @@ mixin table_group li #{translate("best_choices_companies_universities_non_profits")} li #{translate("for_groups_or_site_wide")} li - a(href="/for/enterprises/sales-contact") #{translate("also_available_as_on_premises")} + a( + target="_blank" + href="/for/enterprises/sales-contact" + event-tracking="plans-page-click" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "group_organization-link", "location": "table-header-list", "period": "annual", "plans-page-layout-v2": "new-plans-page"}' + ) #{translate("also_available_as_on_premises")} .plans-v2-table-btn-buy-container-desktop +btn_buy_group_organization() small.plans-v2-table-th-content-additional-link.invisible(aria-hidden="true") @@ -262,10 +269,10 @@ mixin table_student(period) div.plans-v2-table-comments-icon i.fa.fa-comments-o .plans-v2-table-btn-buy-container-mobile - +btn_buy_student_university + +btn_buy_student_university(period) p.plans-v2-table-th-content-benefit !{translate("all_our_group_plans_offer_educational_discount", {}, [{name: 'b'}, {name: 'b'}])} .plans-v2-table-btn-buy-container-desktop - +btn_buy_student_university + +btn_buy_student_university(period) th for planFeaturesPerSection in planFeatures.student @@ -356,6 +363,11 @@ mixin group_plans_license_picker() id="plans-v2-license-picker-select" autocomplete="off" data-ol-plans-v2-license-picker-select + event-tracking="plans-page-group-size" + event-tracking-mb="true" + event-tracking-trigger="click" + event-tracking-element="select" + event-segmentation='{"plans-page-layout-v2": "new-plans-page"}' ) option(value="2") 2 option(value="3") 3 @@ -371,6 +383,11 @@ mixin group_plans_license_picker() id="license-picker-educational-discount" autocomplete="off" data-ol-plans-v2-license-picker-educational-discount-input + event-tracking="plans-page-edu-discount" + event-tracking-mb="true" + event-tracking-trigger="click" + event-tracking-element="checkbox" + event-segmentation='{"plans-page-layout-v2": "new-plans-page"}' ) span #{translate("apply_educational_discount")} //- will only appear on screen width >= 768px (using CSS) @@ -419,17 +436,17 @@ mixin btn_buy_individual_free() mixin btn_buy_individual_personal(period) +btn_buy_individual('paid-personal', period, false) if (period === 'monthly') - small.plans-v2-table-th-content-additional-link !{translate("or_buy_now", {}, [{name: 'a', attrs: {href: '/user/subscription/new?planCode=paid-personal¤cy=' + recommendedCurrency + '&itm_campaign=plans&itm_content=card'}}])} + +additional_link_buy('paid-personal', period) mixin btn_buy_individual_collaborator(period) +btn_buy_individual('collaborator', period, true) if (period === 'monthly') - small.plans-v2-table-th-content-additional-link !{translate("or_buy_now", {}, [{name: 'a', attrs: {href: '/user/subscription/new?planCode=collaborator¤cy=' + recommendedCurrency + '&itm_campaign=plans&itm_content=card'}}])} + +additional_link_buy('collaborator', period) mixin btn_buy_individual_professional(period) +btn_buy_individual('professional', period, false) if (period === 'monthly') - small.plans-v2-table-th-content-additional-link !{translate("or_buy_now", {}, [{name: 'a', attrs: {href: '/user/subscription/new?planCode=professional¤cy=' + recommendedCurrency + '&itm_campaign=plans&itm_content=card'}}])} + +additional_link_buy('professional', period) mixin btn_buy_group_collaborator() a.btn.btn-default.plans-v2-table-btn-buy( @@ -475,15 +492,44 @@ mixin btn_buy_student_student(period) else span #{translate("buy_now")} if (period === 'monthly') - small.plans-v2-table-th-content-additional-link !{translate("or_buy_now", {}, [{name: 'a', attrs: {href: '/user/subscription/new?planCode=student¤cy=' + recommendedCurrency + '&itm_campaign=plans&itm_content=card'}}])} + +additional_link_buy('student', period) -mixin btn_buy_student_university() +mixin btn_buy_student_university(period) a.btn.btn-default.plans-v2-table-btn-buy( href="/for/enterprises/sales-contact" target="_blank" + event-tracking="plans-page-click" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "student-university", "location": "table-header-list", "period": "' + period + '", "plans-page-layout-v2": "new-plans-page"}' ) span #{translate("contact_us_lowercase")} +mixin additional_link_group(plan) + - var buttonSegmentation = plan + '-link' + small.plans-v2-table-th-content-additional-link + | #{translate("or")} + a( + href="/for/enterprises/sales-contact" + target="_blank" + event-tracking="plans-page-click" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "' + buttonSegmentation + '", "location": "table-header", "plans-page-layout-v2": "new-plans-page"}' + ) #{translate("contact_us_lowercase")} + +mixin additional_link_buy(plan, period) + - var buttonSegmentation = plan + '-link' + small.plans-v2-table-th-content-additional-link + | #{translate("or")} + a( + href="/user/subscription/new?planCode=paid-personal¤cy=" + recommendedCurrency + "&itm_campaign=plans&itm_content=card" + event-tracking="plans-page-click" + event-tracking-mb="true" + event-tracking-trigger="click" + event-segmentation='{"button": "' + buttonSegmentation + '", "location": "table-header", "period": "' + period + '", "plans-page-layout-v2": "new-plans-page"}' + ) #{translate("buy_now_no_exclamation_mark")} + mixin table_sticky_header .row.plans-v2-table-sticky-header.plans-v2-table-sticky-header-individual.sticky(data-ol-plans-v2-table-sticky-header='individual') .plans-v2-table-sticky-header-item diff --git a/services/web/frontend/js/features/event-tracking/index.js b/services/web/frontend/js/features/event-tracking/index.js index 48aaa33f2d..8df0db66b0 100644 --- a/services/web/frontend/js/features/event-tracking/index.js +++ b/services/web/frontend/js/features/event-tracking/index.js @@ -19,10 +19,17 @@ function setupEventTracking(el) { const sendMB = el.getAttribute('event-tracking-mb') const trigger = el.getAttribute('event-tracking-trigger') const sendOnce = el.getAttribute('event-tracking-send-once') + const element = el.getAttribute('event-tracking-element') const segmentation = JSON.parse(el.getAttribute('event-segmentation') || '{}') segmentation.page = window.location.pathname function submit() { + if (element === 'checkbox') { + segmentation.checkbox = el.checked ? 'checked' : 'unchecked' + } else if (element === 'select') { + segmentation.selectValue = el.value + } + if (sendMB) { if (sendOnce) { eventTracking.sendMBOnce(key, segmentation) diff --git a/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-main.js b/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-main.js index 9f1ca14b67..95dee47676 100644 --- a/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-main.js +++ b/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-main.js @@ -1,5 +1,6 @@ import '../../../../marketing' +import * as eventTracking from '../../../../infrastructure/event-tracking' import { setUpStickyHeaderObserver, switchStickyHeader, @@ -65,9 +66,11 @@ function setUpTabSwitching() { el.querySelector('a').addEventListener('click', function (e) { e.preventDefault() - // TODO: analytics - // eventTracking.send('subscription-funnel', 'plans-page', `${view}-prices`) - // eventTracking.sendMB('plans-page-toggle', { button: view }) + eventTracking.send( + 'subscription-funnel', + 'plans-page', + `${viewTab}-prices` + ) selectTab(viewTab) }) }) diff --git a/services/web/frontend/js/pages/user/subscription/plans.js b/services/web/frontend/js/pages/user/subscription/plans.js index e0e6d671d5..0fb3d963fc 100644 --- a/services/web/frontend/js/pages/user/subscription/plans.js +++ b/services/web/frontend/js/pages/user/subscription/plans.js @@ -3,6 +3,8 @@ import '../../../features/plans/group-plan-modal' import * as eventTracking from '../../../infrastructure/event-tracking' import getMeta from '../../../utils/meta' +const PLANS_PAGE_LAYOUT_V2 = 'plans-page-layout-v2' + let currentView = 'monthly' let currentCurrencyCode = getMeta('ol-recommendedCurrency') @@ -23,11 +25,16 @@ function selectView(view) { } function setUpViewSwitching(liEl) { + const plansPageV2SplitTestVariant = + getMeta('ol-splitTestVariants')?.[PLANS_PAGE_LAYOUT_V2] ?? 'default' const view = liEl.getAttribute('data-ol-view-tab') liEl.querySelector('a').addEventListener('click', function (e) { e.preventDefault() eventTracking.send('subscription-funnel', 'plans-page', `${view}-prices`) - eventTracking.sendMB('plans-page-toggle', { button: view }) + eventTracking.sendMB('plans-page-toggle', { + button: view, + PLANS_PAGE_LAYOUT_V2: plansPageV2SplitTestVariant, + }) selectView(view) }) } @@ -46,6 +53,8 @@ function setUpCurrencySwitching(linkEl) { } function setUpSubscriptionTracking(linkEl) { + const plansPageV2SplitTestVariant = + getMeta('ol-splitTestVariants')?.[PLANS_PAGE_LAYOUT_V2] ?? 'default' const plan = linkEl.getAttribute('data-ol-tracking-plan') || linkEl.getAttribute('data-ol-start-new-subscription') @@ -63,6 +72,7 @@ function setUpSubscriptionTracking(linkEl) { button: plan, location, period, + PLANS_PAGE_LAYOUT_V2: plansPageV2SplitTestVariant, }) }) } diff --git a/services/web/frontend/stylesheets/app/plans-v2.less b/services/web/frontend/stylesheets/app/plans-v2.less index daa2bd6ca6..5485d754b4 100644 --- a/services/web/frontend/stylesheets/app/plans-v2.less +++ b/services/web/frontend/stylesheets/app/plans-v2.less @@ -875,6 +875,7 @@ strike.plans-v2-table-annual-price-before-discount { } small.plans-v2-table-th-content-additional-link { + text-transform: lowercase; margin-top: @margin-xs; font-size: @font-size-extra-small; height: 16px; diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 9abc6a5506..23882d6f6b 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -1310,6 +1310,7 @@ "restricted": "Restricted", "start_x_day_trial": "Start Your __len__-Day Free Trial Today!", "buy_now": "Buy Now!", + "buy_now_no_exclamation_mark": "Buy now", "cs": "Czech", "view_all": "View All", "terms": "Terms", @@ -1734,8 +1735,6 @@ "saving_20_percent": "Saving 20%!", "feature_included": "Feature included", "feature_not_included": "Feature not included", - "or_contact_us": "or <0>contact us", - "or_buy_now": "or <0>buy now", "all_our_group_plans_offer_educational_discount": "All of our <0>group plans offer an <1>educational discount for students and faculty", "unlink_dropbox_folder": "Unlink Dropbox Account", "unlink_dropbox_warning": "Any projects that you have synced with Dropbox will be disconnected and no longer kept in sync with Dropbox. Are you sure you want to unlink your Dropbox account?",