From f3118771fe598614937a241e605dac7c3523726d Mon Sep 17 00:00:00 2001 From: M Fahru Date: Tue, 5 Jul 2022 11:05:32 -0400 Subject: [PATCH] Add new limited discount information on personal plan in the new plans page (#8715) GitOrigin-RevId: 7f4e91179ba767ff8b88df7787eaf9d4fe6a5f05 --- .../Features/Subscription/plansV2Config.js | 7 ++ .../plans-marketing/v2/_mixins.pug | 69 +++++++++++++----- .../plans-v2/plans-v2-m-a-switch.js | 9 --- .../frontend/stylesheets/app/plans-v2.less | 71 ++++++++++++++++++- 4 files changed, 127 insertions(+), 29 deletions(-) diff --git a/services/web/app/src/Features/Subscription/plansV2Config.js b/services/web/app/src/Features/Subscription/plansV2Config.js index a1cd57f09a..cd0058a7b7 100644 --- a/services/web/app/src/Features/Subscription/plansV2Config.js +++ b/services/web/app/src/Features/Subscription/plansV2Config.js @@ -16,6 +16,13 @@ const config = { annual: 'MOST POPULAR', }, }, + discountedColumn: { + index: 1, + text: { + monthly: 'LIMITED-TIME DISCOUNT!', + annual: 'LIMITED-TIME DISCOUNT!', + }, + }, eventTrackingKey: 'plans-page-click', additionalEventSegmentation: { 'plan-page-layout-v2': 'new-plans-page' }, }, 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 390d1e29ac..c876656c89 100644 --- a/services/web/app/views/subscriptions/plans-marketing/v2/_mixins.pug +++ b/services/web/app/views/subscriptions/plans-marketing/v2/_mixins.pug @@ -1,6 +1,7 @@ mixin plans_v2_table(period, config) - var baseColspan = config.baseColspan || 1 - var maxColumn = config.maxColumn || 4 + - var discountedColumn = config.discountedColumn || {} tr th(colspan=baseColspan) - for (var i = 0; i < maxColumn; i++) @@ -8,19 +9,32 @@ mixin plans_v2_table(period, config) - var tableHeadOptions = Object.values(config.tableHead)[i] || {} - var colspan = tableHeadOptions.colspan || baseColspan - var highlighted = i === config.highlightedColumn.index + - var discountHighlighted = i === discountedColumn.index - var eventTrackingKey = config.eventTrackingKey - var additionalEventSegmentation = config.additionalEventSegmentation || {} + - + if (discountHighlighted) { + var thClass = 'plans-v2-table-discount-highlighted' + } else if (highlighted) { + var thClass = 'plans-v2-table-green-highlighted' + } else if (i === config.highlightedColumn.index - 1) { + var thClass = 'plans-v2-table-cell-before-green-highlighted-column' + } else { + var thClass = '' + } th( - class=(i === config.highlightedColumn.index ? 'plans-v2-table-green-highlighted' : (i === config.highlightedColumn.index - 1 ? 'plans-v2-table-cell-before-highlighted-column' : '')) + class=thClass colspan=colspan ) + if (discountHighlighted) + p.plans-v2-table-discount-highlighted-text !{config.discountedColumn.text[period]} if (highlighted) p.plans-v2-table-green-highlighted-text !{config.highlightedColumn.text[period]} case tableHeadKey when 'individual_free' +table_head_individual_free(highlighted, period) when 'individual_personal' - +table_head_individual_personal(highlighted, eventTrackingKey, additionalEventSegmentation, period) + +table_head_individual_personal(highlighted, discountHighlighted, eventTrackingKey, additionalEventSegmentation, period) when 'individual_collaborator' +table_head_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) when 'individual_professional' @@ -97,8 +111,18 @@ mixin plans_v2_table(period, config) for plan, planIndex in Object.keys(feature.plans) - var tableHeadOptions = Object.values(config.tableHead)[planIndex] || {} - var colspan = tableHeadOptions.colspan || baseColspan + - + if (planIndex === discountedColumn.index) { + var tdClass = 'plans-v2-table-discount-highlighted' + } else if (planIndex === config.highlightedColumn.index) { + var tdClass = 'plans-v2-table-green-highlighted' + } else if (planIndex === config.highlightedColumn.index - 1) { + var tdClass = 'plans-v2-table-cell-before-green-highlighted-column' + } else { + var tdClass = '' + } td( - class=(planIndex === config.highlightedColumn.index ? 'plans-v2-table-green-highlighted' : (planIndex === config.highlightedColumn.index - 1 ? 'plans-v2-table-cell-before-highlighted-column' : '')) + class=tdClass colspan=colspan ) +table_cell(feature, plan) @@ -126,17 +150,17 @@ mixin table_head_individual_free(highlighted, period) .plans-v2-table-btn-buy-container-desktop +btn_buy_individual_free(highlighted) -mixin table_head_individual_personal(highlighted, eventTrackingKey, additionalEventSegmentation, period) +mixin table_head_individual_personal(highlighted, discountHighlighted, eventTrackingKey, additionalEventSegmentation, period) .plans-v2-table-th-content p.plans-v2-table-th-content-title #{translate("personal")} +table_head_price('personal', period) .plans-v2-table-btn-buy-container-mobile - +btn_buy_individual_personal(highlighted, eventTrackingKey, additionalEventSegmentation, period) + +btn_buy_individual_personal(highlighted, discountHighlighted, eventTrackingKey, additionalEventSegmentation, period) ul.plans-v2-table-th-content-benefit li #{translate("one_collaborator")} li #{translate("most_premium_features")} .plans-v2-table-btn-buy-container-desktop - +btn_buy_individual_personal(highlighted, eventTrackingKey, additionalEventSegmentation, period) + +btn_buy_individual_personal(highlighted, discountHighlighted, eventTrackingKey, additionalEventSegmentation, period) mixin table_head_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) .plans-v2-table-th-content @@ -166,7 +190,7 @@ mixin table_head_group_collaborator(highlighted, eventTrackingKey, additionalEve .plans-v2-table-th-content p.plans-v2-table-th-content-title #{translate("group_standard")} .plans-v2-table-price-container - strike.plans-v2-table-annual-price-before-discount(data-ol-plans-v2-table-annual-price-before-discount) + strike.plans-v2-table-price-before-discount +gen_localized_price_for_plan_view('collaborator', 'annual') p.plans-v2-table-price span(data-ol-plans-v2-group-price-per-user='collaborator') #{initialLocalizedGroupPrice.pricePerUser.collaborator} @@ -188,7 +212,7 @@ mixin table_head_group_professional(highlighted, eventTrackingKey, additionalEve .plans-v2-table-th-content p.plans-v2-table-th-content-title #{translate("group_professional")} .plans-v2-table-price-container - strike.plans-v2-table-annual-price-before-discount(data-ol-plans-v2-table-annual-price-before-discount) + strike.plans-v2-table-price-before-discount +gen_localized_price_for_plan_view('professional', 'annual') p.plans-v2-table-price span(data-ol-plans-v2-group-price-per-user='professional') #{initialLocalizedGroupPrice.pricePerUser.professional} @@ -271,9 +295,12 @@ mixin table_head_student_university(highlighted, eventTrackingKey, additionalEve mixin table_head_price(plan, period) div.plans-v2-table-price-container - if plan !== 'free' - strike.plans-v2-table-annual-price-before-discount.hidden(data-ol-plans-v2-table-annual-price-before-discount) + if plan !== 'free' && period === 'annual' + strike.plans-v2-table-price-before-discount +gen_localized_price_for_plan_view(plan, 'monthlyTimesTwelve') + if plan === 'personal' && period === 'monthly' + strike.plans-v2-table-price-before-discount + +gen_localized_undiscounted_price_for_plan_view_personal(period) p.plans-v2-table-price +gen_localized_price_for_plan_view(plan, period) p.plans-v2-table-price-period-label @@ -345,12 +372,12 @@ mixin group_plans_license_picker() ) #{translate("learn_more_lowercase")} span ) -mixin btn_buy_individual(highlighted, eventTrackingKey, subscriptionPlan, period) +mixin btn_buy_individual(highlighted, discountHighlighted, eventTrackingKey, subscriptionPlan, period) a.btn.plans-v2-table-btn-buy( data-ol-start-new-subscription=subscriptionPlan data-ol-event-tracking-key=eventTrackingKey data-ol-item-view=period - class=(highlighted ? 'btn-primary' : 'btn-default') + class=(discountHighlighted ? 'btn-dark-blue' : (highlighted ? 'btn-primary' : 'btn-default')) ) if (period === 'monthly') span #{translate("try_for_free")} @@ -370,18 +397,18 @@ mixin btn_buy_individual_free() class=(highlighted ? 'btn-primary' : 'btn-default') ) -mixin btn_buy_individual_personal(highlighted, eventTrackingKey, additionalEventSegmentation, period) - +btn_buy_individual(highlighted, eventTrackingKey, 'paid-personal', period) +mixin btn_buy_individual_personal(highlighted, discountHighlighted, eventTrackingKey, additionalEventSegmentation, period) + +btn_buy_individual(highlighted, discountHighlighted, eventTrackingKey, 'paid-personal', period) if (period === 'monthly') +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'paid-personal', period) mixin btn_buy_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period) - +btn_buy_individual(highlighted, eventTrackingKey, 'collaborator', period) + +btn_buy_individual(highlighted, false, eventTrackingKey, 'collaborator', period) if (period === 'monthly') +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'collaborator', period) mixin btn_buy_individual_professional(highlighted, eventTrackingKey, additionalEventSegmentation, period) - +btn_buy_individual(highlighted, eventTrackingKey, 'professional', period) + +btn_buy_individual(highlighted, false, eventTrackingKey, 'professional', period) if (period === 'monthly') +additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'professional', period) @@ -492,8 +519,16 @@ mixin plans_v2_table_sticky_header(withSwitch, config) - for (var i = 0; i < tableHeadKeys.length; i++) - var tableHeadKey = tableHeadKeys[i] - var translateKey = tableHeadKey.split('_')[1] + - + if (config.discountedColumn?.index === i) { + var elClass = 'plans-v2-table-sticky-header-item-discount-highlighted' + } else if (config.highlightedColumn.index === i) { + var elClass = 'plans-v2-table-sticky-header-item-green-highlighted' + } else { + var elClass = '' + } .plans-v2-table-sticky-header-item( - class=(config.highlightedColumn.index === i ? 'plans-v2-table-sticky-header-item-highlighted' : '') + class=elClass ) case tableHeadKey when 'individual_collaborator' diff --git a/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-m-a-switch.js b/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-m-a-switch.js index 351a1e1cf4..5f9a7c6266 100644 --- a/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-m-a-switch.js +++ b/services/web/frontend/js/pages/user/subscription/plans-v2/plans-v2-m-a-switch.js @@ -29,15 +29,6 @@ export function switchMonthlyAnnual(currentMonthlyAnnualSwitchValue) { el.hidden = period !== currentMonthlyAnnualSwitchValue }) - document - .querySelectorAll('[data-ol-plans-v2-table-annual-price-before-discount]') - .forEach(el => { - el.classList.toggle( - 'hidden', - currentMonthlyAnnualSwitchValue === 'monthly' - ) - }) - document.querySelectorAll('[data-ol-plans-v2-period').forEach(el => { const period = el.getAttribute('data-ol-plans-v2-period') diff --git a/services/web/frontend/stylesheets/app/plans-v2.less b/services/web/frontend/stylesheets/app/plans-v2.less index c505a56fb2..b8d80a388a 100644 --- a/services/web/frontend/stylesheets/app/plans-v2.less +++ b/services/web/frontend/stylesheets/app/plans-v2.less @@ -9,8 +9,11 @@ @plans-v2-top-switch-group-width-mobile: 46%; @plans-v2-m-a-tooltip-arrow-z-index: 10; @plans-v2-m-a-tooltip-z-index: 20; +@plans-v2-green-highlighted-text-z-index: 1; +@plans-v2-discount-highlighted-text-z-index: 2; @plans-v2-table-sticky-header-z-index: 100; @plans-v2-table-border-radius: 20px; +@plans-v2-dark-blue: #2857a1; .plans { @media (max-width: @screen-xs-max) { @@ -18,6 +21,11 @@ display: none; } } + + .btn-dark-blue { + background-color: @plans-v2-dark-blue; + color: @white; + } } .plans-v2-top-switch ul.plans-v2-nav { @@ -601,7 +609,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { background-clip: padding-box; /* needed for firefox when there is bg color */ text-align: center; - &:not(.plans-v2-table-cell-before-highlighted-column):not(.plans-v2-table-green-highlighted):not(.plans-v2-table-divider-highlighted) { + &:not(.plans-v2-table-cell-before-green-highlighted-column):not(.plans-v2-table-green-highlighted):not(.plans-v2-table-divider-highlighted):not(.plans-v2-table-discount-highlighted) { border-right: 1px solid @ol-blue-gray-0; @media (max-width: @screen-xs-max) { @@ -671,6 +679,14 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { border-bottom: unset; } } + + &:last-child td.plans-v2-table-discount-highlighted { + border-bottom: 2px solid @plans-v2-dark-blue; + + @media (max-width: @screen-xs-max) { + border-bottom: unset; + } + } } .fa-check { @@ -873,7 +889,7 @@ p.plans-v2-table-price { } } -strike.plans-v2-table-annual-price-before-discount { +strike.plans-v2-table-price-before-discount { position: absolute; top: -27px; font-weight: 700; @@ -1040,6 +1056,51 @@ p.plans-v2-table-green-highlighted-text { color: @white; height: @plans-v2-highlighted-text-height-desktop; margin: 0; + z-index: @plans-v2-green-highlighted-text-z-index; + + @media (max-width: @screen-sm-max) { + top: -1 * @plans-v2-highlighted-text-height-mobile; + height: @plans-v2-highlighted-text-height-mobile; + } + + @media (max-width: @screen-xs-max) { + padding-left: 5px; + padding-right: 5px; + font-size: @font-size-extra-small; + line-height: 15px; + } +} + +.plans-v2-table-discount-highlighted { + border-left: 2px solid @plans-v2-dark-blue; + border-right: 2px solid @plans-v2-dark-blue; + + @media (max-width: @screen-xs-max) { + border-left: unset; + border-right: unset; + } +} + +p.plans-v2-table-discount-highlighted-text { + border: 2px solid @plans-v2-dark-blue; + position: absolute; + top: -1 * @plans-v2-highlighted-text-height-desktop; + left: -2px; + display: flex; + justify-content: center; + align-items: center; + // 4px because border width is 2px each side (left and right) + width: calc(100% + 4px); + font-family: @font-family-sans-serif; + font-size: @font-size-small; + line-height: 19px; + font-weight: 700; + background-color: @plans-v2-dark-blue; + border-radius: @plans-v2-table-border-radius @plans-v2-table-border-radius 0 0; + color: @white; + height: @plans-v2-highlighted-text-height-desktop; + margin: 0; + z-index: @plans-v2-discount-highlighted-text-z-index; @media (max-width: @screen-sm-max) { top: -1 * @plans-v2-highlighted-text-height-mobile; @@ -1116,10 +1177,14 @@ p.plans-v2-table-green-highlighted-text { } } -.plans-v2-table-sticky-header-item-highlighted span { +.plans-v2-table-sticky-header-item-green-highlighted span { color: @ol-green; } +.plans-v2-table-sticky-header-item-discount-highlighted span { + color: @plans-v2-dark-blue; +} + .plans-v2-faq { // need for specificity to override default a color p > a {