Add annual saving tooltip & add a striked-through text on the annual price to current plans page

Co-authored-by: Thomas Mees <thomas.mees@overleaf.com>
GitOrigin-RevId: 25a9b7b12ddd00588a8e4c43b55f2d7c57048818
This commit is contained in:
M Fahru 2022-05-12 06:24:46 -04:00 committed by Copybot
parent 406f8b145a
commit cf0b46ecf2
4 changed files with 98 additions and 14 deletions

View file

@ -132,12 +132,20 @@ mixin gen_localized_price_for_plan_view(plan, view)
data-ol-currencyCode=currencyCode data-ol-currencyCode=currencyCode
) #{settings.localizedPlanPricing[currencyCode][plan][view]} ) #{settings.localizedPlanPricing[currencyCode][plan][view]}
mixin gen_localized_undiscounted_price_for_plan_view(plan, view) mixin gen_localized_undiscounted_price_for_plan_view_personal(view)
for currencyCode in Object.keys(settings.localizedPlanPricing) for currencyCode in Object.keys(settings.localizedPlanPricing)
span( span(
hidden=(currencyCode !== recommendedCurrency) hidden=(currencyCode !== recommendedCurrency)
data-ol-currencyCode=currencyCode data-ol-currencyCode=currencyCode
) #{settings.localizedPlanPricing[currencyCode][plan]['withoutDiscount'][view]} ) #{settings.localizedPlanPricing[currencyCode]['personal']['withoutDiscount'][view]}
mixin gen_localized_undiscounted_price_for_plan_view(plan)
for currencyCode in Object.keys(settings.localizedPlanPricing)
span(
hidden=(currencyCode !== recommendedCurrency)
data-ol-currencyCode=currencyCode
) #{settings.localizedPlanPricing[currencyCode][plan]['monthlyTimesTwelve']}
mixin gen_localized_price_for_plan(plan) mixin gen_localized_price_for_plan(plan)
div(data-ol-view='monthly') div(data-ol-view='monthly')
@ -147,27 +155,38 @@ mixin gen_localized_price_for_plan(plan)
+gen_localized_price_for_plan_view(plan, 'annual') +gen_localized_price_for_plan_view(plan, 'annual')
span.small /yr span.small /yr
mixin gen_localized_undiscounted_price_for_plan(plan) mixin gen_localized_undiscounted_price_for_plan_personal()
div(data-ol-view='monthly') div(data-ol-view='monthly')
.undiscounted-price.small strike.undiscounted-price.small
span.sr-only Price reduced from span.sr-only Price reduced from
+gen_localized_undiscounted_price_for_plan_view(plan, 'monthly') +gen_localized_undiscounted_price_for_plan_view_personal('monthly')
| /mo | /mo
div(hidden data-ol-view='annual') div(hidden data-ol-view='annual')
.undiscounted-price.small strike.undiscounted-price.small
span.sr-only Price reduced from span.sr-only Price reduced from
+gen_localized_undiscounted_price_for_plan_view(plan, 'annual') +gen_localized_undiscounted_price_for_plan_view_personal('annual')
| /yr
mixin gen_localized_undiscounted_price_for_plan(plan)
div(hidden data-ol-view='annual')
strike.undiscounted-price.small
span.sr-only Price reduced from
+gen_localized_undiscounted_price_for_plan_view(plan)
| /yr | /yr
//- Prices //- Prices
mixin price_personal mixin price_personal
+gen_localized_price_for_plan('personal') +gen_localized_price_for_plan('personal')
mixin price_personal_undiscounted mixin price_personal_undiscounted
+gen_localized_undiscounted_price_for_plan('personal') +gen_localized_undiscounted_price_for_plan_personal()
mixin price_collaborator mixin price_collaborator
+gen_localized_price_for_plan('collaborator') +gen_localized_price_for_plan('collaborator')
mixin price_collaborator_undiscounted
+gen_localized_undiscounted_price_for_plan('collaborator')
mixin price_professional mixin price_professional
+gen_localized_price_for_plan('professional') +gen_localized_price_for_plan('professional')
mixin price_professional_undiscounted
+gen_localized_undiscounted_price_for_plan('professional')
mixin price_student_annual mixin price_student_annual
+gen_localized_price_for_plan_view('student', 'annual') +gen_localized_price_for_plan_view('student', 'annual')
span.small /yr span.small /yr
@ -199,15 +218,25 @@ mixin currency_dropdown
) #{currencyCode} #{settings.localizedPlanPricing[currencyCode]['symbol']} ) #{currencyCode} #{settings.localizedPlanPricing[currencyCode]['symbol']}
mixin plan_switch(location) mixin plan_switch(location)
ul.nav.nav-pills ul.nav.nav-pills(class=(location === 'card' ? "above-cards" : ""))
li.active(data-ol-view-tab='monthly') li.active(data-ol-view-tab='monthly')
a.btn.btn-default-outline( a.btn.btn-default-outline(
href="#" href="#"
) #{translate("monthly")} ) #{translate("monthly")}
li(data-ol-view-tab='annual') li(data-ol-view-tab='annual' class=(location === 'card' ? "annual-saving-tooltip-container" : ""))
a.btn.btn-default-outline( a.btn.btn-default-outline(
href="#" href="#"
) #{translate("annual")} ) #{translate("annual")}
if (location === 'card')
.tooltip.in.bottom.annual-saving-tooltip(
role="tooltip"
data-ol-annual-saving-tooltip
)
.tooltip-arrow
.tooltip-inner
span(data-ol-view="monthly") #{translate("save_20_percent_by_paying_annually")}
span(hidden data-ol-view="annual") #{translate("saving_20_percent")}
span(hidden data-ol-view="student") #{translate("save_20_percent_by_paying_annually")}
li(data-ol-view-tab='student') li(data-ol-view-tab='student')
a.btn.btn-default-outline( a.btn.btn-default-outline(
href="#" href="#"
@ -217,7 +246,7 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
- var location = listLocation ? 'card_' + listLocation : 'card' - var location = listLocation ? 'card_' + listLocation : 'card'
.row.top-switch(class=(controlsRowSpaced ? "row-spaced" : "")) .row.top-switch(class=(controlsRowSpaced ? "row-spaced" : ""))
.col-md-6.col-md-offset-3 .col-md-6.col-md-offset-3
+plan_switch('card') +plan_switch(location)
.col-md-2.text-right .col-md-2.text-right
+currency_dropdown +currency_dropdown
@ -250,6 +279,7 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
h5.tagline #{translate("tagline_collaborator")} h5.tagline #{translate("tagline_collaborator")}
.circle .circle
+price_collaborator +price_collaborator
+price_collaborator_undiscounted
+features_collaborator(location) +features_collaborator(location)
.col-md-4 .col-md-4
.card.card-last .card.card-last
@ -259,6 +289,7 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
h5.tagline #{translate("tagline_professional")} h5.tagline #{translate("tagline_professional")}
.circle .circle
+price_professional +price_professional
+price_professional_undiscounted
+features_professional(location) +features_professional(location)
.card-group.text-centered(hidden data-ol-view='student') .card-group.text-centered(hidden data-ol-view='student')

View file

@ -1,6 +1,5 @@
import '../../../marketing' import '../../../marketing'
import '../../../features/plans/group-plan-modal' import '../../../features/plans/group-plan-modal'
import * as eventTracking from '../../../infrastructure/event-tracking' import * as eventTracking from '../../../infrastructure/event-tracking'
import getMeta from '../../../utils/meta' import getMeta from '../../../utils/meta'
@ -18,6 +17,7 @@ function selectView(view) {
document.querySelectorAll('[data-ol-view]').forEach(el => { document.querySelectorAll('[data-ol-view]').forEach(el => {
el.hidden = el.getAttribute('data-ol-view') !== view el.hidden = el.getAttribute('data-ol-view') !== view
}) })
updateAnnualSavingBanner(view)
currentView = view currentView = view
updateLinkTargets() updateLinkTargets()
} }
@ -81,6 +81,16 @@ function updateLinkTargets() {
}) })
} }
function updateAnnualSavingBanner(view) {
const tooltipEl = document.querySelector('[data-ol-annual-saving-tooltip]')
if (view === 'annual') {
tooltipEl.classList.add('annual-selected')
} else {
tooltipEl.classList.remove('annual-selected')
}
}
function selectViewFromHash() { function selectViewFromHash() {
try { try {
const params = new URLSearchParams(window.location.hash.substring(1)) const params = new URLSearchParams(window.location.hash.substring(1))

View file

@ -85,7 +85,7 @@
font-size: @font-size-base * 0.8; font-size: @font-size-base * 0.8;
} }
.undiscounted-price { .undiscounted-price {
text-decoration: line-through; display: block;
margin-top: -48px; margin-top: -48px;
} }
} }
@ -135,14 +135,42 @@
ul.nav-pills { ul.nav-pills {
text-align: center; text-align: center;
margin-bottom: @line-height-computed; margin-bottom: @line-height-computed;
display: flex;
justify-content: center;
li { li {
float: none; float: none;
display: inline-block; display: inline-block;
position: relative;
.annual-saving-tooltip {
white-space: nowrap;
left: 50%;
width: 200px;
margin-left: -100px;
&.bottom {
margin-top: 0px;
}
&.annual-selected {
width: 94px;
margin-left: -47px;
.tooltip-inner {
background-color: @ol-green;
}
.tooltip-arrow {
border-bottom-color: @ol-green;
}
}
.tooltip-inner {
max-width: none;
}
}
} }
> li + li { > li + li {
margin-left: @line-height-computed / 2; margin-left: @line-height-computed / 2;
} }
} }
ul.nav-pills.above-cards {
margin-bottom: @line-height-computed * 2;
}
} }
#changePlanSection { #changePlanSection {
@ -210,6 +238,19 @@
} }
} }
} }
@media (max-width: @screen-xs-max) {
.plans ul.nav-pills {
li {
a {
font-size: @font-size-small;
padding: 8px 10px;
}
}
> li + li {
margin-left: @margin-sm;
}
}
}
@media (min-width: @screen-md-min) { @media (min-width: @screen-md-min) {
.plans { .plans {
blockquote { blockquote {

View file

@ -1640,5 +1640,7 @@
"change_primary_email_address_instructions": "To change your primary email, please add your new primary email address first (by clicking <0>Add another email</0>) and confirm it. Then click the <0>Make Primary</0> button. <1>Learn more</1> about managing your __appName__ emails.", "change_primary_email_address_instructions": "To change your primary email, please add your new primary email address first (by clicking <0>Add another email</0>) and confirm it. Then click the <0>Make Primary</0> button. <1>Learn more</1> about managing your __appName__ emails.",
"help_improve_overleaf_fill_out_this_survey": "If you would like to help us improve Overleaf, please take a moment to fill out <0>this survey</0>.", "help_improve_overleaf_fill_out_this_survey": "If you would like to help us improve Overleaf, please take a moment to fill out <0>this survey</0>.",
"unlink_dropbox_folder": "Unlink Dropbox Account", "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?" "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?",
"save_20_percent_by_paying_annually": "Save 20% by paying annually",
"saving_20_percent": "Saving 20%!"
} }