diff --git a/services/web/app/src/Features/Subscription/planFeatures.js b/services/web/app/src/Features/Subscription/planFeatures.js
index 071c5d47ba..a8957056a3 100644
--- a/services/web/app/src/Features/Subscription/planFeatures.js
+++ b/services/web/app/src/Features/Subscription/planFeatures.js
@@ -6,6 +6,7 @@ module.exports = [
value: 'str',
plans: {
free: '1',
+ personal: '1',
coll: '10',
prof: 'unlimited'
},
@@ -17,6 +18,7 @@ module.exports = [
info: 'unlimited_private_info',
plans: {
free: true,
+ personal: true,
coll: true,
prof: true
},
@@ -28,6 +30,7 @@ module.exports = [
info: 'realtime_collab_info',
plans: {
free: true,
+ personal: true,
coll: true,
prof: true
},
@@ -39,6 +42,7 @@ module.exports = [
info: 'hundreds_templates_info',
plans: {
free: true,
+ personal: true,
coll: true,
prof: true
},
@@ -50,39 +54,30 @@ module.exports = [
info: 'latex_editor_info',
plans: {
free: true,
+ personal: true,
coll: true,
prof: true
},
student: true
},
+ {
+ feature: 'compile_timeout',
+ value: 'str',
+ plans: {
+ free: '1 min',
+ personal: '4 mins',
+ coll: '4 mins',
+ prof: '4 mins'
+ },
+ student: '4 mins'
+ },
{
feature: 'realtime_track_changes',
value: 'bool',
info: 'realtime_track_changes_info',
plans: {
free: false,
- coll: true,
- prof: true
- },
- student: true
- },
- {
- feature: 'reference_search',
- value: 'bool',
- info: 'reference_search_info',
- plans: {
- free: false,
- coll: true,
- prof: true
- },
- student: true
- },
- {
- feature: 'reference_sync',
- info: 'reference_sync_info',
- value: 'bool',
- plans: {
- free: false,
+ personal: false,
coll: true,
prof: true
},
@@ -94,6 +89,31 @@ module.exports = [
info: 'full_doc_history_info',
plans: {
free: false,
+ personal: true,
+ coll: true,
+ prof: true
+ },
+ student: true
+ },
+ {
+ feature: 'reference_search',
+ value: 'bool',
+ info: 'reference_search_info',
+ plans: {
+ free: false,
+ personal: true,
+ coll: true,
+ prof: true
+ },
+ student: true
+ },
+ {
+ feature: 'reference_sync',
+ info: 'reference_sync_info',
+ value: 'bool',
+ plans: {
+ free: false,
+ personal: true,
coll: true,
prof: true
},
@@ -105,6 +125,7 @@ module.exports = [
info: 'dropbox_integration_info',
plans: {
free: false,
+ personal: true,
coll: true,
prof: true
},
@@ -116,6 +137,7 @@ module.exports = [
info: 'github_integration_info',
plans: {
free: false,
+ personal: true,
coll: true,
prof: true
},
@@ -126,6 +148,7 @@ module.exports = [
value: 'bool',
plans: {
free: false,
+ personal: true,
coll: true,
prof: true
},
diff --git a/services/web/app/views/subscriptions/_plans_page_mixins.pug b/services/web/app/views/subscriptions/_plans_page_mixins.pug
index 83affdca8f..7ed35769a9 100644
--- a/services/web/app/views/subscriptions/_plans_page_mixins.pug
+++ b/services/web/app/views/subscriptions/_plans_page_mixins.pug
@@ -6,6 +6,13 @@ mixin btn_buy_collaborator(location)
)
span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
+mixin btn_buy_personal(location)
+ a.btn.btn-primary(
+ ng-href="/user/subscription/new?planCode={{ getPersonalPlanCode() }}¤cy={{currencyCode}}&itm_campaign=plans&itm_content=" + location,
+ ng-click="signUpNowClicked('personal','" + location + "')"
+ )
+ span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
+ span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
mixin btn_buy_free(location)
a.btn.btn-primary(
href="/register"
@@ -74,6 +81,19 @@ mixin features_free(location)
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
@@ -100,6 +120,13 @@ mixin features_student(location, plan)
+btn_buy_student(location, plan)
//- Prices
+mixin price_personal
+ span(ng-if="ui.view == 'monthly'")
+ | {{plans[currencyCode]['personal']['monthly']}}
+ span.small /mo
+ span(ng-if="ui.view == 'annual'")
+ | {{plans[currencyCode]['personal']['annual']}}
+ span.small /yr
mixin price_collaborator
span(ng-if="ui.view == 'monthly'")
| {{plans[currencyCode]['collaborator']['monthly']}}
@@ -154,7 +181,7 @@ mixin plan_switch(location)
a.btn.btn-default-outline(
href="#"
ng-click="switchToStudent($event,'" + location + "')"
- ) #{translate("half_price_student")}
+ ) #{translate("special_price_student")}
mixin allCardsAndControls(controlsRowSpaced, listLocation)
- var location = listLocation ? 'card_' + listLocation : 'card'
@@ -173,8 +200,9 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
.card-header
h2 #{translate("personal")}
h5.tagline #{translate("tagline_personal")}
- .circle #{translate("free")}
- +features_free(location)
+ .circle
+ +price_personal
+ +features_personal(location)
.col-md-4
.card.card-highlighted
.best-value
@@ -198,8 +226,8 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
.col-md-4
.card.card-first
.card-header
- h2 #{translate("personal")}
- h5.tagline #{translate("tagline_personal")}
+ h2 #{translate("free")}
+ h5.tagline #{translate("tagline_free")}
.circle #{translate("free")}
+features_free(location)
@@ -209,4 +237,4 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
.col-md-4
.card.card-last
- +card_student_monthly(location)
\ No newline at end of file
+ +card_student_monthly(location)
diff --git a/services/web/app/views/subscriptions/_plans_page_tables.pug b/services/web/app/views/subscriptions/_plans_page_tables.pug
index 9107129e99..9db4d6b7ec 100644
--- a/services/web/app/views/subscriptions/_plans_page_tables.pug
+++ b/services/web/app/views/subscriptions/_plans_page_tables.pug
@@ -1,9 +1,10 @@
//- Features Tables
mixin table_premium
- table.card.plans-table
+ table.card.plans-table.plans-table-main
tr
th
+ th #{translate("free")}
th #{translate("personal")}
th #{translate("collaborator")}
.outer.outer-top
@@ -15,6 +16,8 @@ mixin table_premium
tr
td #{translate("price")}
td #{translate("free")}
+ td
+ +price_personal
td
+price_collaborator
td
@@ -42,6 +45,8 @@ mixin table_premium
td
td
+btn_buy_free('table')
+ td
+ +btn_buy_personal('table')
td
+btn_buy_collaborator('table')
.outer.outer-btm
@@ -60,10 +65,10 @@ mixin table_cell_student(feature)
span.sr-only Feature not included
mixin table_student
- table.card.plans-table
+ table.card.plans-table.plans-table-student
tr
th
- th #{translate("personal")}
+ th #{translate("free")}
th #{translate("student")} (#{translate("annual")})
.outer.outer-top
.outer-content
diff --git a/services/web/app/views/subscriptions/dashboard/_change_plans_mixins.pug b/services/web/app/views/subscriptions/dashboard/_change_plans_mixins.pug
index 9175857d93..3af8872b17 100644
--- a/services/web/app/views/subscriptions/dashboard/_change_plans_mixins.pug
+++ b/services/web/app/views/subscriptions/dashboard/_change_plans_mixins.pug
@@ -18,4 +18,4 @@ mixin printPlan(plan)
mixin printPlans(plans)
each plan in plans
- +printPlan(plan)
\ No newline at end of file
+ +printPlan(plan)
diff --git a/services/web/app/views/subscriptions/new.pug b/services/web/app/views/subscriptions/new.pug
index 834998594e..9fd29b86a7 100644
--- a/services/web/app/views/subscriptions/new.pug
+++ b/services/web/app/views/subscriptions/new.pug
@@ -47,7 +47,7 @@ block content
div(ng-if="trialLength")
span !{translate("first_few_days_free", {trialLen:'{{trialLength}}'})}
span(ng-if="coupon.discountMonths && coupon.discountRate") - {{coupon.discountMonths}} #{translate("month")}s {{coupon.discountRate}}% Off
-
+
div(ng-if="price")
- var priceAngularExp = "{{ availableCurrencies[currencyCode]['symbol'] }}{{ price.total }}";
span(ng-if="!coupon.singleUse && monthlyBilling")
@@ -235,7 +235,7 @@ block content
- priceBreakdownAngularExp += " + " ;
- priceBreakdownAngularExp += "{{availableCurrencies[currencyCode]['symbol']}}{{ price.tax }} tax)";
hr.thin
- span
+ span
| Total:
|
span(ng-if="!coupon.singleUse && monthlyBilling")
@@ -283,7 +283,7 @@ block content
a.btn-primary.btn.plansPageStudentLink(
href,
ng-click="switchToStudent()"
- ) #{translate("half_price_student")}
+ ) #{translate("special_price_student")}
.card.card-first
.paymentPageFeatures
@@ -295,7 +295,10 @@ block content
- var collaboratorCount = 'Unlimited'
else
- var collaboratorCount = plan.features.collaborators
- | #{translate("collabs_per_proj", {collabcount:collaboratorCount})}
+ if plan.features.collaborators == 1
+ | #{translate("collabs_per_proj_single", {collabcount:collaboratorCount})}
+ else
+ | #{translate("collabs_per_proj", {collabcount:collaboratorCount})}
p #{translate("work_on_single_version")}. #{translate("view_collab_edits")} in real time.
h3 #{translate("full_doc_history")}
diff --git a/services/web/app/views/subscriptions/plans.pug b/services/web/app/views/subscriptions/plans.pug
index 2af79b21b8..eb800563fa 100644
--- a/services/web/app/views/subscriptions/plans.pug
+++ b/services/web/app/views/subscriptions/plans.pug
@@ -38,6 +38,7 @@ block content
.row.row-spaced-large.text-centered
.col-xs-12
+ p.text-centered !{translate('also_provides_free_plan', { appName:'{{settings.appName}}', registerLinkOpen: '', registerLinkClose: '' })}
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")
diff --git a/services/web/frontend/js/main/plans.js b/services/web/frontend/js/main/plans.js
index 78ced50890..73c28e16e6 100644
--- a/services/web/frontend/js/main/plans.js
+++ b/services/web/frontend/js/main/plans.js
@@ -16,6 +16,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '$8',
annual: '$80'
},
+ personal: {
+ monthly: '$10',
+ annual: '$120'
+ },
collaborator: {
monthly: '$15',
annual: '$180'
@@ -32,6 +36,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '€7',
annual: '€70'
},
+ personal: {
+ monthly: '€9',
+ annual: '€108'
+ },
collaborator: {
monthly: '€14',
annual: '€168'
@@ -48,6 +56,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '£6',
annual: '£60'
},
+ personal: {
+ monthly: '£8',
+ annual: '£96'
+ },
collaborator: {
monthly: '£12',
annual: '£144'
@@ -64,6 +76,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '60 kr',
annual: '600 kr'
},
+ personal: {
+ monthly: '73 kr',
+ annual: '876 kr'
+ },
collaborator: {
monthly: '110 kr',
annual: '1320 kr'
@@ -79,6 +95,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '$9',
annual: '$90'
},
+ personal: {
+ monthly: '$11',
+ annual: '$132'
+ },
collaborator: {
monthly: '$17',
annual: '$204'
@@ -95,6 +115,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '60 kr',
annual: '600 kr'
},
+ personal: {
+ monthly: '73 kr',
+ annual: '876 kr'
+ },
collaborator: {
monthly: '110 kr',
annual: '1320 kr'
@@ -111,6 +135,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '50 kr',
annual: '500 kr'
},
+ personal: {
+ monthly: '60 kr',
+ annual: '720 kr'
+ },
collaborator: {
monthly: '90 kr',
annual: '1080 kr'
@@ -127,6 +155,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '$10',
annual: '$100'
},
+ personal: {
+ monthly: '$12',
+ annual: '$144'
+ },
collaborator: {
monthly: '$18',
annual: '$216'
@@ -143,6 +175,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '$10',
annual: '$100'
},
+ personal: {
+ monthly: '$12',
+ annual: '$144'
+ },
collaborator: {
monthly: '$18',
annual: '$216'
@@ -159,6 +195,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: 'Fr 8',
annual: 'Fr 80'
},
+ personal: {
+ monthly: 'Fr 10',
+ annual: 'Fr 120'
+ },
collaborator: {
monthly: 'Fr 15',
annual: 'Fr 180'
@@ -175,6 +215,10 @@ App.factory('MultiCurrencyPricing', function() {
monthly: '$12',
annual: '$120'
},
+ personal: {
+ monthly: '$13',
+ annual: '$156'
+ },
collaborator: {
monthly: '$20',
annual: '$240'
@@ -224,6 +268,15 @@ App.controller('PlansController', function(
}
}
+ $scope.getPersonalPlanCode = function() {
+ const { view } = $scope.ui
+ if (view === 'annual') {
+ return 'paid-personal-annual'
+ } else {
+ return `paid-personal${$scope.planQueryString}`
+ }
+ }
+
$scope.signUpNowClicked = function(plan, location) {
if ($scope.ui.view === 'annual') {
plan = `${plan}_annual`
diff --git a/services/web/frontend/stylesheets/app/plans.less b/services/web/frontend/stylesheets/app/plans.less
index f9e7818793..6c8f14d694 100644
--- a/services/web/frontend/stylesheets/app/plans.less
+++ b/services/web/frontend/stylesheets/app/plans.less
@@ -288,20 +288,6 @@
border-bottom: 0;
padding: 18px;
}
- /* 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%;
- }
- }
td:first-child {
border: 0;
}
@@ -316,13 +302,6 @@
color: @gray-med;
}
- /* highlighted column */
- 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;
- }
.outer {
left: -@border-width-base;
right: -@border-width-base;
@@ -357,20 +336,22 @@
}
}
- /* highlight rows on hover */
- tr:hover {
- td {
- background-color: @table-hover-bg;
+ @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 {
+ tr:first-child:hover {
background-color: transparent;
}
+ tr:last-child:hover {
+ background-color: transparent;
+ td {
+ background-color: transparent;
+ }
+ }
}
/* tooltip */
@@ -411,4 +392,95 @@
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%;
+ }
+ }
}