Remove Plans and Pricing A/B Test

Remove all layouts, analytics events, and scope related to the A/B test.

The group modal from the default layout of the A/B test should be maintained though for v2.
This commit is contained in:
Jessica Lawshe 2018-08-27 09:03:01 -05:00
parent 107e8ce633
commit 8889f2aed2
11 changed files with 54 additions and 192 deletions

View file

@ -30,7 +30,6 @@ module.exports = SubscriptionController =
plans: plans plans: plans
gaExperiments: Settings.gaExperiments.plansPage gaExperiments: Settings.gaExperiments.plansPage
recomendedCurrency:recomendedCurrency recomendedCurrency:recomendedCurrency
shouldABTestPlans: currentUser == null or (currentUser?.signUpDate? and currentUser.signUpDate >= '2018-06-06')
planFeatures: planFeatures planFeatures: planFeatures
user_id = AuthenticationController.getLoggedInUserId(req) user_id = AuthenticationController.getLoggedInUserId(req)
if user_id? if user_id?

View file

@ -0,0 +1,30 @@
script(type="text/ng-template", id="groupPlanModalTemplate")
.modal-header
h3 #{translate("group_plan_enquiry")}
.modal-body
form.text-left.form(ng-controller="UniverstiesContactController", ng-submit="contactUs()")
span(ng-show="sent == false && error == false")
.form-group
label#title9(for='Field9')
| Name
input#Field9.field.text.medium.span8.form-control(ng-model="form.name", maxlength='255', tabindex='1', onkeyup='')
label#title11.desc(for='Field11')
| Email
.form-group
input#Field11.field.text.medium.span8.form-control(ng-model="form.email", name='Field11', type='email', spellcheck='false', value='', maxlength='255', tabindex='2')
label#title12.desc(for='Field12')
| University / Company
.form-group
input#Field12.field.text.medium.span8.form-control(ng-model="form.university", name='Field12', type='text', value='', maxlength='255', tabindex='3', onkeyup='')
label#title13.desc(for='Field13')
| Position
.form-group
input#Field13.field.text.medium.span8.form-control(ng-model="form.position", name='Field13', type='text', value='', maxlength='255', tabindex='4', onkeyup='')
.form-group
input(ng-model="form.source", type="hidden", ng-init="form.source = '__ref__'; form.subject = 'General enquiry for larger ShareLaTeX use';")
.form-group.text-center
input#saveForm.btn-success.btn.btn-lg(name='saveForm', type='submit', ng-disabled="sending", value='Request a quote')
span(ng-show="sent == true && error == false")
p Request Sent, Thank you.
span(ng-show="error")
p Error sending request.

View file

@ -1,118 +0,0 @@
.row
.col-md-12
.page-header.centered.plans-header.text-centered
h1 #{translate("start_x_day_trial", {len:'{{trial_len}}'})}
.row
.col-md-8.col-md-offset-2
p.text-centered #{translate("sl_benefits_plans")}
.row.top-switch
.col-md-6.col-md-offset-3
+plan_switch('card')
.col-md-2.text-right
+currency_dropdown
div(ng-show="showPlans")
.row
.col-md-10.col-md-offset-1
.row
.card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
.col-md-4
.card.card-first
.card-header
h2 #{translate("personal")}
.circle #{translate("free")}
+features_free
.col-md-4
.card.card-highlighted
.card-header
h2 #{translate("collaborator")}
.circle
+price_collaborator
+features_collaborator
.col-md-4
.card.card-last
.card-header
h2 #{translate("professional")}
.circle
+price_professional
+features_professional
.card-group.text-centered(ng-if="ui.view == 'student'")
.col-md-4
.card.card-first
.card-header
h2 #{translate("personal")}
.circle #{translate("free")}
+features_free
.col-md-4
.card.card-highlighted
+card_student_monthly
.col-md-4
.card.card-last
+card_student_annual
.row.row-spaced
p.text-centered #{translate("choose_plan_works_for_you", {len:'{{trial_len}}'})}
.row
.col-md-8.col-md-offset-2
.alert.alert-info.text-centered
| #{translate("interested_in_group_licence")}
br
a(href, ng-click="openGroupPlanModal()") #{translate("get_in_touch_for_details")}
script(type="text/ng-template", id="groupPlanModalTemplate")
.modal-header
h3 #{translate("group_plan_enquiry")}
.modal-body
form.text-left.form(ng-controller="UniverstiesContactController", ng-submit="contactUs()")
span(ng-show="sent == false && error == false")
.form-group
label#title9(for='Field9')
| Name
input#Field9.field.text.medium.span8.form-control(ng-model="form.name", maxlength='255', tabindex='1', onkeyup='')
label#title11.desc(for='Field11')
| Email
.form-group
input#Field11.field.text.medium.span8.form-control(ng-model="form.email", name='Field11', type='email', spellcheck='false', value='', maxlength='255', tabindex='2')
label#title12.desc(for='Field12')
| University / Company
.form-group
input#Field12.field.text.medium.span8.form-control(ng-model="form.university", name='Field12', type='text', value='', maxlength='255', tabindex='3', onkeyup='')
label#title13.desc(for='Field13')
| Position
.form-group
input#Field13.field.text.medium.span8.form-control(ng-model="form.position", name='Field13', type='text', value='', maxlength='255', tabindex='4', onkeyup='')
.form-group
input(ng-model="form.source", type="hidden", ng-init="form.source = '__ref__'; form.subject = 'General enquiry for larger ShareLaTeX use';")
.form-group.text-center
input#saveForm.btn-success.btn.btn-lg(name='saveForm', type='submit', ng-disabled="sending", value='Request a quote')
span(ng-show="sent == true && error == false")
p Request Sent, Thank you.
span(ng-show="error")
p Error sending request.
.row
.col-md-12
.page-header.plans-header.plans-subheader.text-centered
h2 #{translate("enjoy_these_features")}
.col-md-4
.card.features.text-centered
i.fa.fa-file-text-o.fa-5x
h4 #{translate("unlimited_projects")}
p #{translate("create_unlimited_projects")}
.col-md-4
.card.features.text-centered
i.fa.fa-clock-o.fa-5x
h4 #{translate("full_doc_history")}
p #{translate("never_loose_work")}
.col-md-4
.card.features.text-centered
i.fa.fa-dropbox.fa-5x
|    
i.fa.fa-github.fa-5x
h4 #{translate("sync_to_dropbox_and_github")}
p #{translate("access_projects_anywhere")}

View file

@ -12,8 +12,7 @@ mixin btn_buy_free(location)
style=(getLoggedInUserId() === null ? "" : "visibility: hidden") style=(getLoggedInUserId() === null ? "" : "visibility: hidden")
ng-click="signUpNowClicked('free','" + location + "')" ng-click="signUpNowClicked('free','" + location + "')"
) )
span(ng-if="plansVariant !== 'more-details'") #{translate('sign_up_now')} span.text-capitalize #{translate('get_started_now')}
span.text-capitalize(ng-if="plansVariant === 'more-details'") #{translate('get_started_now')}
mixin btn_buy_professional(location) mixin btn_buy_professional(location)
a.btn.btn-info( a.btn.btn-info(
ng-href="/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}&currency={{currencyCode}}" ng-href="/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}&currency={{currencyCode}}"
@ -36,11 +35,11 @@ mixin btn_buy_student(location, plan)
//- Cards //- Cards
mixin card_student_annual mixin card_student_annual
.best-value(ng-if="plansVariant == 'more-details'") .best-value
strong #{translate('best_value')} strong #{translate('best_value')}
.card-header .card-header
h2 #{translate("student")} (#{translate("annual")}) h2 #{translate("student")} (#{translate("annual")})
h5.tagline(ng-if="plansVariant == 'more-details'") #{translate('tagline_student_annual')} h5.tagline #{translate('tagline_student_annual')}
.circle .circle
span span
+price_student_annual +price_student_annual
@ -48,7 +47,7 @@ mixin card_student_annual
mixin card_student_monthly mixin card_student_monthly
.card-header .card-header
h2 #{translate("student")} h2 #{translate("student")}
h5.tagline(ng-if="plansVariant == 'more-details'") #{translate('tagline_student_monthly')} h5.tagline #{translate('tagline_student_monthly')}
.circle .circle
span span
+price_student_monthly +price_student_monthly
@ -69,23 +68,20 @@ mixin features_free
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(class="hidden-xs hidden-sm" ng-if="plansVariant === 'more-details'")   li(class="hidden-xs hidden-sm")  
li(class="hidden-xs hidden-sm" ng-if="plansVariant === 'more-details'")   li(class="hidden-xs hidden-sm")  
li(class="hidden-xs hidden-sm" ng-if="plansVariant === 'more-details'")   li(class="hidden-xs hidden-sm")  
li li
br br
+btn_buy_free('card') +btn_buy_free('card')
mixin features_premium mixin features_premium
li(ng-if="plansVariant != 'more-details'") #{translate("full_doc_history")} li  
li(ng-if="plansVariant != 'more-details'") #{translate("sync_to_dropbox")} li
li(ng-if="plansVariant != 'more-details'") #{translate("sync_to_github")}
li(ng-if="plansVariant === 'more-details'")  
li(ng-if="plansVariant === 'more-details'")
strong #{translate('all_premium_features')} strong #{translate('all_premium_features')}
li(ng-if="plansVariant === 'more-details'") #{translate('sync_dropbox_github')} li #{translate('sync_dropbox_github')}
li(ng-if="plansVariant === 'more-details'") #{translate('full_doc_history')} li #{translate('full_doc_history')}
li(ng-if="plansVariant === 'more-details'") #{translate('track_changes')} li #{translate('track_changes')}
li(ng-if="plansVariant === 'more-details'") + #{translate('more').toLowerCase()} li + #{translate('more').toLowerCase()}
mixin features_professional mixin features_professional
ul.list-unstyled ul.list-unstyled
li li
@ -159,4 +155,3 @@ mixin plan_switch(location)
href="#" href="#"
ng-click="switchToStudent($event,'" + location + "')" ng-click="switchToStudent($event,'" + location + "')"
) #{translate("half_price_student")} ) #{translate("half_price_student")}

View file

@ -22,7 +22,7 @@ mixin table_premium
for feature in planFeatures for feature in planFeatures
tr tr
td(event-tracking="features-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}-exp-{{plansVariant}}`) td(event-tracking="features-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
if feature.info if feature.info
span(tooltip=translate(feature.info)) #{translate(feature.feature)} span(tooltip=translate(feature.info)) #{translate(feature.feature)}
else else
@ -77,7 +77,7 @@ mixin table_student
for feature in planFeatures for feature in planFeatures
tr tr
td(event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}-exp-{{plansVariant}}`) td(event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}`)
if feature.info if feature.info
span(tooltip=translate(feature.info)) #{translate(feature.feature)} span(tooltip=translate(feature.info)) #{translate(feature.feature)}
else else
@ -104,4 +104,3 @@ mixin table_student
.outer-content   .outer-content  
td td
+btn_buy_student('table', 'monthly') +btn_buy_student('table', 'monthly')

View file

@ -33,7 +33,7 @@ block content
a( a(
ng-click="changeCurrency(currency)", ng-click="changeCurrency(currency)",
) {{currency}} ({{value['symbol']}}) ) {{currency}} ({{value['symbol']}})
.row(ng-if="plansVariant == 'more-details' && planCode == 'student-annual' || plansVariant == 'more-details' && planCode == 'student-monthly'") .row(ng-if="planCode == 'student-annual' || planCode == 'student-monthly'")
.col-xs-12 .col-xs-12
p.student-disclaimer #{translate('student_disclaimer')} p.student-disclaimer #{translate('student_disclaimer')}

View file

@ -7,12 +7,9 @@ block scripts
script(type='text/javascript'). script(type='text/javascript').
window.recomendedCurrency = '#{recomendedCurrency}' window.recomendedCurrency = '#{recomendedCurrency}'
window.abCurrencyFlag = '#{abCurrencyFlag}' window.abCurrencyFlag = '#{abCurrencyFlag}'
window.shouldABTestPlans = #{shouldABTestPlans || false}
block content block content
.content.content-alt .content.content-alt
.content.plans(ng-controller="PlansController") .content.plans(ng-controller="PlansController")
.container(class="more-details" ng-cloak ng-if="plansVariant === 'more-details'") .container(class="more-details" ng-cloak)
include _plans_page_details_more include _plans_page_details_more
.container(ng-cloak ng-if="plansVariant === 'default' || !shouldABTestPlans || timeout")
include _plans_page_details_less

View file

@ -87,10 +87,6 @@ define [
} }
$scope.user = window.user $scope.user = window.user
$scope.shouldABTestPlans = false
if $scope.user.signUpDate >= '2018-06-06'
$scope.shouldABTestPlans = true
$scope.settings = window.userSettings $scope.settings = window.userSettings
$scope.anonymous = window.anonymous $scope.anonymous = window.anonymous
$scope.isTokenMember = window.isTokenMember $scope.isTokenMember = window.isTokenMember

View file

@ -4,21 +4,20 @@ define [
"libs/recurly-4.8.5" "libs/recurly-4.8.5"
], (App)-> ], (App)->
App.controller "NewSubscriptionController", ($scope, MultiCurrencyPricing, abTestManager, $http, sixpack, event_tracking, ccUtils, ipCookie)-> App.controller "NewSubscriptionController", ($scope, MultiCurrencyPricing, $http, event_tracking, ccUtils)->
throw new Error("Recurly API Library Missing.") if typeof recurly is "undefined" throw new Error("Recurly API Library Missing.") if typeof recurly is "undefined"
$scope.currencyCode = MultiCurrencyPricing.currencyCode $scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.plans = MultiCurrencyPricing.plans $scope.plans = MultiCurrencyPricing.plans
$scope.planCode = window.plan_code $scope.planCode = window.plan_code
$scope.plansVariant = ipCookie('plansVariant')
$scope.switchToStudent = ()-> $scope.switchToStudent = ()->
currentPlanCode = window.plan_code currentPlanCode = window.plan_code
planCode = currentPlanCode.replace('collaborator', 'student') planCode = currentPlanCode.replace('collaborator', 'student')
event_tracking.sendMB 'subscription-form-switch-to-student', { plan: window.plan_code, variant: $scope.plansVariant } event_tracking.sendMB 'subscription-form-switch-to-student', { plan: window.plan_code }
window.location = "/user/subscription/new?planCode=#{planCode}&currency=#{$scope.currencyCode}&cc=#{$scope.data.coupon}" window.location = "/user/subscription/new?planCode=#{planCode}&currency=#{$scope.currencyCode}&cc=#{$scope.data.coupon}"
event_tracking.sendMB "subscription-form", { plan : window.plan_code, variant: $scope.plansVariant } event_tracking.sendMB "subscription-form", { plan : window.plan_code }
$scope.paymentMethod = $scope.paymentMethod =
value: "credit_card" value: "credit_card"
@ -144,14 +143,13 @@ define [
currencyCode : postData.subscriptionDetails.currencyCode, currencyCode : postData.subscriptionDetails.currencyCode,
plan_code : postData.subscriptionDetails.plan_code, plan_code : postData.subscriptionDetails.plan_code,
coupon_code : postData.subscriptionDetails.coupon_code, coupon_code : postData.subscriptionDetails.coupon_code,
isPaypal : postData.subscriptionDetails.isPaypal, isPaypal : postData.subscriptionDetails.isPaypal
variant : $scope.plansVariant
} }
$http.post("/user/subscription/create", postData) $http.post("/user/subscription/create", postData)
.then ()-> .then ()->
event_tracking.sendMB "subscription-submission-success", { variant: $scope.plansVariant } event_tracking.sendMB "subscription-submission-success"
window.location.href = "/user/subscription/thank-you" window.location.href = "/user/subscription/thank-you"
.catch ()-> .catch ()->
$scope.processing = false $scope.processing = false

View file

@ -145,21 +145,7 @@ define [
} }
App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http, sixpack, $filter, ipCookie) -> App.controller "PlansController", ($scope, $modal, event_tracking, MultiCurrencyPricing, $http, $filter, ipCookie) ->
$scope.showPlans = false
$scope.shouldABTestPlans = window.shouldABTestPlans
if $scope.shouldABTestPlans
sixpack.participate 'plans-details', ['default', 'more-details'], (chosenVariation, rawResponse)->
if rawResponse?.status != 'failed'
$scope.plansVariant = chosenVariation
expiration = new Date();
expiration.setDate(expiration.getDate() + 5);
ipCookie('plansVariant', chosenVariation, {expires: expiration})
event_tracking.send 'subscription-funnel', 'plans-page-loaded', chosenVariation
else
$scope.timeout = true
$scope.showPlans = true $scope.showPlans = true
@ -190,10 +176,8 @@ define [
if $scope.ui.view == "annual" if $scope.ui.view == "annual"
plan = "#{plan}_annual" plan = "#{plan}_annual"
plan = eventLabel(plan, location) plan = eventLabel(plan, location)
event_tracking.sendMB 'plans-page-start-trial', {plan, variant: $scope.plansVariant} event_tracking.sendMB 'plans-page-start-trial'
event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan
if $scope.plansVariant
sixpack.convert 'plans-details'
$scope.switchToMonthly = (e, location) -> $scope.switchToMonthly = (e, location) ->
uiView = 'monthly' uiView = 'monthly'
@ -217,14 +201,9 @@ define [
event_tracking.send 'subscription-funnel', 'plans-page', 'group-inquiry-potential' event_tracking.send 'subscription-funnel', 'plans-page', 'group-inquiry-potential'
eventLabel = (label, location) -> eventLabel = (label, location) ->
if $scope.plansVariant && location && $scope.plansVariant != 'default'
label = label + '-' + location
if $scope.plansVariant && $scope.plansVariant != 'default'
label += '-exp-' + $scope.plansVariant
label label
switchEvent = (e, label, location) -> switchEvent = (e, label, location) ->
e.preventDefault() e.preventDefault()
gaLabel = eventLabel(label, location) gaLabel = eventLabel(label, location)
event_tracking.send 'subscription-funnel', 'plans-page', gaLabel event_tracking.send 'subscription-funnel', 'plans-page', gaLabel

View file

@ -100,14 +100,6 @@ describe "SubscriptionController", ->
@UserGetter.getUser.callCount.should.equal 1 @UserGetter.getUser.callCount.should.equal 1
done() done()
it 'should decide not to AB test the plans when signed up before 2018-06-06', (done) ->
# Users before we introduce the test may have already seen the old variant,
# and so may react positively to a change rather than the variant itself.
# So it's more likely to skew in favour of the change
# just because change makes things 'fresh'
@res.renderedVariables.shouldABTestPlans.should.equal false
done()
describe 'not dependant on logged in state', (done) -> describe 'not dependant on logged in state', (done) ->
# these could have been put in 'when user is not logged in' too # these could have been put in 'when user is not logged in' too
it "should set the recommended currency from the geoiplookup", (done)-> it "should set the recommended currency from the geoiplookup", (done)->
@ -115,7 +107,6 @@ describe "SubscriptionController", ->
@GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true @GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true
done() done()
it 'should include data for features table', (done) -> it 'should include data for features table', (done) ->
# this is part of AB test. If default wins test, then remove this test
@res.renderedVariables.planFeatures.length.should.not.equal 0 @res.renderedVariables.planFeatures.length.should.not.equal 0
done() done()
@ -150,10 +141,6 @@ describe "SubscriptionController", ->
@UserGetter.getUser.callCount.should.equal 0 @UserGetter.getUser.callCount.should.equal 0
done() done()
it 'should decide to AB test', (done) ->
@res.renderedVariables.shouldABTestPlans.should.equal true
done()
describe "paymentPage", -> describe "paymentPage", ->
beforeEach -> beforeEach ->
@req.headers = {} @req.headers = {}