mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #12593 from overleaf/jk-remove-plans-split-test
[web] Remove 'plans-page-layout-v3' split test GitOrigin-RevId: 91e0d3d8bc40632df630131b2e872fa824015da5
This commit is contained in:
parent
70072481f4
commit
f5740e6b17
16 changed files with 95 additions and 1266 deletions
|
@ -56,37 +56,7 @@ async function plansPage(req, res) {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
let plansPageLayoutV3Assignment = { variant: 'default' }
|
const currentView = 'annual'
|
||||||
|
|
||||||
try {
|
|
||||||
plansPageLayoutV3Assignment = await SplitTestHandler.promises.getAssignment(
|
|
||||||
req,
|
|
||||||
res,
|
|
||||||
'plans-page-layout-v3'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (plansPageLayoutV3Assignment.variant === 'old-plans-page-annual') {
|
|
||||||
plansPageLayoutV3Assignment.variant = 'old-plans-page-annual-fixed'
|
|
||||||
res.locals.splitTestVariants['plans-page-layout-v3'] =
|
|
||||||
'old-plans-page-annual-fixed'
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(
|
|
||||||
{ err: error },
|
|
||||||
'failed to get "plans-page-layout-v3" split test assignment'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentView = 'monthly'
|
|
||||||
if (
|
|
||||||
plansPageLayoutV3Assignment.variant === 'old-plans-page-annual-fixed' ||
|
|
||||||
plansPageLayoutV3Assignment.variant === 'new-plans-page'
|
|
||||||
) {
|
|
||||||
currentView = 'annual'
|
|
||||||
}
|
|
||||||
|
|
||||||
const showNewPlansPage =
|
|
||||||
plansPageLayoutV3Assignment.variant === 'new-plans-page'
|
|
||||||
|
|
||||||
let defaultGroupPlanModalCurrency = 'USD'
|
let defaultGroupPlanModalCurrency = 'USD'
|
||||||
if (validGroupPlanModalOptions.currency.includes(recommendedCurrency)) {
|
if (validGroupPlanModalOptions.currency.includes(recommendedCurrency)) {
|
||||||
|
@ -94,20 +64,14 @@ async function plansPage(req, res) {
|
||||||
}
|
}
|
||||||
const groupPlanModalDefaults = {
|
const groupPlanModalDefaults = {
|
||||||
plan_code: getDefault('plan', 'plan_code', 'collaborator'),
|
plan_code: getDefault('plan', 'plan_code', 'collaborator'),
|
||||||
size: getDefault('number', 'size', showNewPlansPage ? '2' : '10'),
|
size: getDefault('number', 'size', '2'),
|
||||||
currency: getDefault('currency', 'currency', defaultGroupPlanModalCurrency),
|
currency: getDefault('currency', 'currency', defaultGroupPlanModalCurrency),
|
||||||
usage: getDefault('usage', 'usage', 'enterprise'),
|
usage: getDefault('usage', 'usage', 'enterprise'),
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalyticsManager.recordEventForSession(req.session, 'plans-page-view', {
|
AnalyticsManager.recordEventForSession(req.session, 'plans-page-view')
|
||||||
'plans-page-layout-v3': plansPageLayoutV3Assignment.variant,
|
|
||||||
})
|
|
||||||
|
|
||||||
const template = showNewPlansPage
|
res.render('subscriptions/plans-marketing-v2', {
|
||||||
? 'subscriptions/plans-marketing-v2'
|
|
||||||
: 'subscriptions/plans-marketing'
|
|
||||||
|
|
||||||
res.render(template, {
|
|
||||||
title: 'plans_and_pricing',
|
title: 'plans_and_pricing',
|
||||||
currentView,
|
currentView,
|
||||||
plans,
|
plans,
|
||||||
|
@ -120,7 +84,6 @@ async function plansPage(req, res) {
|
||||||
groupPlans: GroupPlansData,
|
groupPlans: GroupPlansData,
|
||||||
groupPlanModalOptions,
|
groupPlanModalOptions,
|
||||||
groupPlanModalDefaults,
|
groupPlanModalDefaults,
|
||||||
plansPageLayoutV3Variant: plansPageLayoutV3Assignment.variant,
|
|
||||||
initialLocalizedGroupPrice:
|
initialLocalizedGroupPrice:
|
||||||
SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||||
recommendedCurrency
|
recommendedCurrency
|
||||||
|
|
|
@ -17,9 +17,7 @@ const config = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
eventTrackingKey: 'plans-page-click',
|
eventTrackingKey: 'plans-page-click',
|
||||||
additionalEventSegmentation: {
|
additionalEventSegmentation: {},
|
||||||
'plans-page-layout-v3': 'new-plans-page',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
group: {
|
group: {
|
||||||
tableHead: {
|
tableHead: {
|
||||||
|
@ -35,9 +33,7 @@ const config = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
eventTrackingKey: 'plans-page-click',
|
eventTrackingKey: 'plans-page-click',
|
||||||
additionalEventSegmentation: {
|
additionalEventSegmentation: {},
|
||||||
'plans-page-layout-v3': 'new-plans-page',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
student: {
|
student: {
|
||||||
baseColspan: 2,
|
baseColspan: 2,
|
||||||
|
@ -60,9 +56,7 @@ const config = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
eventTrackingKey: 'plans-page-click',
|
eventTrackingKey: 'plans-page-click',
|
||||||
additionalEventSegmentation: {
|
additionalEventSegmentation: {},
|
||||||
'plans-page-layout-v3': 'new-plans-page',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
extends ../layout
|
extends ../layout
|
||||||
|
|
||||||
include ./plans-marketing/_mixins
|
|
||||||
include ./plans-marketing/_tables
|
|
||||||
include ./plans-marketing/v2/_mixins
|
include ./plans-marketing/v2/_mixins
|
||||||
|
|
||||||
block vars
|
block vars
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
extends ../layout-marketing
|
extends ../layout-marketing
|
||||||
|
|
||||||
include ./plans-marketing/_mixins
|
|
||||||
include ./plans-marketing/_tables
|
|
||||||
|
|
||||||
block vars
|
block vars
|
||||||
- entrypoint = 'pages/user/subscription/plans-v2/plans-v2-main'
|
- entrypoint = 'pages/user/subscription/plans-v2/plans-v2-main'
|
||||||
|
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
extends ../layout-marketing
|
|
||||||
|
|
||||||
include ./plans-marketing/_mixins
|
|
||||||
include ./plans-marketing/_tables
|
|
||||||
|
|
||||||
block vars
|
|
||||||
- entrypoint = 'pages/user/subscription/plans'
|
|
||||||
|
|
||||||
block append meta
|
|
||||||
meta(name="ol-recommendedCurrency" content=recommendedCurrency)
|
|
||||||
meta(name="ol-groupPlans" data-type="json" content=groupPlans)
|
|
||||||
meta(name="ol-currencySymbols" data-type="json" content=groupPlanModalOptions.currencySymbols)
|
|
||||||
meta(name="ol-itm_content" content=itm_content)
|
|
||||||
meta(name="ol-currentView" content=currentView)
|
|
||||||
|
|
||||||
block content
|
|
||||||
main.content.content-alt#main-content
|
|
||||||
.content-page
|
|
||||||
.plans
|
|
||||||
.container(ng-cloak)
|
|
||||||
.row
|
|
||||||
.col-md-12
|
|
||||||
.page-header.centered.plans-header.text-centered
|
|
||||||
h1.text-capitalize(ng-non-bindable) #{translate('get_instant_access_to')} #{settings.appName}
|
|
||||||
.row
|
|
||||||
.col-md-8.col-md-offset-2
|
|
||||||
p.text-centered #{translate("sl_benefits_plans")}
|
|
||||||
|
|
||||||
+allCardsAndControls()
|
|
||||||
|
|
||||||
.row.row-spaced-large.text-centered
|
|
||||||
.col-xs-12
|
|
||||||
p.text-centered !{translate('also_provides_free_plan', {}, [{ name: 'a', attrs: { href: '/register' }}])}
|
|
||||||
i.fa.fa-cc-mastercard.fa-2x(aria-hidden="true")
|
|
||||||
span.sr-only Mastercard accepted
|
|
||||||
i.fa.fa-cc-visa.fa-2x(aria-hidden="true")
|
|
||||||
span.sr-only Visa accepted
|
|
||||||
i.fa.fa-cc-amex.fa-2x(aria-hidden="true")
|
|
||||||
span.sr-only Amex accepted
|
|
||||||
i.fa.fa-cc-paypal.fa-2x(aria-hidden="true")
|
|
||||||
span.sr-only Paypal accepted
|
|
||||||
div.text-centered #{translate('change_plans_any_time')}<br/> #{translate('billed_after_x_days', {len:'7'})}
|
|
||||||
br
|
|
||||||
div.text-centered #{translate('subject_to_additional_vat')}<br/> #{translate('select_country_vat')}
|
|
||||||
|
|
||||||
.row.row-spaced-large
|
|
||||||
.col-md-8.col-md-offset-2
|
|
||||||
.card.text-centered
|
|
||||||
.card-header
|
|
||||||
h2 #{translate('looking_multiple_licenses')}
|
|
||||||
span #{translate('reduce_costs_group_licenses')}
|
|
||||||
br
|
|
||||||
br
|
|
||||||
a.btn.btn-default(
|
|
||||||
href="#groups"
|
|
||||||
data-ol-open-group-plan-modal
|
|
||||||
data-ol-location='callout'
|
|
||||||
) #{translate('find_out_more')}
|
|
||||||
|
|
||||||
.row.row-spaced-large
|
|
||||||
.col-sm-12
|
|
||||||
.page-header.plans-header.plans-subheader.text-centered
|
|
||||||
h2 #{translate('compare_plan_features')}
|
|
||||||
.row
|
|
||||||
.col-md-6.col-md-offset-3
|
|
||||||
if (plansPageLayoutV3Variant === 'old-plans-page-annual-fixed')
|
|
||||||
+plan_switch_annual_default('table')
|
|
||||||
else
|
|
||||||
+plan_switch('table')
|
|
||||||
.col-md-3.text-right
|
|
||||||
+currency_dropdown
|
|
||||||
.row(event-tracking="features-table-viewed" event-tracking-ga="subscription-funnel" event-tracking-trigger="scroll" event-tracking-send-once="true" event-tracking-label="exp-")
|
|
||||||
.col-sm-12(hidden=(currentView !== 'monthly') data-ol-view='monthly')
|
|
||||||
+table_premium
|
|
||||||
.col-sm-12(hidden=(currentView !== 'annual') data-ol-view='annual')
|
|
||||||
+table_premium
|
|
||||||
.col-sm-12(hidden=(currentView !== 'student') data-ol-view='student')
|
|
||||||
+table_student
|
|
||||||
|
|
||||||
include ./plans-marketing/_quotes
|
|
||||||
|
|
||||||
include ./plans-marketing/_faq
|
|
||||||
|
|
||||||
#bottom-cards.row.row-spaced(style="display: none;")
|
|
||||||
.col-sm-12
|
|
||||||
+allCardsAndControls(true, 'bottom')
|
|
||||||
|
|
||||||
.row.row-spaced-large
|
|
||||||
.col-md-12
|
|
||||||
.plans-header.plans-subheader.text-centered
|
|
||||||
h2.header-with-btn #{translate('still_have_questions')}
|
|
||||||
button.btn.btn-default.btn-header.text-capitalize(
|
|
||||||
data-ol-open-contact-form-modal="general"
|
|
||||||
) #{translate('get_in_touch')}
|
|
||||||
|
|
||||||
.row.row-spaced
|
|
||||||
|
|
||||||
include ./plans-marketing/_group_plan_modal
|
|
||||||
!= moduleIncludes("contactModalGeneral-marketing", locals)
|
|
|
@ -1,34 +0,0 @@
|
||||||
.faq
|
|
||||||
.row.row-spaced-large
|
|
||||||
.col-md-12
|
|
||||||
.page-header.plans-header.plans-subheader.text-centered
|
|
||||||
h2 FAQ
|
|
||||||
.row
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate("faq_how_free_trial_works_question")}
|
|
||||||
p #{translate('faq_how_does_free_trial_works_answer', { len:'7' })}
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_change_plans_question')}
|
|
||||||
p #{translate('faq_change_plans_answer')}
|
|
||||||
.row
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_do_collab_need_premium_question')}
|
|
||||||
p #{translate('faq_do_collab_need_premium_answer')}
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_need_more_collab_question')}
|
|
||||||
p !{translate('faq_need_more_collab_answer', { referFriendsLink: translate('referring_your_friends') })}
|
|
||||||
.row
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_purchase_more_licenses_question')}
|
|
||||||
p !{translate('faq_purchase_more_licenses_answer', { groupLink: translate('discounted_group_accounts') })}
|
|
||||||
a(href='#groups' data-ol-open-group-plan-modal) #{translate("get_in_touch_for_details")}
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_monthly_or_annual_question')}
|
|
||||||
p #{translate('faq_monthly_or_annual_answer')}
|
|
||||||
.row
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_how_to_pay_question')}
|
|
||||||
p #{translate('faq_how_to_pay_answer')}
|
|
||||||
.col-md-6
|
|
||||||
h3 #{translate('faq_pay_by_invoice_question')}
|
|
||||||
p !{translate('faq_pay_by_invoice_answer', {}, [{ name: 'a', attrs: { href: "#pay-by-invoice", 'data-ol-open-contact-form-modal': 'general' }}])}
|
|
|
@ -61,7 +61,6 @@ div.modal.fade(tabindex="-1" role="dialog" data-ol-group-plan-modal)
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-tracking-element="select"
|
event-tracking-element="select"
|
||||||
event-segmentation='{"plans-page-layout-v3": "' + (plansPageLayoutV3Variant) + '"}'
|
|
||||||
)
|
)
|
||||||
for size in groupPlanModalOptions.sizes
|
for size in groupPlanModalOptions.sizes
|
||||||
option(
|
option(
|
||||||
|
@ -89,7 +88,6 @@ div.modal.fade(tabindex="-1" role="dialog" data-ol-group-plan-modal)
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-tracking-element="checkbox"
|
event-tracking-element="checkbox"
|
||||||
event-segmentation='{"plans-page-layout-v3": "' + (plansPageLayoutV3Variant) + '"}'
|
|
||||||
)
|
)
|
||||||
span This license is for educational purposes (applies to students or faculty using Overleaf for teaching)
|
span This license is for educational purposes (applies to students or faculty using Overleaf for teaching)
|
||||||
|
|
||||||
|
|
|
@ -1,303 +0,0 @@
|
||||||
//- Buy Buttons
|
|
||||||
mixin btn_buy_collaborator(location)
|
|
||||||
a.btn.btn-primary(
|
|
||||||
data-ol-start-new-subscription='collaborator'
|
|
||||||
data-ol-location=location
|
|
||||||
)
|
|
||||||
span(hidden=(currentView !== 'monthly') data-ol-view='monthly') #{translate("start_free_trial")}
|
|
||||||
span(hidden=(currentView !== 'annual') data-ol-view='annual') #{translate("buy_now")}
|
|
||||||
mixin btn_buy_personal(location)
|
|
||||||
a.btn.btn-primary(
|
|
||||||
data-ol-start-new-subscription='paid-personal'
|
|
||||||
data-ol-tracking-plan='personal'
|
|
||||||
data-ol-location=location
|
|
||||||
)
|
|
||||||
span(hidden=(currentView !== 'monthly') data-ol-view='monthly') #{translate("start_free_trial")}
|
|
||||||
span(hidden=(currentView !== 'annual') data-ol-view='annual') #{translate("buy_now")}
|
|
||||||
mixin btn_buy_free(location)
|
|
||||||
a.btn.btn-primary(
|
|
||||||
data-ol-has-custom-href
|
|
||||||
href="/register"
|
|
||||||
style=(getLoggedInUserId() === null ? "" : "visibility: hidden")
|
|
||||||
data-ol-start-new-subscription='free'
|
|
||||||
data-ol-location=location
|
|
||||||
)
|
|
||||||
span.text-capitalize #{translate('get_started_now')}
|
|
||||||
mixin btn_buy_professional(location)
|
|
||||||
a.btn.btn-primary(
|
|
||||||
data-ol-start-new-subscription='professional'
|
|
||||||
data-ol-location=location
|
|
||||||
)
|
|
||||||
span(hidden=(currentView !== 'monthly') data-ol-view='monthly') #{translate("start_free_trial")}
|
|
||||||
span(hidden=(currentView !== 'annual') data-ol-view='annual') #{translate("buy_now")}
|
|
||||||
mixin btn_buy_student(location, plan)
|
|
||||||
if plan == 'annual'
|
|
||||||
a.btn.btn-primary(
|
|
||||||
data-ol-start-new-subscription='student'
|
|
||||||
data-ol-item-view='annual'
|
|
||||||
data-ol-tracking-label='student-annual'
|
|
||||||
data-ol-location=location
|
|
||||||
) #{translate("buy_now")}
|
|
||||||
else
|
|
||||||
a.btn.btn-primary(
|
|
||||||
data-ol-start-new-subscription='student'
|
|
||||||
data-ol-item-view='monthly'
|
|
||||||
data-ol-tracking-label='student-monthly'
|
|
||||||
data-ol-location=location
|
|
||||||
) #{translate("start_free_trial")}
|
|
||||||
|
|
||||||
//- Cards
|
|
||||||
mixin card_student_annual(location)
|
|
||||||
.best-value
|
|
||||||
strong #{translate('best_value')}
|
|
||||||
.card-header
|
|
||||||
h2 #{translate("student")} (#{translate("annual")})
|
|
||||||
h5.tagline #{translate('tagline_student_annual')}
|
|
||||||
.circle
|
|
||||||
span
|
|
||||||
+price_student_annual
|
|
||||||
+features_student(location, 'annual')
|
|
||||||
mixin card_student_monthly(location)
|
|
||||||
.card-header
|
|
||||||
h2 #{translate("student")}
|
|
||||||
h5.tagline #{translate('tagline_student_monthly')}
|
|
||||||
.circle
|
|
||||||
span
|
|
||||||
+price_student_monthly
|
|
||||||
+features_student(location, 'monthly')
|
|
||||||
|
|
||||||
//- Features Lists, used within cards
|
|
||||||
mixin features_collaborator(location)
|
|
||||||
ul.list-unstyled
|
|
||||||
li
|
|
||||||
strong #{translate("collabs_per_proj", {collabcount:10})}
|
|
||||||
+features_premium
|
|
||||||
li
|
|
||||||
br
|
|
||||||
+btn_buy_collaborator(location)
|
|
||||||
mixin features_free(location)
|
|
||||||
ul.list-unstyled
|
|
||||||
li #{translate("one_collaborator")}
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li
|
|
||||||
br
|
|
||||||
+btn_buy_free(location)
|
|
||||||
mixin features_personal(location)
|
|
||||||
ul.list-unstyled
|
|
||||||
li #{translate("one_collaborator")}
|
|
||||||
li
|
|
||||||
li
|
|
||||||
strong #{translate('premium_features')}
|
|
||||||
li #{translate('sync_dropbox_github')}
|
|
||||||
li #{translate('full_doc_history')}
|
|
||||||
li + #{translate('more').toLowerCase()}
|
|
||||||
li(class="hidden-xs hidden-sm")
|
|
||||||
li
|
|
||||||
br
|
|
||||||
+btn_buy_personal(location)
|
|
||||||
mixin features_premium
|
|
||||||
li
|
|
||||||
li
|
|
||||||
strong #{translate('all_premium_features')}
|
|
||||||
li #{translate('sync_dropbox_github')}
|
|
||||||
li #{translate('full_doc_history')}
|
|
||||||
li #{translate('track_changes')}
|
|
||||||
li + #{translate('more').toLowerCase()}
|
|
||||||
mixin features_professional(location)
|
|
||||||
ul.list-unstyled
|
|
||||||
li
|
|
||||||
strong #{translate("unlimited_collabs")}
|
|
||||||
+features_premium
|
|
||||||
li
|
|
||||||
br
|
|
||||||
+btn_buy_professional(location)
|
|
||||||
mixin features_student(location, plan)
|
|
||||||
ul.list-unstyled
|
|
||||||
li
|
|
||||||
strong #{translate("collabs_per_proj", {collabcount:6})}
|
|
||||||
+features_premium
|
|
||||||
li
|
|
||||||
br
|
|
||||||
+btn_buy_student(location, plan)
|
|
||||||
|
|
||||||
mixin gen_localized_price_for_plan_view(plan, view)
|
|
||||||
for currencyCode in Object.keys(settings.localizedPlanPricing)
|
|
||||||
span(
|
|
||||||
hidden=(currencyCode !== recommendedCurrency)
|
|
||||||
data-ol-currencyCode=currencyCode
|
|
||||||
) #{settings.localizedPlanPricing[currencyCode][plan][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)
|
|
||||||
div(hidden=(currentView !== 'monthly') data-ol-view='monthly')
|
|
||||||
+gen_localized_price_for_plan_view(plan, 'monthly')
|
|
||||||
span.small /mo
|
|
||||||
div(hidden=(currentView !== 'annual') data-ol-view='annual')
|
|
||||||
+gen_localized_price_for_plan_view(plan, 'annual')
|
|
||||||
span.small /yr
|
|
||||||
|
|
||||||
mixin gen_localized_undiscounted_price_for_plan(plan)
|
|
||||||
div(hidden=(currentView !== 'annual') data-ol-view='annual')
|
|
||||||
strike.undiscounted-price.small
|
|
||||||
span.sr-only Price reduced from
|
|
||||||
+gen_localized_undiscounted_price_for_plan_view(plan)
|
|
||||||
| /yr
|
|
||||||
|
|
||||||
//- Prices
|
|
||||||
mixin price_personal
|
|
||||||
+gen_localized_price_for_plan('personal')
|
|
||||||
mixin price_personal_undiscounted
|
|
||||||
+gen_localized_undiscounted_price_for_plan('personal')
|
|
||||||
mixin price_collaborator
|
|
||||||
+gen_localized_price_for_plan('collaborator')
|
|
||||||
mixin price_collaborator_undiscounted
|
|
||||||
+gen_localized_undiscounted_price_for_plan('collaborator')
|
|
||||||
mixin price_professional
|
|
||||||
+gen_localized_price_for_plan('professional')
|
|
||||||
mixin price_professional_undiscounted
|
|
||||||
+gen_localized_undiscounted_price_for_plan('professional')
|
|
||||||
mixin price_student_annual
|
|
||||||
+gen_localized_price_for_plan_view('student', 'annual')
|
|
||||||
span.small /yr
|
|
||||||
mixin price_student_monthly
|
|
||||||
+gen_localized_price_for_plan_view('student', 'monthly')
|
|
||||||
span.small /mo
|
|
||||||
|
|
||||||
//- UI Control
|
|
||||||
mixin currency_dropdown
|
|
||||||
.dropdown.currency-dropdown(dropdown)
|
|
||||||
a.btn.btn-default.dropdown-toggle(
|
|
||||||
href="#",
|
|
||||||
data-toggle="dropdown",
|
|
||||||
dropdown-toggle
|
|
||||||
)
|
|
||||||
for currencyCode in Object.keys(settings.localizedPlanPricing)
|
|
||||||
span(
|
|
||||||
hidden=(currencyCode !== recommendedCurrency)
|
|
||||||
data-ol-currencyCode=currencyCode
|
|
||||||
) #{currencyCode} (#{settings.localizedPlanPricing[currencyCode]['symbol']})
|
|
||||||
span.caret
|
|
||||||
|
|
||||||
ul.dropdown-menu.dropdown-menu-right.text-right(role="menu")
|
|
||||||
for currencyCode in Object.keys(settings.localizedPlanPricing)
|
|
||||||
li
|
|
||||||
a(
|
|
||||||
href='#'
|
|
||||||
data-ol-currencyCode-switch=currencyCode
|
|
||||||
) #{currencyCode} #{settings.localizedPlanPricing[currencyCode]['symbol']}
|
|
||||||
|
|
||||||
mixin plan_switch(location)
|
|
||||||
ul.nav.nav-pills(class=(location === 'card' ? "above-cards" : ""))
|
|
||||||
li.active(data-ol-view-tab='monthly')
|
|
||||||
button.btn-default-outline #{translate("monthly")}
|
|
||||||
li(data-ol-view-tab='annual' class=(location === 'card' ? "annual-saving-tooltip-container" : ""))
|
|
||||||
button.btn-default-outline #{translate("annual")}
|
|
||||||
if (location === 'card')
|
|
||||||
.tooltip.in.bottom.annual-saving-tooltip(
|
|
||||||
role="tooltip"
|
|
||||||
data-ol-annual-saving-tooltip
|
|
||||||
)
|
|
||||||
.tooltip-arrow
|
|
||||||
.tooltip-inner
|
|
||||||
span(hidden=(currentView !== 'monthly') data-ol-view='monthly') #{translate("save_20_percent_by_paying_annually")}
|
|
||||||
span(hidden=(currentView !== 'annual') data-ol-view='annual') #{translate("saving_20_percent")}
|
|
||||||
span(hidden=(currentView !== 'student') data-ol-view='student') #{translate("save_20_percent_by_paying_annually")}
|
|
||||||
li(data-ol-view-tab='student')
|
|
||||||
button.btn-default-outline #{translate("special_price_student")}
|
|
||||||
|
|
||||||
mixin plan_switch_annual_default(location)
|
|
||||||
ul.nav.nav-pills(class=(location === 'card' ? "above-cards" : ""))
|
|
||||||
li.active(data-ol-view-tab='annual' class=(location === 'card' ? "annual-saving-tooltip-container" : ""))
|
|
||||||
button.btn-default-outline #{translate("annual")}
|
|
||||||
if (location === 'card')
|
|
||||||
.tooltip.in.bottom.annual-saving-tooltip.annual-selected.green-background(
|
|
||||||
role="tooltip"
|
|
||||||
data-ol-annual-saving-tooltip
|
|
||||||
)
|
|
||||||
.tooltip-arrow
|
|
||||||
.tooltip-inner
|
|
||||||
span(hidden=(currentView !== 'annual') data-ol-view='annual') #{translate("saving_20_percent")}
|
|
||||||
span(hidden=(currentView !== 'monthly') data-ol-view='monthly') #{translate("save_20_percent_by_paying_annually")}
|
|
||||||
span(hidden=(currentView !== 'student') data-ol-view='student') #{translate("save_20_percent_by_paying_annually")}
|
|
||||||
li(data-ol-view-tab='monthly')
|
|
||||||
button.btn-default-outline #{translate("monthly")}
|
|
||||||
li(data-ol-view-tab='student')
|
|
||||||
button.btn-default-outline #{translate("special_price_student")}
|
|
||||||
|
|
||||||
mixin allCardsAndControls(controlsRowSpaced, listLocation)
|
|
||||||
- var location = listLocation ? 'card_' + listLocation : 'card'
|
|
||||||
.row.top-switch(class=(controlsRowSpaced ? "row-spaced" : ""))
|
|
||||||
.col-md-6.col-md-offset-3
|
|
||||||
if (plansPageLayoutV3Variant === 'old-plans-page-annual-fixed')
|
|
||||||
+plan_switch_annual_default(location)
|
|
||||||
else
|
|
||||||
+plan_switch(location)
|
|
||||||
.col-md-2.text-right
|
|
||||||
+currency_dropdown
|
|
||||||
|
|
||||||
.row
|
|
||||||
.col-md-10.col-md-offset-1
|
|
||||||
.row
|
|
||||||
for view in ['monthly', 'annual']
|
|
||||||
.card-group.text-centered(data-ol-view=view hidden=(view==='annual'))
|
|
||||||
.col-md-4
|
|
||||||
.card.card-first
|
|
||||||
.card-header
|
|
||||||
h2 #{translate("personal")}
|
|
||||||
.card-byline
|
|
||||||
h5.tagline #{translate("tagline_personal")}
|
|
||||||
.circle
|
|
||||||
+price_personal
|
|
||||||
+price_personal_undiscounted
|
|
||||||
+features_personal(location)
|
|
||||||
.col-md-4
|
|
||||||
.card.card-highlighted
|
|
||||||
.best-value
|
|
||||||
strong #{translate('best_value')}
|
|
||||||
.card-header
|
|
||||||
h2 #{translate("standard")}
|
|
||||||
.card-byline
|
|
||||||
h5.tagline #{translate("tagline_collaborator")}
|
|
||||||
.circle
|
|
||||||
+price_collaborator
|
|
||||||
+price_collaborator_undiscounted
|
|
||||||
+features_collaborator(location)
|
|
||||||
.col-md-4
|
|
||||||
.card.card-last
|
|
||||||
.card-header
|
|
||||||
h2 #{translate("professional")}
|
|
||||||
.card-byline
|
|
||||||
h5.tagline #{translate("tagline_professional")}
|
|
||||||
.circle
|
|
||||||
+price_professional
|
|
||||||
+price_professional_undiscounted
|
|
||||||
+features_professional(location)
|
|
||||||
|
|
||||||
.card-group.text-centered(hidden=(currentView !== 'student') data-ol-view='student')
|
|
||||||
.col-md-4
|
|
||||||
.card.card-first
|
|
||||||
.card-header
|
|
||||||
h2 #{translate("free")}
|
|
||||||
h5.tagline #{translate("tagline_free")}
|
|
||||||
.circle #{translate("free")}
|
|
||||||
+features_free(location)
|
|
||||||
|
|
||||||
.col-md-4
|
|
||||||
.card.card-highlighted
|
|
||||||
+card_student_annual(location)
|
|
||||||
|
|
||||||
.col-md-4
|
|
||||||
.card.card-last
|
|
||||||
+card_student_monthly(location)
|
|
|
@ -1,116 +0,0 @@
|
||||||
//- Features Tables
|
|
||||||
mixin table_premium
|
|
||||||
table.card.plans-table.plans-table-main
|
|
||||||
tr
|
|
||||||
th
|
|
||||||
th #{translate("free")}
|
|
||||||
th #{translate("personal")}
|
|
||||||
th #{translate("standard")}
|
|
||||||
.outer.outer-top
|
|
||||||
.outer-content
|
|
||||||
.best-value
|
|
||||||
strong #{translate('best_value')}
|
|
||||||
th #{translate("professional")}
|
|
||||||
|
|
||||||
tr
|
|
||||||
td #{translate("price")}
|
|
||||||
td #{translate("free")}
|
|
||||||
td
|
|
||||||
+price_personal
|
|
||||||
td
|
|
||||||
+price_collaborator
|
|
||||||
td
|
|
||||||
+price_professional
|
|
||||||
|
|
||||||
for feature in planFeatures
|
|
||||||
tr
|
|
||||||
td(event-tracking="features-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
|
|
||||||
if feature.info
|
|
||||||
span(data-toggle="tooltip" title=translate(feature.info)) #{translate(feature.feature)}
|
|
||||||
else
|
|
||||||
| #{translate(feature.feature)}
|
|
||||||
for plan in feature.plans
|
|
||||||
td(ng-non-bindable)
|
|
||||||
if feature.value == 'str'
|
|
||||||
| #{plan}
|
|
||||||
else if plan
|
|
||||||
i.fa.fa-check(aria-hidden="true")
|
|
||||||
span.sr-only #{translate("feature_included")}
|
|
||||||
else
|
|
||||||
i.fa.fa-times(aria-hidden="true")
|
|
||||||
span.sr-only #{translate("feature_not_included")}
|
|
||||||
|
|
||||||
tr
|
|
||||||
td
|
|
||||||
td
|
|
||||||
+btn_buy_free('table')
|
|
||||||
td
|
|
||||||
+btn_buy_personal('table')
|
|
||||||
td
|
|
||||||
+btn_buy_collaborator('table')
|
|
||||||
.outer.outer-btm
|
|
||||||
.outer-content
|
|
||||||
td
|
|
||||||
+btn_buy_professional('table')
|
|
||||||
|
|
||||||
mixin table_cell_student(feature)
|
|
||||||
if feature.value == 'str'
|
|
||||||
| #{feature.student}
|
|
||||||
else if feature.student
|
|
||||||
i.fa.fa-check(aria-hidden="true")
|
|
||||||
span.sr-only #{translate("feature_included")}
|
|
||||||
else
|
|
||||||
i.fa.fa-times(aria-hidden="true")
|
|
||||||
span.sr-only #{translate("feature_not_included")}
|
|
||||||
|
|
||||||
mixin table_student
|
|
||||||
table.card.plans-table.plans-table-student
|
|
||||||
tr
|
|
||||||
th
|
|
||||||
th #{translate("free")}
|
|
||||||
th #{translate("student")} (#{translate("annual")})
|
|
||||||
.outer.outer-top
|
|
||||||
.outer-content
|
|
||||||
.best-value
|
|
||||||
strong Best Value
|
|
||||||
th #{translate("student")}
|
|
||||||
|
|
||||||
tr
|
|
||||||
td #{translate("price")}
|
|
||||||
td #{translate("free")}
|
|
||||||
td
|
|
||||||
+price_student_annual
|
|
||||||
td
|
|
||||||
+price_student_monthly
|
|
||||||
|
|
||||||
for feature in planFeatures
|
|
||||||
tr
|
|
||||||
td(event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
|
|
||||||
if feature.info
|
|
||||||
span(data-toggle="tooltip" title=translate(feature.info)) #{translate(feature.feature)}
|
|
||||||
else
|
|
||||||
| #{translate(feature.feature)}
|
|
||||||
td(ng-non-bindable)
|
|
||||||
if feature.value == 'str'
|
|
||||||
| #{feature.plans.free}
|
|
||||||
else if feature.plans.free
|
|
||||||
i.fa.fa-check(aria-hidden="true")
|
|
||||||
span.sr-only #{translate("feature_included")}
|
|
||||||
else
|
|
||||||
i.fa.fa-times(aria-hidden="true")
|
|
||||||
span.sr-only #{translate("feature_not_included")}
|
|
||||||
td(ng-non-bindable)
|
|
||||||
+table_cell_student(feature)
|
|
||||||
td(ng-non-bindable)
|
|
||||||
+table_cell_student(feature)
|
|
||||||
|
|
||||||
tr
|
|
||||||
td
|
|
||||||
td
|
|
||||||
+btn_buy_free('table')
|
|
||||||
td
|
|
||||||
+btn_buy_student('table', 'annual')
|
|
||||||
.outer.outer-btm
|
|
||||||
.outer-content
|
|
||||||
td
|
|
||||||
+btn_buy_student('table', 'monthly')
|
|
|
@ -8,7 +8,7 @@ include ./_mixins
|
||||||
event-tracking="plans-page-toggle-plan"
|
event-tracking="plans-page-toggle-plan"
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-segmentation='{"button": "individual", "plans-page-layout-v3": "new-plans-page"}'
|
event-segmentation='{"button": "individual"}'
|
||||||
)
|
)
|
||||||
button.btn.btn-default-outline #{translate("indvidual_plans")}
|
button.btn.btn-default-outline #{translate("indvidual_plans")}
|
||||||
li.plans-v2-top-switch-group(
|
li.plans-v2-top-switch-group(
|
||||||
|
@ -16,7 +16,7 @@ include ./_mixins
|
||||||
event-tracking="plans-page-toggle-plan"
|
event-tracking="plans-page-toggle-plan"
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-segmentation='{"button": "group", "plans-page-layout-v3": "new-plans-page"}'
|
event-segmentation='{"button": "group"}'
|
||||||
)
|
)
|
||||||
button.btn.btn-default-outline(
|
button.btn.btn-default-outline(
|
||||||
href="#"
|
href="#"
|
||||||
|
@ -28,13 +28,13 @@ include ./_mixins
|
||||||
event-tracking="plans-page-toggle-plan"
|
event-tracking="plans-page-toggle-plan"
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-segmentation='{"button": "student", "plans-page-layout-v3": "new-plans-page"}'
|
event-segmentation='{"button": "student"}'
|
||||||
)
|
)
|
||||||
button.btn.btn-default-outline(
|
button.btn.btn-default-outline(
|
||||||
href="#"
|
href="#"
|
||||||
) #{translate("student_plans")}
|
) #{translate("student_plans")}
|
||||||
|
|
||||||
+monthly_annual_switch("annual", "plans-page-toggle-period", '{"plans-page-layout-v3": "new-plans-page"}')
|
+monthly_annual_switch("annual", "plans-page-toggle-period")
|
||||||
|
|
||||||
.row(hidden data-ol-plans-v2-license-picker-container)
|
.row(hidden data-ol-plans-v2-license-picker-container)
|
||||||
.col-sm-12
|
.col-sm-12
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
mixin features_premium
|
||||||
|
li
|
||||||
|
li
|
||||||
|
strong #{translate('all_premium_features')}
|
||||||
|
li #{translate('sync_dropbox_github')}
|
||||||
|
li #{translate('full_doc_history')}
|
||||||
|
li #{translate('track_changes')}
|
||||||
|
li + #{translate('more').toLowerCase()}
|
||||||
|
|
||||||
|
mixin gen_localized_price_for_plan_view(plan, view)
|
||||||
|
span #{settings.localizedPlanPricing[recommendedCurrency][plan][view]}
|
||||||
|
|
||||||
mixin plans_v2_table(period, config)
|
mixin plans_v2_table(period, config)
|
||||||
- var baseColspan = config.baseColspan || 1
|
- var baseColspan = config.baseColspan || 1
|
||||||
- var maxColumn = config.maxColumn || 4
|
- var maxColumn = config.maxColumn || 4
|
||||||
|
@ -344,7 +356,6 @@ mixin group_plans_license_picker()
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-tracking-element="select"
|
event-tracking-element="select"
|
||||||
event-segmentation='{"plans-page-layout-v3": "new-plans-page"}'
|
|
||||||
)
|
)
|
||||||
option(value="2") 2
|
option(value="2") 2
|
||||||
option(value="3") 3
|
option(value="3") 3
|
||||||
|
@ -364,7 +375,6 @@ mixin group_plans_license_picker()
|
||||||
event-tracking-mb="true"
|
event-tracking-mb="true"
|
||||||
event-tracking-trigger="click"
|
event-tracking-trigger="click"
|
||||||
event-tracking-element="checkbox"
|
event-tracking-element="checkbox"
|
||||||
event-segmentation='{"plans-page-layout-v3": "new-plans-page"}'
|
|
||||||
)
|
)
|
||||||
span #{translate("apply_educational_discount")}
|
span #{translate("apply_educational_discount")}
|
||||||
//- will only appear on screen width >= 768px (using CSS)
|
//- will only appear on screen width >= 768px (using CSS)
|
||||||
|
|
|
@ -13,7 +13,69 @@ import {
|
||||||
updateMainGroupPlanPricing,
|
updateMainGroupPlanPricing,
|
||||||
} from './plans-v2-group-plan'
|
} from './plans-v2-group-plan'
|
||||||
import { setUpGroupSubscriptionButtonAction } from './plans-v2-subscription-button'
|
import { setUpGroupSubscriptionButtonAction } from './plans-v2-subscription-button'
|
||||||
import { updateLinkTargets } from '../plans'
|
import getMeta from '../../../../utils/meta'
|
||||||
|
|
||||||
|
const currentCurrencyCode = getMeta('ol-recommendedCurrency')
|
||||||
|
|
||||||
|
function setUpSubscriptionTracking(linkEl) {
|
||||||
|
linkEl.addEventListener('click', function () {
|
||||||
|
const plan =
|
||||||
|
linkEl.getAttribute('data-ol-tracking-plan') ||
|
||||||
|
linkEl.getAttribute('data-ol-start-new-subscription')
|
||||||
|
|
||||||
|
const location = linkEl.getAttribute('data-ol-location')
|
||||||
|
const period = linkEl.getAttribute('data-ol-item-view')
|
||||||
|
|
||||||
|
const DEFAULT_EVENT_TRACKING_KEY = 'plans-page-click'
|
||||||
|
|
||||||
|
const eventTrackingKey =
|
||||||
|
linkEl.getAttribute('data-ol-event-tracking-key') ||
|
||||||
|
DEFAULT_EVENT_TRACKING_KEY
|
||||||
|
|
||||||
|
const eventTrackingSegmentation = {
|
||||||
|
button: plan,
|
||||||
|
location,
|
||||||
|
'billing-period': period,
|
||||||
|
}
|
||||||
|
|
||||||
|
eventTracking.sendMB('plans-page-start-trial') // deprecated by plans-page-click
|
||||||
|
eventTracking.sendMB(eventTrackingKey, eventTrackingSegmentation)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchParams = new URLSearchParams(window.location.search)
|
||||||
|
|
||||||
|
export function updateLinkTargets() {
|
||||||
|
document.querySelectorAll('[data-ol-start-new-subscription]').forEach(el => {
|
||||||
|
if (el.hasAttribute('data-ol-has-custom-href')) return
|
||||||
|
|
||||||
|
const plan = el.getAttribute('data-ol-start-new-subscription')
|
||||||
|
const view = el.getAttribute('data-ol-item-view')
|
||||||
|
const suffix = view === 'annual' ? `-annual` : `_free_trial_7_days`
|
||||||
|
const planCode = `${plan}${suffix}`
|
||||||
|
|
||||||
|
const location = el.getAttribute('data-ol-location')
|
||||||
|
const itmCampaign = searchParams.get('itm_campaign') || 'plans'
|
||||||
|
const itmContent =
|
||||||
|
itmCampaign === 'plans' ? location : searchParams.get('itm_content')
|
||||||
|
|
||||||
|
const queryString = new URLSearchParams({
|
||||||
|
planCode,
|
||||||
|
currency: currentCurrencyCode,
|
||||||
|
itm_campaign: itmCampaign,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (itmContent) {
|
||||||
|
queryString.set('itm_content', itmContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchParams.get('itm_referrer')) {
|
||||||
|
queryString.set('itm_referrer', searchParams.get('itm_referrer'))
|
||||||
|
}
|
||||||
|
|
||||||
|
el.href = `/user/subscription/new?${queryString.toString()}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// We need this mutable variable because the group tab only have annual.
|
// We need this mutable variable because the group tab only have annual.
|
||||||
// There's some difference between the monthly and annual UI
|
// There's some difference between the monthly and annual UI
|
||||||
|
@ -133,6 +195,10 @@ document
|
||||||
switchMonthlyAnnual(currentMonthlyAnnualSwitchValue)
|
switchMonthlyAnnual(currentMonthlyAnnualSwitchValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll('[data-ol-start-new-subscription]')
|
||||||
|
.forEach(setUpSubscriptionTracking)
|
||||||
|
|
||||||
setUpTabSwitching()
|
setUpTabSwitching()
|
||||||
setUpGroupPlanPricingChange()
|
setUpGroupPlanPricingChange()
|
||||||
setUpMonthlyAnnualSwitching()
|
setUpMonthlyAnnualSwitching()
|
||||||
|
|
|
@ -1,202 +0,0 @@
|
||||||
import '../../../marketing'
|
|
||||||
import '../../../features/plans/group-plan-modal'
|
|
||||||
import * as eventTracking from '../../../infrastructure/event-tracking'
|
|
||||||
import getMeta from '../../../utils/meta'
|
|
||||||
|
|
||||||
let currentView = getMeta('ol-currentView')
|
|
||||||
let currentCurrencyCode = getMeta('ol-recommendedCurrency')
|
|
||||||
const plansPageLayoutV3Variant =
|
|
||||||
getMeta('ol-splitTestVariants')?.['plans-page-layout-v3'] ?? 'default'
|
|
||||||
|
|
||||||
if (window.location.href.includes('validate-pre-rendering=true')) {
|
|
||||||
validatePreRendering()
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectView(view) {
|
|
||||||
document.querySelectorAll('[data-ol-view-tab]').forEach(el => {
|
|
||||||
if (el.getAttribute('data-ol-view-tab') === view) {
|
|
||||||
el.classList.add('active')
|
|
||||||
} else {
|
|
||||||
el.classList.remove('active')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
document.querySelectorAll('[data-ol-view]').forEach(el => {
|
|
||||||
el.hidden = el.getAttribute('data-ol-view') !== view
|
|
||||||
})
|
|
||||||
|
|
||||||
updateAnnualSavingBanner(view)
|
|
||||||
currentView = view
|
|
||||||
updateLinkTargets()
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUpViewSwitching(liEl) {
|
|
||||||
liEl.querySelector('button').addEventListener('click', function (e) {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
const view = liEl.getAttribute('data-ol-view-tab')
|
|
||||||
eventTracking.send('subscription-funnel', 'plans-page', `${view}-prices`)
|
|
||||||
eventTracking.sendMB('plans-page-toggle', {
|
|
||||||
button: view,
|
|
||||||
'plans-page-layout-v3': plansPageLayoutV3Variant,
|
|
||||||
})
|
|
||||||
selectView(view)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUpCurrencySwitching(linkEl) {
|
|
||||||
linkEl.addEventListener('click', function (e) {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
const currencyCode = linkEl.getAttribute('data-ol-currencyCode-switch')
|
|
||||||
document.querySelectorAll('[data-ol-currencyCode]').forEach(el => {
|
|
||||||
el.hidden = el.getAttribute('data-ol-currencyCode') !== currencyCode
|
|
||||||
})
|
|
||||||
currentCurrencyCode = currencyCode
|
|
||||||
eventTracking.sendMB('plans-page-currency', { currency: currencyCode })
|
|
||||||
updateLinkTargets()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUpSubscriptionTracking(linkEl) {
|
|
||||||
linkEl.addEventListener('click', function () {
|
|
||||||
const plansPageLayoutV3Variant =
|
|
||||||
getMeta('ol-splitTestVariants')?.['plans-page-layout-v3'] ?? 'default'
|
|
||||||
|
|
||||||
const plan =
|
|
||||||
linkEl.getAttribute('data-ol-tracking-plan') ||
|
|
||||||
linkEl.getAttribute('data-ol-start-new-subscription')
|
|
||||||
|
|
||||||
const location = linkEl.getAttribute('data-ol-location')
|
|
||||||
const period = linkEl.getAttribute('data-ol-item-view') || currentView
|
|
||||||
|
|
||||||
const DEFAULT_EVENT_TRACKING_KEY = 'plans-page-click'
|
|
||||||
|
|
||||||
const eventTrackingKey =
|
|
||||||
linkEl.getAttribute('data-ol-event-tracking-key') ||
|
|
||||||
DEFAULT_EVENT_TRACKING_KEY
|
|
||||||
|
|
||||||
const eventTrackingSegmentation = {
|
|
||||||
button: plan,
|
|
||||||
location,
|
|
||||||
'billing-period': period,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventTrackingKey === DEFAULT_EVENT_TRACKING_KEY) {
|
|
||||||
eventTrackingSegmentation['plans-page-layout-v3'] =
|
|
||||||
plansPageLayoutV3Variant
|
|
||||||
}
|
|
||||||
|
|
||||||
const customLabel = linkEl.getAttribute('data-ol-tracking-label')
|
|
||||||
const computedLabel = currentView === 'annual' ? `${plan}_annual` : plan
|
|
||||||
const label = customLabel || computedLabel
|
|
||||||
|
|
||||||
eventTracking.sendMB('plans-page-start-trial') // deprecated by plans-page-click
|
|
||||||
eventTracking.send('subscription-funnel', 'sign_up_now_button', label) // deprecated by plans-page-click
|
|
||||||
eventTracking.sendMB(eventTrackingKey, eventTrackingSegmentation)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchParams = new URLSearchParams(window.location.search)
|
|
||||||
|
|
||||||
export function updateLinkTargets() {
|
|
||||||
document.querySelectorAll('[data-ol-start-new-subscription]').forEach(el => {
|
|
||||||
if (el.hasAttribute('data-ol-has-custom-href')) return
|
|
||||||
|
|
||||||
const plan = el.getAttribute('data-ol-start-new-subscription')
|
|
||||||
const view = el.getAttribute('data-ol-item-view') || currentView
|
|
||||||
const suffix = view === 'annual' ? `-annual` : `_free_trial_7_days`
|
|
||||||
const planCode = `${plan}${suffix}`
|
|
||||||
|
|
||||||
const location = el.getAttribute('data-ol-location')
|
|
||||||
const itmCampaign = searchParams.get('itm_campaign') || 'plans'
|
|
||||||
const itmContent =
|
|
||||||
itmCampaign === 'plans' ? location : searchParams.get('itm_content')
|
|
||||||
|
|
||||||
const queryString = new URLSearchParams({
|
|
||||||
planCode,
|
|
||||||
currency: currentCurrencyCode,
|
|
||||||
itm_campaign: itmCampaign,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (itmContent) {
|
|
||||||
queryString.set('itm_content', itmContent)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchParams.get('itm_referrer')) {
|
|
||||||
queryString.set('itm_referrer', searchParams.get('itm_referrer'))
|
|
||||||
}
|
|
||||||
|
|
||||||
el.href = `/user/subscription/new?${queryString.toString()}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
|
||||||
try {
|
|
||||||
const params = new URLSearchParams(window.location.hash.substring(1))
|
|
||||||
const view = params.get('view')
|
|
||||||
if (view) {
|
|
||||||
// make sure the selected view is valid
|
|
||||||
if (document.querySelector(`[data-ol-view-tab="${view}"]`)) {
|
|
||||||
selectView(view)
|
|
||||||
// clear the hash so it doesn't persist when switching plans
|
|
||||||
window.location.hash = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function validatePreRendering() {
|
|
||||||
document.querySelectorAll('[data-ol-view-tab]').forEach(el => {
|
|
||||||
console.assert(
|
|
||||||
(el.getAttribute('data-ol-view-tab') === currentView) ===
|
|
||||||
el.classList.contains('active'),
|
|
||||||
el
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
document.querySelectorAll('[data-ol-view]').forEach(el => {
|
|
||||||
console.assert(
|
|
||||||
(el.hidden === el.getAttribute('data-ol-view')) !== currentView,
|
|
||||||
el
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const plansPageLayoutV3Variant = getMeta('ol-splitTestVariants')?.[
|
|
||||||
'plans-page-layout-v3'
|
|
||||||
]
|
|
||||||
if (plansPageLayoutV3Variant !== 'new-plans-page') {
|
|
||||||
const tooltipEl = document.querySelector('[data-ol-annual-saving-tooltip]')
|
|
||||||
console.assert(
|
|
||||||
(currentView === 'annual') ===
|
|
||||||
tooltipEl.classList.contains('annual-selected'),
|
|
||||||
tooltipEl
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('validated pre-rendering')
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll('[data-ol-view-tab]').forEach(setUpViewSwitching)
|
|
||||||
document
|
|
||||||
.querySelectorAll('[data-ol-currencyCode-switch]')
|
|
||||||
.forEach(setUpCurrencySwitching)
|
|
||||||
document
|
|
||||||
.querySelectorAll('[data-ol-start-new-subscription]')
|
|
||||||
.forEach(setUpSubscriptionTracking)
|
|
||||||
updateLinkTargets()
|
|
||||||
|
|
||||||
selectViewFromHash()
|
|
||||||
window.addEventListener('hashchange', selectViewFromHash)
|
|
|
@ -3,35 +3,15 @@
|
||||||
color: @gray-dark;
|
color: @gray-dark;
|
||||||
margin-bottom: @line-height-computed;
|
margin-bottom: @line-height-computed;
|
||||||
}
|
}
|
||||||
.best-value {
|
|
||||||
color: @brand-secondary;
|
|
||||||
line-height: @line-height-computed;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
blockquote {
|
blockquote {
|
||||||
footer {
|
footer {
|
||||||
/* accessibility fix */
|
/* accessibility fix */
|
||||||
color: @gray-med;
|
color: @gray-med;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.btn-header {
|
|
||||||
font-family: @font-family-sans-serif;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-top: -10px;
|
|
||||||
text-shadow: 0 0 0;
|
|
||||||
}
|
|
||||||
.card .btn {
|
.card .btn {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
.card.features {
|
|
||||||
margin-top: @line-height-computed;
|
|
||||||
i {
|
|
||||||
color: @red;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.btn-header {
|
.btn-header {
|
||||||
font-family: @font-family-sans-serif;
|
font-family: @font-family-sans-serif;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
@ -41,29 +21,6 @@
|
||||||
.card .btn {
|
.card .btn {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
.card-group {
|
|
||||||
.card-highlighted {
|
|
||||||
padding-top: @line-height-computed * 2;
|
|
||||||
padding-bottom: @line-height-computed * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.card-first,
|
|
||||||
.card-last {
|
|
||||||
background: @plans-non-highlighted;
|
|
||||||
}
|
|
||||||
.card-highlighted {
|
|
||||||
border: @border-width-base solid @border-color-base;
|
|
||||||
padding-top: 10px !important;
|
|
||||||
.best-value {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.card-header {
|
|
||||||
padding-bottom: 22px; /* align hr with other plans */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.card-header {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.circle {
|
.circle {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
@ -125,89 +82,6 @@
|
||||||
.tagline {
|
.tagline {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
ul.nav-pills {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: @line-height-computed;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
li {
|
|
||||||
float: none;
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
.annual-saving-tooltip {
|
|
||||||
// hide tooltip below group modal, which has 1050 z-index value (from bootstrap .modal class)
|
|
||||||
// .tooltip (this element) has 1070 default z-index value
|
|
||||||
z-index: 1040;
|
|
||||||
white-space: nowrap;
|
|
||||||
left: 50%;
|
|
||||||
width: @tooltip-max-width;
|
|
||||||
margin-left: -(@tooltip-max-width / 2);
|
|
||||||
&.bottom {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
&.annual-selected {
|
|
||||||
width: 110px;
|
|
||||||
margin-left: -55px;
|
|
||||||
.tooltip-inner {
|
|
||||||
background-color: @ol-green;
|
|
||||||
}
|
|
||||||
.tooltip-arrow {
|
|
||||||
border-bottom-color: @ol-green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&.green-background {
|
|
||||||
.tooltip-inner {
|
|
||||||
background-color: @ol-green;
|
|
||||||
}
|
|
||||||
.tooltip-arrow {
|
|
||||||
border-bottom-color: @ol-green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tooltip-inner {
|
|
||||||
max-width: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
> li + li {
|
|
||||||
margin-left: @line-height-computed / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ul.nav-pills.above-cards {
|
|
||||||
margin-bottom: @line-height-computed * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#changePlanSection {
|
|
||||||
padding-top: 30px;
|
|
||||||
.changePlanButton {
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.paymentPageFeatures {
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3 {
|
|
||||||
color: @gray-dark;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
font-size: 18px;
|
|
||||||
&:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
font-size: 14px;
|
|
||||||
color: @gray;
|
|
||||||
}
|
|
||||||
.small {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.plansPageStudentLink {
|
|
||||||
margin-left: 20px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -220,41 +94,13 @@
|
||||||
/* Media Queries */
|
/* Media Queries */
|
||||||
@media (max-width: @screen-sm-max) {
|
@media (max-width: @screen-sm-max) {
|
||||||
.plans {
|
.plans {
|
||||||
.card-group {
|
|
||||||
/*override style in cards.less */
|
|
||||||
.card {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
.card-highlighted {
|
|
||||||
margin-top: @line-height-computed!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.circle-img {
|
.circle-img {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 0 15px;
|
margin: 0 15px;
|
||||||
}
|
}
|
||||||
ul.nav-pills {
|
|
||||||
margin-bottom: @margin-xs;
|
|
||||||
li {
|
|
||||||
margin-bottom: @margin-sm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (max-width: @screen-xs-max) {
|
|
||||||
.plans ul.nav-pills {
|
|
||||||
li {
|
|
||||||
button {
|
|
||||||
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 {
|
||||||
|
@ -267,11 +113,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.top-switch {
|
|
||||||
.currency-dropdown {
|
|
||||||
margin-right: -15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,266 +122,6 @@
|
||||||
margin: 12.5px 0 0 0;
|
margin: 12.5px 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Plans Table
|
|
||||||
*/
|
|
||||||
.plans-table {
|
|
||||||
border: 1px solid @gray-lighter;
|
|
||||||
background-color: @plans-non-highlighted;
|
|
||||||
margin: @best-val-height 0 15px 0;
|
|
||||||
table-layout: fixed;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
-moz-background-clip: padding;
|
|
||||||
-webkit-background-clip: padding;
|
|
||||||
background-clip: padding-box; /* needed for firefox when there is bg color */
|
|
||||||
border: 1px solid @gray-lighter;
|
|
||||||
padding: 6px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
border-top: 0;
|
|
||||||
font-family: @headings-font-family;
|
|
||||||
font-size: @font-size-h2;
|
|
||||||
font-weight: @headings-font-weight;
|
|
||||||
hyphens: auto;
|
|
||||||
line-height: @headings-line-height;
|
|
||||||
padding: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th:first-child,
|
|
||||||
td:first-child {
|
|
||||||
border-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
th:last-child,
|
|
||||||
td:last-child {
|
|
||||||
border-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
td:first-child {
|
|
||||||
font-weight: bold;
|
|
||||||
padding-left: 18px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:first-child {
|
|
||||||
th {
|
|
||||||
position: relative;
|
|
||||||
/* keep here position here, otherwise messes up border on safari */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:last-child {
|
|
||||||
td {
|
|
||||||
border-bottom: 0;
|
|
||||||
padding: 18px;
|
|
||||||
}
|
|
||||||
td:first-child {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.fa-check {
|
|
||||||
color: @green;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* accessibility fixes */
|
|
||||||
.small {
|
|
||||||
color: @gray-med;
|
|
||||||
}
|
|
||||||
|
|
||||||
.outer {
|
|
||||||
left: -@border-width-base;
|
|
||||||
right: -@border-width-base;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
.outer-content {
|
|
||||||
background: white;
|
|
||||||
border: @border-width-base solid @border-color-base;
|
|
||||||
border-radius: @border-radius-base;
|
|
||||||
font-size: @font-size-base;
|
|
||||||
font-family: @font-family-sans-serif;
|
|
||||||
font-weight: bold;
|
|
||||||
height: @best-val-height;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.outer.outer-top {
|
|
||||||
top: -@best-val-height;
|
|
||||||
.outer-content {
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.outer.outer-btm {
|
|
||||||
bottom: -@best-val-height / 2;
|
|
||||||
.outer-content {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border-top: 0;
|
|
||||||
height: @best-val-height / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: @screen-sm-min) {
|
|
||||||
/* highlight rows on hover */
|
|
||||||
tr:hover {
|
|
||||||
td {
|
|
||||||
background-color: @table-hover-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tr:first-child:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
tr:last-child:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
td {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tooltip */
|
|
||||||
sup {
|
|
||||||
color: @brand-secondary;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
.tooltip.in {
|
|
||||||
min-width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Media Queries */
|
|
||||||
@media (max-width: @screen-sm-max) {
|
|
||||||
font-size: @font-size-small;
|
|
||||||
hyphens: auto;
|
|
||||||
margin-top: @best-val-height*2;
|
|
||||||
th {
|
|
||||||
font-size: @font-size-base;
|
|
||||||
padding-left: @padding-xs;
|
|
||||||
padding-right: @padding-xs;
|
|
||||||
}
|
|
||||||
td:first-child {
|
|
||||||
padding-left: @padding-xs;
|
|
||||||
}
|
|
||||||
tr:last-child {
|
|
||||||
td {
|
|
||||||
padding: @padding-xs;
|
|
||||||
.btn {
|
|
||||||
word-break: normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.best-value {
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.btn {
|
|
||||||
font-size: @font-size-small;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: @screen-xs-max) {
|
|
||||||
tbody,
|
|
||||||
thead {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
tr {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
justify-content: space-around;
|
|
||||||
}
|
|
||||||
th {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
/* hide the first column header */
|
|
||||||
tr:first-child {
|
|
||||||
th:first-child {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* make the first column into a row */
|
|
||||||
td:first-child {
|
|
||||||
text-align: center;
|
|
||||||
background: @gray-lightest;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.plans-table-main {
|
|
||||||
td:nth-child(4),
|
|
||||||
th:nth-child(4) {
|
|
||||||
background-color: white;
|
|
||||||
border-left: @border-width-base solid @border-color-base;
|
|
||||||
border-right: @border-width-base solid @border-color-base;
|
|
||||||
}
|
|
||||||
tr:last-child {
|
|
||||||
/* highlighted column */
|
|
||||||
td:nth-child(4) {
|
|
||||||
position: relative;
|
|
||||||
/* keep here position here, otherwise messes up border on safari when there is a bg color */
|
|
||||||
&:before {
|
|
||||||
/* needed for safafi */
|
|
||||||
border-top: 1px solid @border-color-base;
|
|
||||||
content: '';
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: -1px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: @screen-xs-max) {
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
display: block;
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.plans-table-student {
|
|
||||||
td:nth-child(3),
|
|
||||||
th:nth-child(3) {
|
|
||||||
background-color: white;
|
|
||||||
border-left: @border-width-base solid @border-color-base;
|
|
||||||
border-right: @border-width-base solid @border-color-base;
|
|
||||||
}
|
|
||||||
tr:last-child {
|
|
||||||
/* highlighted column */
|
|
||||||
td:nth-child(3) {
|
|
||||||
position: relative;
|
|
||||||
/* keep here position here, otherwise messes up border on safari when there is a bg color */
|
|
||||||
&:before {
|
|
||||||
/* needed for safafi */
|
|
||||||
border-top: 1px solid @border-color-base;
|
|
||||||
content: '';
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: -1px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media screen and (max-width: @screen-xs-max) {
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
display: block;
|
|
||||||
width: 33.3%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-subscription-modal {
|
.group-subscription-modal {
|
||||||
.modal-header {
|
.modal-header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -80,7 +80,6 @@
|
||||||
"already_have_sl_account": "Already have an __appName__ account?",
|
"already_have_sl_account": "Already have an __appName__ account?",
|
||||||
"also": "Also",
|
"also": "Also",
|
||||||
"also_available_as_on_premises": "Also available as On-Premises",
|
"also_available_as_on_premises": "Also available as On-Premises",
|
||||||
"also_provides_free_plan": "__appName__ also provides a free plan -- simply <0>register here</0> to get started.",
|
|
||||||
"alternatively_create_new_institution_account": "Alternatively, you can create a <b>new account</b> with your institution email (<b>__email__</b>) by clicking <b>__clickText__</b>.",
|
"alternatively_create_new_institution_account": "Alternatively, you can create a <b>new account</b> with your institution email (<b>__email__</b>) by clicking <b>__clickText__</b>.",
|
||||||
"an_error_occurred_when_verifying_the_coupon_code": "An error occurred when verifying the coupon code",
|
"an_error_occurred_when_verifying_the_coupon_code": "An error occurred when verifying the coupon code",
|
||||||
"and": "and",
|
"and": "and",
|
||||||
|
@ -134,7 +133,6 @@
|
||||||
"beta_program_opt_in_action": "Opt-In to Beta Program",
|
"beta_program_opt_in_action": "Opt-In to Beta Program",
|
||||||
"beta_program_opt_out_action": "Opt-Out of Beta Program",
|
"beta_program_opt_out_action": "Opt-Out of Beta Program",
|
||||||
"bibliographies": "Bibliographies",
|
"bibliographies": "Bibliographies",
|
||||||
"billed_after_x_days": "You won’t be billed until after your __len__ day trial expires.",
|
|
||||||
"binary_history_error": "Preview not available for this file type",
|
"binary_history_error": "Preview not available for this file type",
|
||||||
"blank_project": "Blank Project",
|
"blank_project": "Blank Project",
|
||||||
"blocked_filename": "This file name is blocked.",
|
"blocked_filename": "This file name is blocked.",
|
||||||
|
@ -197,7 +195,6 @@
|
||||||
"change_owner": "Change owner",
|
"change_owner": "Change owner",
|
||||||
"change_password": "Change Password",
|
"change_password": "Change Password",
|
||||||
"change_plan": "Change plan",
|
"change_plan": "Change plan",
|
||||||
"change_plans_any_time": "You can change plans or change your account at any time. ",
|
|
||||||
"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.",
|
||||||
"change_project_owner": "Change Project Owner",
|
"change_project_owner": "Change Project Owner",
|
||||||
"change_to_annual_billing_and_save": "Get <0>__percentage__</0> off with annual billing. If you switch now you’ll save <1>__yearlySaving__</1> per year.",
|
"change_to_annual_billing_and_save": "Get <0>__percentage__</0> off with annual billing. If you switch now you’ll save <1>__yearlySaving__</1> per year.",
|
||||||
|
@ -240,7 +237,6 @@
|
||||||
"commons_plan_tooltip": "You’re on the __plan__ plan because of your affiliation with __institution__. Click to find out how to make the most of your Overleaf premium features.",
|
"commons_plan_tooltip": "You’re on the __plan__ plan because of your affiliation with __institution__. Click to find out how to make the most of your Overleaf premium features.",
|
||||||
"compact": "Compact",
|
"compact": "Compact",
|
||||||
"company_name": "Company Name",
|
"company_name": "Company Name",
|
||||||
"compare_plan_features": "Compare Plan Features",
|
|
||||||
"compare_to_another_version": "Compare to another version",
|
"compare_to_another_version": "Compare to another version",
|
||||||
"comparing_x_to_y": "Comparing <0>__startTime__</0> to <0>__endTime__</0>",
|
"comparing_x_to_y": "Comparing <0>__startTime__</0> to <0>__endTime__</0>",
|
||||||
"compile_error_entry_description": "An error which prevented this project from compiling",
|
"compile_error_entry_description": "An error which prevented this project from compiling",
|
||||||
|
@ -344,7 +340,6 @@
|
||||||
"disable_stop_on_first_error": "Disable “Stop on first error”",
|
"disable_stop_on_first_error": "Disable “Stop on first error”",
|
||||||
"disconnected": "Disconnected",
|
"disconnected": "Disconnected",
|
||||||
"discount_of": "Discount of __amount__",
|
"discount_of": "Discount of __amount__",
|
||||||
"discounted_group_accounts": "discounted group accounts",
|
|
||||||
"dismiss": "Dismiss",
|
"dismiss": "Dismiss",
|
||||||
"dismiss_error_popup": "Dismiss first error alert",
|
"dismiss_error_popup": "Dismiss first error alert",
|
||||||
"do_not_have_acct_or_do_not_want_to_link": "If you don’t have an <b>__appName__</b> account, or if you don’t want to link to your <b>__institutionName__</b> account, please click <b>__clickText__</b>.",
|
"do_not_have_acct_or_do_not_want_to_link": "If you don’t have an <b>__appName__</b> account, or if you don’t want to link to your <b>__institutionName__</b> account, please click <b>__clickText__</b>.",
|
||||||
|
@ -445,33 +440,20 @@
|
||||||
"expiry": "Expiry Date",
|
"expiry": "Expiry Date",
|
||||||
"export_csv": "Export CSV",
|
"export_csv": "Export CSV",
|
||||||
"export_project_to_github": "Export Project to GitHub",
|
"export_project_to_github": "Export Project to GitHub",
|
||||||
"faq_change_plans_answer": "Yes, you can change your plan at any time via your subscription settings. This includes options to switch to a different plan, or to switch between monthly and annual billing options, or to cancel to downgrade to the free plan.",
|
|
||||||
"faq_change_plans_or_cancel_answer": "Yes, you can do this at any time via your subscription settings. You can change plans, switch between monthly and annual billing options, or cancel to downgrade to the free plan. When cancelling, your subscription will continue until the end of the billing period. If your account temporarily does not have a subscription, the only change will be to the features available to you. Your projects will always be available on your account.",
|
"faq_change_plans_or_cancel_answer": "Yes, you can do this at any time via your subscription settings. You can change plans, switch between monthly and annual billing options, or cancel to downgrade to the free plan. When cancelling, your subscription will continue until the end of the billing period. If your account temporarily does not have a subscription, the only change will be to the features available to you. Your projects will always be available on your account.",
|
||||||
"faq_change_plans_or_cancel_question": "Can I change plans or cancel later?",
|
"faq_change_plans_or_cancel_question": "Can I change plans or cancel later?",
|
||||||
"faq_change_plans_question": "Can I change plans later?",
|
|
||||||
"faq_do_collab_need_on_paid_plan_answer": "No, they can be on any plan, including the free plan. If you are on a premium plan, some premium features will be available to your collaborators in projects that you have created, even if those collaborators are on the free plan. For more information, read about <0>account and subscriptions</0> and <1>how premium features work</1>.",
|
"faq_do_collab_need_on_paid_plan_answer": "No, they can be on any plan, including the free plan. If you are on a premium plan, some premium features will be available to your collaborators in projects that you have created, even if those collaborators are on the free plan. For more information, read about <0>account and subscriptions</0> and <1>how premium features work</1>.",
|
||||||
"faq_do_collab_need_on_paid_plan_question": "Do my collaborators also need to be on a paid plan?",
|
"faq_do_collab_need_on_paid_plan_question": "Do my collaborators also need to be on a paid plan?",
|
||||||
"faq_do_collab_need_premium_answer": "Premium features, such as tracked changes, will be available to your collaborators on projects that you have created, even if those collaborators have free accounts.",
|
|
||||||
"faq_do_collab_need_premium_question": "Do my collaborators also need premium accounts?",
|
|
||||||
"faq_how_does_a_group_plan_work_answer": "Group subscriptions are a way to upgrade more than one Overleaf account. They are easy to manage, help to save on paperwork, and reduce the cost of purchasing multiple subscriptions separately. To learn more, read about <0>joining a group subscription</0> and <1>managing a group subscription</1>. You can purchase group subscriptions above or by <2>contacting us</2>.",
|
"faq_how_does_a_group_plan_work_answer": "Group subscriptions are a way to upgrade more than one Overleaf account. They are easy to manage, help to save on paperwork, and reduce the cost of purchasing multiple subscriptions separately. To learn more, read about <0>joining a group subscription</0> and <1>managing a group subscription</1>. You can purchase group subscriptions above or by <2>contacting us</2>.",
|
||||||
"faq_how_does_a_group_plan_work_question": "How does a group plan work? How can I add people to the plan?",
|
"faq_how_does_a_group_plan_work_question": "How does a group plan work? How can I add people to the plan?",
|
||||||
"faq_how_does_free_trial_works_answer": "You get full access to your chosen __appName__ plan during your __len__-day free trial. There is no obligation to continue beyond the trial. Your card will be charged at the end of your __len__ day trial unless you cancel before then. You can cancel via your subscription settings.",
|
"faq_how_does_free_trial_works_answer": "You get full access to your chosen __appName__ plan during your __len__-day free trial. There is no obligation to continue beyond the trial. Your card will be charged at the end of your __len__ day trial unless you cancel before then. You can cancel via your subscription settings.",
|
||||||
"faq_how_free_trial_works_answer_v2": "You get full access to your chosen premium plan during your __len__ day free trial, and there is no obligation to continue beyond the trial. Your card will be charged at the end of your trial unless you cancel before then. To cancel, go to your subscription settings in your account (the trial will continue for the full __len__ days).",
|
"faq_how_free_trial_works_answer_v2": "You get full access to your chosen premium plan during your __len__ day free trial, and there is no obligation to continue beyond the trial. Your card will be charged at the end of your trial unless you cancel before then. To cancel, go to your subscription settings in your account (the trial will continue for the full __len__ days).",
|
||||||
"faq_how_free_trial_works_question": "How does the free trial work?",
|
"faq_how_free_trial_works_question": "How does the free trial work?",
|
||||||
"faq_how_to_pay_answer": "Yes, you can. All major credit and debit cards and Paypal are supported. Select the plan you’d like above, and you’ll have the option to pay by card or to go through to PayPal when it’s time to set up payment.",
|
|
||||||
"faq_how_to_pay_question": "Can I pay online with a credit or debit card, or PayPal?",
|
|
||||||
"faq_i_have_free_account_want_subscription_how_answer_first_paragraph": "In Overleaf, every user creates and manages their own Overleaf account. Most users start on the free plan but can upgrade and enjoy the premium features by subscribing to a plan, joining a group subscription or joining a <0>Common subscription</0>. When you purchase, join or leave a subscription, you can still keep the same Overleaf account.",
|
"faq_i_have_free_account_want_subscription_how_answer_first_paragraph": "In Overleaf, every user creates and manages their own Overleaf account. Most users start on the free plan but can upgrade and enjoy the premium features by subscribing to a plan, joining a group subscription or joining a <0>Common subscription</0>. When you purchase, join or leave a subscription, you can still keep the same Overleaf account.",
|
||||||
"faq_i_have_free_account_want_subscription_how_answer_second_paragraph": "To find out more, read more about <0>how accounts and subscriptions work together in Overleaf</0>.",
|
"faq_i_have_free_account_want_subscription_how_answer_second_paragraph": "To find out more, read more about <0>how accounts and subscriptions work together in Overleaf</0>.",
|
||||||
"faq_i_have_free_account_want_subscription_how_question": "I have a free account and want to join a subscription, how do I do that?",
|
"faq_i_have_free_account_want_subscription_how_question": "I have a free account and want to join a subscription, how do I do that?",
|
||||||
"faq_monthly_or_annual_answer": "Annual billing offers a way to cut down on your admin and paperwork. If you’d prefer to manage a single payment every year, instead of twelve, annual billing is for you.",
|
|
||||||
"faq_monthly_or_annual_question": "Should I choose monthly or annual billing?",
|
|
||||||
"faq_need_more_collab_answer": "You can upgrade to one of our paid accounts, which support more collaborators. You can also earn additional collaborators on our free accounts by __referFriendsLink__.",
|
|
||||||
"faq_need_more_collab_question": "What if I need more collaborators?",
|
|
||||||
"faq_pay_by_invoice_answer": "Yes, if you’d like to purchase a group account or site license and would prefer to pay by invoice,\r\nor need to raise a purchase order, please <0>let us know</0>.\r\nFor individual accounts or accounts with monthly billing, we can only accept payment online\r\nvia credit or debit card, or PayPal.",
|
|
||||||
"faq_pay_by_invoice_answer_v2": "Yes, if you’d like to purchase a group subscription for five or more people, or a site license. For individual subscriptions we can only accept payment online via credit card, debit card or PayPal.",
|
"faq_pay_by_invoice_answer_v2": "Yes, if you’d like to purchase a group subscription for five or more people, or a site license. For individual subscriptions we can only accept payment online via credit card, debit card or PayPal.",
|
||||||
"faq_pay_by_invoice_question": "Can I pay by invoice / purchase order?",
|
"faq_pay_by_invoice_question": "Can I pay by invoice / purchase order?",
|
||||||
"faq_purchase_more_licenses_answer": "Yes, we provide __groupLink__, which are easy to manage, help to save on paperwork, and reduce the cost of purchasing multiple licenses.",
|
|
||||||
"faq_purchase_more_licenses_question": "Can I purchase additional licenses for my colleagues?",
|
|
||||||
"faq_the_individual_standard_plan_10_collab_first_paragraph": "No. Only the subscriber’s account will be upgraded. An individual Standard subscription allows you to invite 10 collaborators to each project owned by you.",
|
"faq_the_individual_standard_plan_10_collab_first_paragraph": "No. Only the subscriber’s account will be upgraded. An individual Standard subscription allows you to invite 10 collaborators to each project owned by you.",
|
||||||
"faq_the_individual_standard_plan_10_collab_question": "The individual Standard plan has 10 project collaborators, does it mean that 10 people will be upgraded?",
|
"faq_the_individual_standard_plan_10_collab_question": "The individual Standard plan has 10 project collaborators, does it mean that 10 people will be upgraded?",
|
||||||
"faq_the_individual_standard_plan_10_collab_second_paragraph": "While working on a project that you, as a subscriber, share with them, your collaborators will be able to access some premium features such as the full document history and extended compile time for that particular project. Inviting them to a particular project does not upgrade their accounts overall, however. Read more about <0>which features are per project, and which are per account</0>.",
|
"faq_the_individual_standard_plan_10_collab_second_paragraph": "While working on a project that you, as a subscriber, share with them, your collaborators will be able to access some premium features such as the full document history and extended compile time for that particular project. Inviting them to a particular project does not upgrade their accounts overall, however. Read more about <0>which features are per project, and which are per account</0>.",
|
||||||
|
@ -584,10 +566,7 @@
|
||||||
"generic_linked_file_compile_error": "This project’s output files are not available because it failed to compile. Please open the project to see the compilation error details.",
|
"generic_linked_file_compile_error": "This project’s output files are not available because it failed to compile. Please open the project to see the compilation error details.",
|
||||||
"generic_something_went_wrong": "Sorry, something went wrong",
|
"generic_something_went_wrong": "Sorry, something went wrong",
|
||||||
"get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline",
|
"get_collaborative_benefits": "Get the collaborative benefits from __appName__, even if you prefer to work offline",
|
||||||
"get_in_touch": "Get in touch",
|
|
||||||
"get_in_touch_for_details": "Get in touch for details!",
|
|
||||||
"get_in_touch_having_problems": "<a href=\"__link__\">Get in touch with support</a> if you’re having problems",
|
"get_in_touch_having_problems": "<a href=\"__link__\">Get in touch with support</a> if you’re having problems",
|
||||||
"get_instant_access_to": "Get instant access to",
|
|
||||||
"get_involved": "Get involved",
|
"get_involved": "Get involved",
|
||||||
"get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__’s features</0>.",
|
"get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__’s features</0>.",
|
||||||
"get_most_subscription_by_checking_premium_features": "Get the most out of your __appName__ subscription by checking out the list of <0>__appName__’s premium features</0>.",
|
"get_most_subscription_by_checking_premium_features": "Get the most out of your __appName__ subscription by checking out the list of <0>__appName__’s premium features</0>.",
|
||||||
|
@ -1220,7 +1199,6 @@
|
||||||
"reference_sync": "Reference manager sync",
|
"reference_sync": "Reference manager sync",
|
||||||
"reference_sync_info": "Manage your reference library in Mendeley or Zotero and link it directly to a .bib file in Overleaf, so you can easily cite anything in your library.",
|
"reference_sync_info": "Manage your reference library in Mendeley or Zotero and link it directly to a .bib file in Overleaf, so you can easily cite anything in your library.",
|
||||||
"references_search_hint": "Press CTRL-Space to Search",
|
"references_search_hint": "Press CTRL-Space to Search",
|
||||||
"referring_your_friends": "referring your friends",
|
|
||||||
"refresh": "Refresh",
|
"refresh": "Refresh",
|
||||||
"refresh_page_after_linking_dropbox": "Please refresh this page after linking your account to Dropbox.",
|
"refresh_page_after_linking_dropbox": "Please refresh this page after linking your account to Dropbox.",
|
||||||
"refresh_page_after_starting_free_trial": "Please refresh this page after starting your free trial.",
|
"refresh_page_after_starting_free_trial": "Please refresh this page after starting your free trial.",
|
||||||
|
@ -1327,7 +1305,6 @@
|
||||||
"select_all": "Select all",
|
"select_all": "Select all",
|
||||||
"select_all_projects": "Select all projects",
|
"select_all_projects": "Select all projects",
|
||||||
"select_an_output_file": "Select an Output File",
|
"select_an_output_file": "Select an Output File",
|
||||||
"select_country_vat": "Please select your country on the payment page to view the total price including any VAT.",
|
|
||||||
"select_from_output_files": "select from output files",
|
"select_from_output_files": "select from output files",
|
||||||
"select_from_source_files": "select from source files",
|
"select_from_source_files": "select from source files",
|
||||||
"select_github_repository": "Select a GitHub repository to import into __appName__.",
|
"select_github_repository": "Select a GitHub repository to import into __appName__.",
|
||||||
|
@ -1383,7 +1360,6 @@
|
||||||
"sitewide_option_available_info": "Users are automatically upgraded when they register or add their email address to Overleaf (domain-based enrollment or SSO).",
|
"sitewide_option_available_info": "Users are automatically upgraded when they register or add their email address to Overleaf (domain-based enrollment or SSO).",
|
||||||
"skip": "Skip",
|
"skip": "Skip",
|
||||||
"skip_to_content": "Skip to content",
|
"skip_to_content": "Skip to content",
|
||||||
"sl_benefits_plans": "__appName__ is the world’s easiest to use LaTeX editor. Stay up to date with your collaborators, keep track of all changes to your work, and use our LaTeX environment from anywhere in the world.",
|
|
||||||
"sl_gives_you_free_stuff_see_progress_below": "When someone starts using __appName__ after your recommendation we’ll give you some <strong>free stuff</strong> to say thanks! Check your progress below.",
|
"sl_gives_you_free_stuff_see_progress_below": "When someone starts using __appName__ after your recommendation we’ll give you some <strong>free stuff</strong> to say thanks! Check your progress below.",
|
||||||
"sl_included_history_of_changes_blurb": "__appName__ includes a history of all of your changes so you can see exactly who changed what, and when. This makes it extremely easy to keep up to date with any progress made by your collaborators and allows you to review recent work.",
|
"sl_included_history_of_changes_blurb": "__appName__ includes a history of all of your changes so you can see exactly who changed what, and when. This makes it extremely easy to keep up to date with any progress made by your collaborators and allows you to review recent work.",
|
||||||
"something_went_wrong_canceling_your_subscription": "Something went wrong canceling your subscription. Please contact support.",
|
"something_went_wrong_canceling_your_subscription": "Something went wrong canceling your subscription. Please contact support.",
|
||||||
|
|
|
@ -177,7 +177,7 @@ describe('SubscriptionController', function () {
|
||||||
describe('groupPlanModal data', function () {
|
describe('groupPlanModal data', function () {
|
||||||
it('should pass local currency if valid', function (done) {
|
it('should pass local currency if valid', function (done) {
|
||||||
this.res.render = (page, opts) => {
|
this.res.render = (page, opts) => {
|
||||||
page.should.equal('subscriptions/plans-marketing')
|
page.should.equal('subscriptions/plans-marketing-v2')
|
||||||
opts.groupPlanModalDefaults.currency.should.equal('GBP')
|
opts.groupPlanModalDefaults.currency.should.equal('GBP')
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ describe('SubscriptionController', function () {
|
||||||
|
|
||||||
it('should fallback to USD when valid', function (done) {
|
it('should fallback to USD when valid', function (done) {
|
||||||
this.res.render = (page, opts) => {
|
this.res.render = (page, opts) => {
|
||||||
page.should.equal('subscriptions/plans-marketing')
|
page.should.equal('subscriptions/plans-marketing-v2')
|
||||||
opts.groupPlanModalDefaults.currency.should.equal('USD')
|
opts.groupPlanModalDefaults.currency.should.equal('USD')
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ describe('SubscriptionController', function () {
|
||||||
|
|
||||||
it('should pass valid options for group plan modal and discard invalid', function (done) {
|
it('should pass valid options for group plan modal and discard invalid', function (done) {
|
||||||
this.res.render = (page, opts) => {
|
this.res.render = (page, opts) => {
|
||||||
page.should.equal('subscriptions/plans-marketing')
|
page.should.equal('subscriptions/plans-marketing-v2')
|
||||||
opts.groupPlanModalDefaults.size.should.equal('42')
|
opts.groupPlanModalDefaults.size.should.equal('42')
|
||||||
opts.groupPlanModalDefaults.plan_code.should.equal('collaborator')
|
opts.groupPlanModalDefaults.plan_code.should.equal('collaborator')
|
||||||
opts.groupPlanModalDefaults.currency.should.equal('GBP')
|
opts.groupPlanModalDefaults.currency.should.equal('GBP')
|
||||||
|
|
Loading…
Reference in a new issue