overleaf/services/web/app/views/subscriptions/plans/light-redesign/_mixins.pug
Jessica Lawshe 214f093eb7 Merge pull request #19749 from overleaf/jel-fix-first-feature-row-border
[web] Fix first feature row border radius on light touch plans redesign

GitOrigin-RevId: 2ef5b1cbb13284a95d6c5d9370cd003f4ccf7f48
2024-08-13 08:04:29 +00:00

403 lines
16 KiB
Text

include ./_table_ctas
include ./_table_short_feature_lists
include ./_table_column_headers_row
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 #{formatCurrency(settings.localizedPlanPricing[recommendedCurrency][plan][view], recommendedCurrency, language, true)}
mixin currency_and_payment_methods()
.row.plans-payment-methods.text-centered
.col-xs-12
p
| #{translate("all_prices_displayed_are_in_currency", { recommendedCurrency })}
| #{translate("subject_to_additional_vat")}
.plans-payment-methods-icons
img(src=buildImgPath('/other-brands/logo_mastercard.svg') aria-hidden="true")
span.sr-only #{translate('payment_method_accepted', { paymentMethod: 'Mastercard' })}
img(src=buildImgPath('/other-brands/logo_visa.svg') aria-hidden="true")
span.sr-only #{translate('payment_method_accepted', { paymentMethod: 'Visa' })}
img(src=buildImgPath('/other-brands/logo_amex.svg') aria-hidden="true")
span.sr-only #{translate('payment_method_accepted', { paymentMethod: 'Amex' })}
img(src=buildImgPath('/other-brands/logo_paypal.svg') aria-hidden="true")
span.sr-only #{translate('payment_method_accepted', { paymentMethod: 'Paypal' })}
mixin plans_table(period, config)
- var maxColumn = config.maxColumn || 4
- var tableHeadKeys = Object.keys(config.tableHead)
- var highlightedColKey = tableHeadKeys[config.highlightedColumn.index]
-var highlightedColTranslationKey = config.highlightedColumn.text[period] === 'most_popular' ? 'most_popular_uppercase' : config.highlightedColumn.text[period] === 'saving_20_percent' ? 'saving_20_percent_no_exclamation' : config.highlightedColumn.text[period]
+table_column_headers_row({maxColumn, tableHeadKeys, highlightedColKey, highlightedColTranslationKey})
tr(class=`plans-table-price-row plans-table-cols-${tableHeadKeys.length}`)
td
- for (const [tableHeadKey] of Object.entries(config.tableHead))
- var highlighted = highlightedColKey === tableHeadKey
- var eventTrackingKey = config.eventTrackingKey
- var additionalEventSegmentation = config.additionalEventSegmentation || {}
- var tdClass = highlighted ? 'plans-table-green-highlighted' : ''
td(class=tdClass)
.plans-table-cell.plans-table-cell-price
case tableHeadKey
when 'individual_free'
+table_head_price('free', period)
when 'individual_collaborator'
+table_head_price('collaborator', period)
when 'individual_professional'
+table_head_price('professional', period)
when 'group_collaborator'
+table_price_group_collaborator()
when 'group_professional'
+table_price_group_professional()
when 'group_organization'
.plans-table-comments-icon
.match-non-discounted-price-alignment  
i.material-symbols.material-symbols-outlined(aria-hidden="true") forum
when 'student_free'
+table_head_price('free', period)
when 'student_student'
+table_head_price('student', period)
tr(class=`plans-table-cta-mobile plans-table-cols-${tableHeadKeys.length}`)
td
- for (const [tableHeadKey] of Object.entries(config.tableHead))
- var highlighted = highlightedColKey === tableHeadKey
- var eventTrackingKey = config.eventTrackingKey
- var additionalEventSegmentation = config.additionalEventSegmentation || {}
- var tdClass = highlighted ? 'plans-table-green-highlighted' : ''
td(class=tdClass)
.plans-table-cell.plans-table-cell-cta-mobile
.plans-table-btn-buy-container-mobile
+plans_cta(tableHeadKey, highlighted, eventTrackingKey, additionalEventSegmentation, period)
tr(class=`plans-table-short-feature-list plans-table-cols-${tableHeadKeys.length}`)
td
- for (const [tableHeadKey, tableHeadOptions] of Object.entries(config.tableHead))
- var highlighted = highlightedColKey === tableHeadKey
- var eventTrackingKey = config.eventTrackingKey
- var additionalEventSegmentation = config.additionalEventSegmentation || {}
- var tdClass = highlighted ? 'plans-table-green-highlighted' : ''
td(class=tdClass)
.plans-table-cell.plans-table-cell-short-feature-list
div
case tableHeadKey
when 'individual_free'
+table_short_feature_list_free()
when 'individual_collaborator'
+table_short_feature_list_collaborator()
when 'individual_professional'
+table_short_feature_list_professional()
when 'group_collaborator'
+table_short_feature_list_group_collaborator()
when 'group_professional'
+table_short_feature_list_group_professional()
when 'group_organization'
+table_short_feature_list_group_organization(additionalEventSegmentation)
when 'student_free'
+table_short_feature_list_free()
when 'student_student'
+table_short_feature_list_student_student(tableHeadOptions.showExtraContent)
tr(class=`plans-table-cta-desktop plans-table-cols-${tableHeadKeys.length}`)
td
- for (const [tableHeadKey] of Object.entries(config.tableHead))
- var highlighted = highlightedColKey === tableHeadKey
- var eventTrackingKey = config.eventTrackingKey
- var additionalEventSegmentation = config.additionalEventSegmentation || {}
- var tdClass = highlighted ? 'plans-table-green-highlighted' : ''
td(class=tdClass)
.plans-table-cell.plans-table-cell-cta-desktop
.plans-table-btn-buy-container-desktop
+plans_cta(tableHeadKey, highlighted, eventTrackingKey, additionalEventSegmentation, period)
for featuresPerSection, featuresSectionIndex in config.features
- var dividerColspan = Object.values(config.tableHead).length + 1
if featuresPerSection.divider
tr.plans-table-divider
td(
colspan=dividerColspan
class=((config.highlightedColumn.index === Object.keys(config.tableHead).length - 1) ? 'plans-table-last-col-highlighted' : '')
)
.plans-table-cell-divider
//- all cells need 2 layers of divs for handling border and padding. See .plans-table in CSS for more details
.plans-table-cell-divider-content
b.plans-table-divider-label #{translate(featuresPerSection.dividerLabel)}
//- will only appear on screen width >= 768px (using CSS)
i.material-symbols.material-symbols-outlined.icon-sm(
data-toggle="tooltip"
title=translate(featuresPerSection.dividerInfo),
data-placement="top"
) help
//- will only appear on screen width < 768px (using CSS)
span.plans-table-divider-learn-more-container
span (
span.plans-table-divider-learn-more-text(
data-toggle="tooltip"
title=translate(featuresPerSection.dividerInfo),
data-placement="top"
) #{translate("learn_more_lowercase")}
span )
span.sr-only #{translate(featuresPerSection.dividerInfo)}
for feature, featureIndex in featuresPerSection.items
tr(
class=`plans-table-feature-row plans-table-cols-${tableHeadKeys.length}`
)
th(
event-tracking="plans-page-table"
event-tracking-trigger="hover"
event-tracking-ga="subscription-funnel"
event-tracking-label=`${feature.feature}`
scope="row"
class=`${featuresSectionIndex === 0 && featureIndex === 0 ? 'plans-table-first-feature-header' : ''}`
)
.plans-table-feature-name
.plans-table-feature-name-content
if feature.info
span #{translate(feature.feature)}
//- will only appear on screen width >= 768px (using CSS)
i.material-symbols.material-symbols-outlined.icon-sm.plans-table-feature-question-icon(
data-toggle="tooltip"
title=translate(feature.info),
data-placement="right"
) help
//- will only appear on screen width < 768px (using CSS)
span.plans-table-feature-learn-more-container
span (
span.plans-table-feature-learn-more-text(
data-toggle="tooltip"
title=translate(feature.info),
data-placement="top"
) #{translate("learn_more_lowercase")}
span )
span.sr-only #{translate(feature.info)}
else
| #{translate(feature.feature)}
for plan, planIndex in Object.keys(feature.plans)
- var tableHeadOptions = Object.values(config.tableHead)[planIndex] || {}
- var tdClass = planIndex === config.highlightedColumn.index ? 'plans-table-green-highlighted' : ''
td(class=tdClass)
+table_cell(feature, plan)
mixin table_individual(period)
table.plans-table.plans-table-individual
+plans_table(period, plansConfig.individual)
mixin table_group
table.plans-table.plans-table-group
+plans_table('annual', plansConfig.group)
mixin table_student(period)
table.plans-table.plans-table-student
+plans_table(period, plansConfig.student)
//- group mixins
mixin table_price_group_collaborator()
.plans-table-price-container
s
+gen_localized_price_for_plan_view('collaborator', 'annual')
p.plans-table-price
span(data-ol-plans-v2-group-price-per-user='collaborator') #{initialLocalizedGroupPrice.pricePerUser.collaborator}
p.plans-table-price-period-label
| #{translate('per_user_year')}
mixin table_price_group_professional()
.plans-table-price-container
s
+gen_localized_price_for_plan_view('professional', 'annual')
p.plans-table-price
span(data-ol-plans-v2-group-price-per-user='professional') #{initialLocalizedGroupPrice.pricePerUser.professional}
p.plans-table-price-period-label
| #{translate('per_user_year')}
mixin table_head_group_total_per_year(groupPlan)
- var initialLicenseSize = '2'
span.plans-group-total-price(data-ol-plans-v2-group-total-price=groupPlan) #{initialLocalizedGroupPrice.price[groupPlan]}
| &nbsp;
for licenseSize in groupPlanModalOptions.sizes
span(
hidden=(licenseSize !== initialLicenseSize)
data-ol-plans-v2-table-th-group-license-size=licenseSize
) !{translate("total_per_year_for_x_users", {licenseSize})}
mixin group_plans_license_picker()
form.plans-license-picker-form(data-ol-plans-v2-license-picker-form)
.plans-license-picker-select-container
span #{translate("number_of_users_with_colon")}
select(
name="plans-v2-license-picker-select"
id="plans-v2-license-picker-select"
autocomplete="off"
data-ol-plans-v2-license-picker-select
event-tracking="plans-page-group-size"
event-tracking-mb="true"
event-tracking-trigger="click"
event-tracking-element="select"
)
option(value="2") 2
option(value="3") 3
option(value="4") 4
option(value="5") 5
option(value="10") 10
option(value="20") 20
option(value="50") 50
.plans-v2-license-picker-educational-discount
label(data-ol-plans-v2-license-picker-educational-discount-label)
input.plans-v2-license-picker-educational-discount-checkbox(
type="checkbox"
id="license-picker-educational-discount"
autocomplete="off"
data-ol-plans-v2-license-picker-educational-discount-input
event-tracking="plans-page-edu-discount"
event-tracking-mb="true"
event-tracking-trigger="click"
event-tracking-element="checkbox"
)
span #{translate("apply_educational_discount")}
//- will only appear on screen width >= 768px (using CSS)
i.material-symbols.material-symbols-outlined.icon-sm(
data-toggle="tooltip"
title=translate("apply_educational_discount_info"),
data-placement="bottom"
) help
//- will only appear on screen width < 768px (using CSS)
span.plans-v2-license-picker-educational-discount-learn-more-container
span (
span.plans-v2-license-picker-educational-discount-learn-more-text(
data-toggle="tooltip"
title=translate("apply_educational_discount_info"),
data-placement="bottom"
) #{translate("learn_more_lowercase")}
span )
span.sr-only #{translate("apply_educational_discount_info")}
//- all plans mixins
mixin table_head_price(plan, period)
div.plans-table-price-container
if plan !== 'free' && period === 'annual'
s
+gen_localized_price_for_plan_view(plan, 'monthlyTimesTwelve')
else
.match-non-discounted-price-alignment &nbsp;
p.plans-table-price
+gen_localized_price_for_plan_view(plan, period)
p.plans-table-price-period-label
if period == 'annual'
| #{translate("per_year")}
else
| #{translate("per_month")}
mixin table_cell(feature, plan)
- var planValue = feature.plans[plan]
- var featureName = feature.feature
.plans-table-cell
.plans-table-cell-content(
data-ol-plans-v2-table-cell-plan=plan
data-ol-plans-v2-table-cell-feature=featureName
)
if (feature.value === 'str')
| !{translate(planValue, {}, ['strong'])}
else if (feature.value === 'bool')
if (planValue)
i.material-symbols.material-symbols-outlined.icon-green-round-background.icon-sm(aria-hidden="true") check
span.sr-only #{translate("feature_included")}
else
span(aria-hidden="true") -
span.sr-only #{translate("feature_not_included")}
//- table header and control mixins
mixin plans_table_sticky_header(withSwitch, config)
- var tableHeadKeys = Object.keys(config.tableHead)
.row.plans-table-sticky-header.sticky(
data-ol-plans-v2-table-sticky-header
class=(withSwitch ? 'plans-table-sticky-header-with-switch' : 'plans-table-sticky-header-without-switch')
)
- for (var i = 0; i < tableHeadKeys.length; i++)
- var tableHeadKey = tableHeadKeys[i]
- var translateKey = tableHeadKey.split('_')[1]
-
if (config.highlightedColumn.index === i) {
var elClass = 'plans-table-sticky-header-item-green-highlighted'
} else {
var elClass = ''
}
.plans-table-sticky-header-item(
class=elClass
)
case tableHeadKey
when 'individual_collaborator'
span #{translate('standard')}
when 'group_professional'
span #{translate(tableHeadKey)}
when 'group_collaborator'
span #{translate('group_standard')}
default
span #{translate(translateKey)}
mixin table_sticky_header_all(plansConfig)
.row.plans-table-sticky-header-container(
data-ol-plans-v2-view='individual'
)
+plans_table_sticky_header(true, plansConfig.individual)
.row.plans-table-sticky-header-container(
hidden
data-ol-plans-v2-view='group'
)
+plans_table_sticky_header(false, plansConfig.group)
.row.plans-table-sticky-header-container(
hidden
data-ol-plans-v2-view='student'
)
+plans_table_sticky_header(true, plansConfig.student)
mixin monthly_annual_switch(initialState, eventTracking, eventSegmentation)
- var monthlyAnnualToggleChecked = initialState === 'monthly'
.row
.col-md-4.col-md-offset-4.text-centered.monthly-annual-switch(data-ol-plans-v2-m-a-switch-container)
.monthly-annual-switch-text
span.underline(data-ol-plans-v2-m-a-switch-text='annual') #{translate("annual")}
.tooltip.in.left(
role="tooltip"
data-ol-plans-v2-m-a-tooltip
class=monthlyAnnualToggleChecked ? 'plans-v2-m-a-tooltip-monthly-selected' : ''
)
.tooltip-arrow
.tooltip-inner
span(hidden=!monthlyAnnualToggleChecked data-ol-tooltip-period='monthly') #{translate("save_20_percent_by_paying_annually")}
span(hidden=monthlyAnnualToggleChecked data-ol-tooltip-period='annual') #{translate("saving_20_percent")}
label(data-ol-plans-v2-m-a-switch)
input(
type="checkbox"
checked=monthlyAnnualToggleChecked
role="switch"
aria-label=translate("select_monthly_plans")
autocomplete="off"
event-tracking=eventTracking
event-tracking-mb="true"
event-tracking-trigger="click"
event-tracking-element="checkbox"
event-segmentation=eventSegmentation
)
span
span(data-ol-plans-v2-m-a-switch-text='monthly') #{translate("monthly")}