mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
[web] Extract reusable table mixin on plans page v2 tables (#8262)
GitOrigin-RevId: 7d8dcff5fd3f0c450de6cca57b428759d44dec7d
This commit is contained in:
parent
4f127f8408
commit
b12c108522
5 changed files with 284 additions and 324 deletions
|
@ -9,7 +9,7 @@ const logger = require('@overleaf/logger')
|
|||
const GeoIpLookup = require('../../infrastructure/GeoIpLookup')
|
||||
const FeaturesUpdater = require('./FeaturesUpdater')
|
||||
const planFeatures = require('./planFeatures')
|
||||
const planFeaturesV2 = require('./planFeaturesV2')
|
||||
const plansV2Config = require('./plansV2Config')
|
||||
const GroupPlansData = require('./GroupPlansData')
|
||||
const V1SubscriptionManager = require('./V1SubscriptionManager')
|
||||
const Errors = require('../Errors/Errors')
|
||||
|
@ -89,7 +89,8 @@ async function plansPage(req, res) {
|
|||
plans,
|
||||
itm_content: req.query && req.query.itm_content,
|
||||
recommendedCurrency,
|
||||
planFeatures: newPlansPageVariantV2 ? planFeaturesV2 : planFeatures,
|
||||
planFeatures,
|
||||
plansV2Config,
|
||||
groupPlans: GroupPlansData,
|
||||
groupPlanModalOptions,
|
||||
groupPlanModalDefaults,
|
||||
|
|
47
services/web/app/src/Features/Subscription/plansV2Config.js
Normal file
47
services/web/app/src/Features/Subscription/plansV2Config.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
const plansV2Features = require('./plansV2Features')
|
||||
|
||||
const config = {
|
||||
individual: {
|
||||
tableHead: [
|
||||
'individual_free',
|
||||
'individual_personal',
|
||||
'individual_collaborator',
|
||||
'individual_professional',
|
||||
],
|
||||
features: plansV2Features.individual,
|
||||
highlightedColumn: {
|
||||
index: 2,
|
||||
text: {
|
||||
monthly: 'MOST POPULAR',
|
||||
annual: 'MOST POPULAR',
|
||||
},
|
||||
},
|
||||
},
|
||||
group: {
|
||||
tableHead: [
|
||||
'group_collaborator',
|
||||
'group_professional',
|
||||
'group_organization',
|
||||
],
|
||||
features: plansV2Features.group,
|
||||
highlightedColumn: {
|
||||
index: 1,
|
||||
text: {
|
||||
annual: 'RECOMMENDED',
|
||||
},
|
||||
},
|
||||
},
|
||||
student: {
|
||||
tableHead: ['student_free', 'student_student', 'student_university'],
|
||||
features: plansV2Features.student,
|
||||
highlightedColumn: {
|
||||
index: 1,
|
||||
text: {
|
||||
monthly: 'SAVE 20% ON ANNUAL PLAN',
|
||||
annual: 'SAVING 20%',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = config
|
|
@ -1,63 +1,44 @@
|
|||
mixin table_individual(period)
|
||||
table.card.plans-v2-table.plans-v2-table-individual
|
||||
mixin plans_v2_table(period, config)
|
||||
tr
|
||||
th
|
||||
th
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("free")}
|
||||
+table_head_price('free', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_free()
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li #{translate("one_collaborator")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_free()
|
||||
th.plans-v2-table-cell-before-highlighted-column
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("personal")}
|
||||
+table_head_price('personal', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_personal(period)
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li #{translate("one_collaborator")}
|
||||
li #{translate("most_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_personal(period)
|
||||
th.plans-v2-table-green-highlighted
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-green-highlighted-text MOST POPULAR
|
||||
p.plans-v2-table-th-content-title #{translate("standard")}
|
||||
+table_head_price('collaborator', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_collaborator(period)
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})}
|
||||
li #{translate("all_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_collaborator(period)
|
||||
- for (var i = 0; i < 4; i++)
|
||||
th(
|
||||
class=(i === config.highlightedColumn.index ? 'plans-v2-table-green-highlighted' : (i === config.highlightedColumn.index - 1 ? 'plans-v2-table-cell-before-highlighted-column' : ''))
|
||||
)
|
||||
if (i === config.highlightedColumn.index)
|
||||
p.plans-v2-table-green-highlighted-text !{config.highlightedColumn.text[period]}
|
||||
case config.tableHead[i]
|
||||
when 'individual_free'
|
||||
+table_head_individual_free(period)
|
||||
when 'individual_personal'
|
||||
+table_head_individual_personal(period)
|
||||
when 'individual_collaborator'
|
||||
+table_head_individual_collaborator(period)
|
||||
when 'individual_professional'
|
||||
+table_head_individual_professional(period)
|
||||
when 'group_collaborator'
|
||||
+table_head_group_collaborator()
|
||||
when 'group_professional'
|
||||
+table_head_group_professional()
|
||||
when 'group_organization'
|
||||
+table_head_group_organization()
|
||||
when 'student_free'
|
||||
+table_head_student_free(period)
|
||||
when 'student_student'
|
||||
+table_head_student_student(period)
|
||||
when 'student_university'
|
||||
+table_head_student_university(period)
|
||||
|
||||
th
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("professional")}
|
||||
+table_head_price('professional', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_professional(period)
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li #{translate("unlimited_collabs")}
|
||||
li #{translate("all_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_professional(period)
|
||||
|
||||
for planFeaturesPerSection in planFeatures.individual
|
||||
if planFeaturesPerSection.divider
|
||||
for featuresPerSection in config.features
|
||||
if featuresPerSection.divider
|
||||
tr.plans-v2-table-divider
|
||||
td(colspan="5")
|
||||
td(colspan=config.tableHead.length + 1)
|
||||
div
|
||||
b.plans-v2-table-divider-label #{translate(planFeaturesPerSection.dividerLabel)}
|
||||
b.plans-v2-table-divider-label #{translate(featuresPerSection.dividerLabel)}
|
||||
//- will only appear on screen width >= 768px (using CSS)
|
||||
i.fa.fa-question-circle.plans-v2-table-divider-question-icon(
|
||||
data-toggle="tooltip"
|
||||
title=translate(planFeaturesPerSection.dividerInfo),
|
||||
title=translate(featuresPerSection.dividerInfo),
|
||||
data-placement="top"
|
||||
)
|
||||
//- will only appear on screen width < 768px (using CSS)
|
||||
|
@ -65,13 +46,13 @@ mixin table_individual(period)
|
|||
span (
|
||||
span.plans-v2-table-divider-learn-more-text(
|
||||
data-toggle="tooltip"
|
||||
title=translate(planFeaturesPerSection.dividerInfo),
|
||||
title=translate(featuresPerSection.dividerInfo),
|
||||
data-placement="top"
|
||||
) #{translate("learn_more_lowercase")}
|
||||
span )
|
||||
for feature, featureIndex in planFeaturesPerSection.items
|
||||
for feature, featureIndex in featuresPerSection.items
|
||||
tr(
|
||||
class=(featureIndex === (planFeaturesPerSection.items.length - 1) ? 'plans-v2-table-row-last-row-per-section' : '')
|
||||
class=(featureIndex === (featuresPerSection.items.length - 1) ? 'plans-v2-table-row-last-row-per-section' : '')
|
||||
)
|
||||
td(event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
|
||||
.plans-v2-table-feature-name
|
||||
|
@ -94,23 +75,75 @@ mixin table_individual(period)
|
|||
span )
|
||||
else
|
||||
| #{translate(feature.feature)}
|
||||
td(ng-non-bindable)
|
||||
+table_cell(feature, 'free')
|
||||
td.plans-v2-table-cell-before-highlighted-column(ng-non-bindable)
|
||||
+table_cell(feature, 'personal')
|
||||
td.plans-v2-table-green-highlighted(ng-non-bindable)
|
||||
+table_cell(feature, 'collaborator')
|
||||
td(ng-non-bindable)
|
||||
+table_cell(feature, 'professional')
|
||||
for plan, planIndex in Object.keys(feature.plans)
|
||||
td(
|
||||
class=(planIndex === config.highlightedColumn.index ? 'plans-v2-table-green-highlighted' : (planIndex === config.highlightedColumn.index - 1 ? 'plans-v2-table-cell-before-highlighted-column' : ''))
|
||||
)
|
||||
+table_cell(feature, plan)
|
||||
|
||||
mixin table_individual(period)
|
||||
table.card.plans-v2-table.plans-v2-table-individual
|
||||
+plans_v2_table(period, plansV2Config.individual)
|
||||
|
||||
mixin table_group
|
||||
table.card.plans-v2-table.plans-v2-table-group
|
||||
tr
|
||||
th
|
||||
th.plans-v2-table-cell-before-highlighted-column
|
||||
div.plans-v2-table-th-content
|
||||
+plans_v2_table('annual', plansV2Config.group)
|
||||
|
||||
mixin table_student(period)
|
||||
table.card.plans-v2-table.plans-v2-table-student
|
||||
+plans_v2_table(period, plansV2Config.student)
|
||||
|
||||
mixin table_head_individual_free(period)
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("free")}
|
||||
+table_head_price('free', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_free()
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li #{translate("one_collaborator")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_free()
|
||||
|
||||
mixin table_head_individual_personal(period)
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("personal")}
|
||||
+table_head_price('personal', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_personal(period)
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li #{translate("one_collaborator")}
|
||||
li #{translate("most_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_personal(period)
|
||||
|
||||
mixin table_head_individual_collaborator(period)
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("standard")}
|
||||
+table_head_price('collaborator', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_collaborator(period)
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li !{translate("x_collaborators_per_project", {collaboratorsCount: '10'})}
|
||||
li #{translate("all_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_collaborator(period)
|
||||
|
||||
mixin table_head_individual_professional(period)
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("professional")}
|
||||
+table_head_price('professional', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_individual_professional(period)
|
||||
ul.plans-v2-table-th-content-benefit
|
||||
li #{translate("unlimited_collabs")}
|
||||
li #{translate("all_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_individual_professional(period)
|
||||
|
||||
mixin table_head_group_collaborator()
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("group_standard")}
|
||||
div.plans-v2-table-price-container
|
||||
.plans-v2-table-price-container
|
||||
strike.plans-v2-table-annual-price-before-discount(data-ol-plans-v2-table-annual-price-before-discount)
|
||||
+gen_localized_price_for_plan_view('collaborator', 'annual')
|
||||
p.plans-v2-table-price
|
||||
|
@ -129,11 +162,10 @@ mixin table_group
|
|||
+btn_buy_group_collaborator()
|
||||
+additional_link_group('group_collaborator')
|
||||
|
||||
th.plans-v2-table-green-highlighted
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-green-highlighted-text RECOMMENDED
|
||||
mixin table_head_group_professional()
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("group_professional")}
|
||||
div.plans-v2-table-price-container
|
||||
.plans-v2-table-price-container
|
||||
strike.plans-v2-table-annual-price-before-discount(data-ol-plans-v2-table-annual-price-before-discount)
|
||||
+gen_localized_price_for_plan_view('professional', 'annual')
|
||||
p.plans-v2-table-price
|
||||
|
@ -152,10 +184,11 @@ mixin table_group
|
|||
+btn_buy_group_professional()
|
||||
+additional_link_group('group_professional')
|
||||
|
||||
th
|
||||
div.plans-v2-table-th-content
|
||||
|
||||
mixin table_head_group_organization()
|
||||
.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("organization")}
|
||||
div.plans-v2-table-comments-icon
|
||||
.plans-v2-table-comments-icon
|
||||
i.fa.fa-comments-o
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
+btn_buy_group_organization()
|
||||
|
@ -175,68 +208,8 @@ mixin table_group
|
|||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_group_organization()
|
||||
small.plans-v2-table-th-content-additional-link.invisible(aria-hidden="true")
|
||||
th
|
||||
|
||||
for planFeaturesPerSection in planFeatures.group
|
||||
if planFeaturesPerSection.divider
|
||||
tr.plans-v2-table-divider
|
||||
td(colspan="4")
|
||||
div
|
||||
b.plans-v2-table-divider-label #{translate(planFeaturesPerSection.dividerLabel)}
|
||||
//- will only appear on screen width >= 768px (using CSS)
|
||||
i.fa.fa-question-circle.plans-v2-table-divider-question-icon(
|
||||
data-toggle="tooltip"
|
||||
title=translate(planFeaturesPerSection.dividerInfo),
|
||||
data-placement="top"
|
||||
)
|
||||
//- will only appear on screen width < 768px (using CSS)
|
||||
span.plans-v2-table-divider-learn-more-container
|
||||
span (
|
||||
span.plans-v2-table-divider-learn-more-text(
|
||||
data-toggle="tooltip"
|
||||
title=translate(planFeaturesPerSection.dividerInfo),
|
||||
data-placement="top"
|
||||
) #{translate("learn_more_lowercase")}
|
||||
span )
|
||||
td
|
||||
for feature, featureIndex in planFeaturesPerSection.items
|
||||
tr(
|
||||
class=(featureIndex === (planFeaturesPerSection.items.length - 1) ? 'plans-v2-table-row-last-row-per-section' : '')
|
||||
)
|
||||
td(event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
|
||||
.plans-v2-table-feature-name
|
||||
if feature.info
|
||||
span #{translate(feature.feature)}
|
||||
//- will only appear on screen width >= 768px (using CSS)
|
||||
i.fa.fa-question-circle.plans-v2-table-feature-name-question-icon(
|
||||
data-toggle="tooltip"
|
||||
title=translate(feature.info),
|
||||
data-placement="right"
|
||||
)
|
||||
//- will only appear on screen width < 768px (using CSS)
|
||||
span.plans-v2-table-feature-name-learn-more-container
|
||||
span (
|
||||
span.plans-v2-table-feature-name-learn-more-text(
|
||||
data-toggle="tooltip"
|
||||
title=translate(feature.info),
|
||||
data-placement="top"
|
||||
) #{translate("learn_more_lowercase")}
|
||||
span )
|
||||
else
|
||||
| #{translate(feature.feature)}
|
||||
td.plans-v2-table-cell-before-highlighted-column(ng-non-bindable)
|
||||
+table_cell(feature, 'group_standard')
|
||||
td.plans-v2-table-green-highlighted(ng-non-bindable)
|
||||
+table_cell(feature, 'group_professional')
|
||||
td(ng-non-bindable)
|
||||
+table_cell(feature, 'organization')
|
||||
td
|
||||
|
||||
mixin table_student(period)
|
||||
table.card.plans-v2-table.plans-v2-table-student
|
||||
tr
|
||||
th
|
||||
th.plans-v2-table-cell-before-highlighted-column
|
||||
mixin table_head_student_free(period)
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("free")}
|
||||
+table_head_price('free', period)
|
||||
|
@ -246,13 +219,9 @@ mixin table_student(period)
|
|||
li #{translate("one_collaborator")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_student_free()
|
||||
th.plans-v2-table-green-highlighted
|
||||
|
||||
mixin table_head_student_student(period)
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-green-highlighted-text
|
||||
if (period === 'monthly')
|
||||
| SAVE 20% ON ANNUAL PLAN
|
||||
else
|
||||
| SAVING 20%
|
||||
p.plans-v2-table-th-content-title #{translate("student")}
|
||||
+table_head_price('student', period)
|
||||
.plans-v2-table-btn-buy-container-mobile
|
||||
|
@ -262,7 +231,8 @@ mixin table_student(period)
|
|||
li #{translate("all_premium_features")}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_student_student(period)
|
||||
th
|
||||
|
||||
mixin table_head_student_university(period)
|
||||
div.plans-v2-table-th-content
|
||||
p.plans-v2-table-th-content-title #{translate("university")}
|
||||
div.plans-v2-table-comments-icon
|
||||
|
@ -272,62 +242,6 @@ mixin table_student(period)
|
|||
p.plans-v2-table-th-content-benefit !{translate("all_our_group_plans_offer_educational_discount", {}, [{name: 'b'}, {name: 'b'}])}
|
||||
.plans-v2-table-btn-buy-container-desktop
|
||||
+btn_buy_student_university(period)
|
||||
th
|
||||
|
||||
for planFeaturesPerSection in planFeatures.student
|
||||
if (planFeaturesPerSection.divider)
|
||||
tr.plans-v2-table-divider
|
||||
td(colspan="4")
|
||||
div
|
||||
b.plans-v2-table-divider-label #{translate(planFeaturesPerSection.dividerLabel)}
|
||||
//- will only appear on screen width >= 768px (using CSS)
|
||||
i.fa.fa-question-circle.plans-v2-table-divider-question-icon(
|
||||
data-toggle="tooltip"
|
||||
title=translate(planFeaturesPerSection.dividerInfo),
|
||||
data-placement="top"
|
||||
)
|
||||
//- will only appear on screen width < 768px (using CSS)
|
||||
span.plans-v2-table-divider-learn-more-container
|
||||
span (
|
||||
span.plans-v2-table-divider-learn-more-text(
|
||||
data-toggle="tooltip"
|
||||
title=translate(planFeaturesPerSection.dividerInfo),
|
||||
data-placement="top"
|
||||
) #{translate("learn_more_lowercase")}
|
||||
span )
|
||||
td
|
||||
for feature, featureIndex in planFeaturesPerSection.items
|
||||
tr(
|
||||
class=(featureIndex === (planFeaturesPerSection.items.length - 1) ? 'plans-v2-table-row-last-row-per-section' : '')
|
||||
)
|
||||
td(event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
|
||||
.plans-v2-table-feature-name
|
||||
if (feature.info)
|
||||
span #{translate(feature.feature)}
|
||||
//- will only appear on screen width >= 768px (using CSS)
|
||||
i.fa.fa-question-circle.plans-v2-table-feature-name-question-icon(
|
||||
data-toggle="tooltip"
|
||||
title=translate(feature.info),
|
||||
data-placement="right"
|
||||
)
|
||||
//- will only appear on screen width < 768px (using CSS)
|
||||
span.plans-v2-table-feature-name-learn-more-container
|
||||
span (
|
||||
span.plans-v2-table-feature-name-learn-more-text(
|
||||
data-toggle="tooltip"
|
||||
title=translate(feature.info),
|
||||
data-placement="top"
|
||||
) #{translate("learn_more_lowercase")}
|
||||
span )
|
||||
else
|
||||
| #{translate(feature.feature)}
|
||||
td.plans-v2-table-cell-before-highlighted-column(ng-non-bindable)
|
||||
+table_cell(feature, 'free')
|
||||
td.plans-v2-table-green-highlighted(ng-non-bindable)
|
||||
+table_cell(feature, 'student')
|
||||
td(ng-non-bindable)
|
||||
+table_cell(feature, 'university')
|
||||
td
|
||||
|
||||
mixin table_head_price(plan, period)
|
||||
div.plans-v2-table-price-container
|
||||
|
|
|
@ -379,8 +379,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
|
|||
.plans-v2-table-student {
|
||||
tr {
|
||||
// "hide" the last column on desktop by making the background-color as the default background color
|
||||
th:last-of-type,
|
||||
td:last-of-type {
|
||||
th:last-of-type {
|
||||
background-color: @ol-blue-gray-0;
|
||||
}
|
||||
|
||||
|
@ -419,8 +418,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
|
|||
|
||||
@media (max-width: @screen-md-max) {
|
||||
tr {
|
||||
th:last-of-type,
|
||||
td:last-of-type {
|
||||
th:last-of-type {
|
||||
// Last column is only a UI placeholder for desktop view.
|
||||
// We need to hide it for mobile to have the full table fully visible on mobile
|
||||
// without any empty horizontal space.
|
||||
|
|
Loading…
Reference in a new issue