|
|
@@ -0,0 +1,360 @@
|
|
|
+extends ../layout
|
|
|
+
|
|
|
+block vars
|
|
|
+ - var suppressNavbarRight = true
|
|
|
+ - var suppressFooter = true
|
|
|
+
|
|
|
+block append meta
|
|
|
+ meta(name="ol-countryCode" content=countryCode)
|
|
|
+ meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
|
|
|
+ meta(name="ol-recommendedCurrency" content=String(currency).slice(0,3))
|
|
|
+
|
|
|
+block head-scripts
|
|
|
+ script(type="text/javascript", nonce=scriptNonce, src="https://js.recurly.com/v4/recurly.js")
|
|
|
+
|
|
|
+block content
|
|
|
+ main.content.content-alt#main-content
|
|
|
+ .container(ng-controller="NewSubscriptionController" ng-cloak)
|
|
|
+ .row.card-group
|
|
|
+ .col-md-3.col-md-push-1
|
|
|
+ .card.card-highlighted
|
|
|
+ .price-feature-description
|
|
|
+ h4(ng-if="planName") {{planName}}
|
|
|
+ h4(ng-if="!planName") #{plan.name}
|
|
|
+ if plan.features
|
|
|
+ if plan.features.collaborators === 1
|
|
|
+ .text-small.number-of-collaborators #{translate("collabs_per_proj_single", {collabcount: 1})}
|
|
|
+ if plan.features.collaborators === -1
|
|
|
+ .text-small.number-of-collaborators #{translate("unlimited_collabs")}
|
|
|
+ if plan.features.collaborators > 1
|
|
|
+ .text-small.number-of-collaborators #{translate("collabs_per_proj", {collabcount: plan.features.collaborators})}
|
|
|
+ .text-small #{translate("all_premium_features_including")}
|
|
|
+ ul.small
|
|
|
+ if plan.features.compileTimeout > 1
|
|
|
+ li #{translate("increased_compile_timeout")}
|
|
|
+ if plan.features.dropbox && plan.features.github
|
|
|
+ li #{translate("sync_dropbox_github")}
|
|
|
+ if plan.features.versioning
|
|
|
+ li #{translate("full_doc_history")}
|
|
|
+ if plan.features.trackChanges
|
|
|
+ li #{translate("track_changes")}
|
|
|
+ if plan.features.references
|
|
|
+ li #{translate("reference_search")}
|
|
|
+ if plan.features.mendeley || plan.features.zotero
|
|
|
+ li #{translate("reference_sync")}
|
|
|
+ if plan.features.symbolyPalette
|
|
|
+ li #{translate("symboly_palette")}
|
|
|
+
|
|
|
+
|
|
|
+ div.price-summary(ng-if="recurlyPrice")
|
|
|
+ - var priceVars = { price: "{{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.total }}"};
|
|
|
+ hr
|
|
|
+ h4 #{translate("payment_summary")}
|
|
|
+ div.small
|
|
|
+ .price-summary-line
|
|
|
+ span
|
|
|
+ | {{planName}}
|
|
|
+ span(ng-if="coupon")
|
|
|
+ | {{ availableCurrencies[currencyCode]['symbol'] }}{{ coupon.normalPriceWithoutTax | number:2 }}
|
|
|
+ span(ng-if="!coupon")
|
|
|
+ | {{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.subtotal }}
|
|
|
+ .price-summary-line(ng-if="coupon")
|
|
|
+ span
|
|
|
+ | {{ coupon.name }}
|
|
|
+ span
|
|
|
+ | –{{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.discount}}
|
|
|
+
|
|
|
+ .price-summary-line(ng-if="taxes && taxes[0] && taxes[0].rate > 0")
|
|
|
+ span
|
|
|
+ | #{translate("vat")} {{taxes[0].rate * 100}}%
|
|
|
+ span
|
|
|
+ | {{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.tax }}
|
|
|
+ .price-summary-line.price-summary-total-line
|
|
|
+ span
|
|
|
+ b {{ monthlyBilling ? '#{translate("total_per_month")}' : '#{translate("total_per_year")}'}}
|
|
|
+ span
|
|
|
+ b {{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.total }}
|
|
|
+
|
|
|
+
|
|
|
+ .change-currency
|
|
|
+ div.dropdown(ng-cloak dropdown)
|
|
|
+ button.btn.btn-link.dropdown-toggle.change-currency-toggle(
|
|
|
+ href="#",
|
|
|
+ data-toggle="dropdown",
|
|
|
+ dropdown-toggle
|
|
|
+ ) Change currency
|
|
|
+ ul.dropdown-menu(role="menu")
|
|
|
+ li(ng-repeat="(currency, value) in limitedCurrencies")
|
|
|
+ a(
|
|
|
+ ng-click="changeCurrency(currency)",
|
|
|
+ )
|
|
|
+ span.change-currency-dropdown-selected-icon(ng-show="currency == currencyCode")
|
|
|
+ i.fa.fa-check
|
|
|
+ | {{currency}} ({{value['symbol']}})
|
|
|
+
|
|
|
+ hr.thin(ng-if="trialLength || coupon")
|
|
|
+ div.trial-coupon-summary
|
|
|
+ div(ng-if="trialLength")
|
|
|
+ - var trialPriceVars = { price: "{{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.total }}", trialLen:'{{trialLength}}' };
|
|
|
+ | !{translate("first_x_days_free_after_that_y_per_month", trialPriceVars, ['strong'] )}
|
|
|
+
|
|
|
+ div(ng-if="recurlyPrice")
|
|
|
+ - var priceVars = { price: "{{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.total }}", discountMonths: "{{ coupon.discountMonths }}" };
|
|
|
+ span(ng-if="!coupon.singleUse && coupon.discountMonths > 0 && monthlyBilling")
|
|
|
+ | !{translate("x_price_for_y_months", priceVars, ['strong'] )}
|
|
|
+ span(ng-if="coupon.singleUse && monthlyBilling")
|
|
|
+ | !{translate("x_price_for_first_month", priceVars, ['strong'] )}
|
|
|
+ span(ng-if="coupon.singleUse && !monthlyBilling")
|
|
|
+ | !{translate("x_price_for_first_year", priceVars, ['strong'] )}
|
|
|
+
|
|
|
+ div(ng-if="coupon && coupon.normalPrice")
|
|
|
+ - var noDiscountPriceAngularExp = "{{ availableCurrencies[currencyCode]['symbol']}}{{coupon.normalPrice | number:2 }}";
|
|
|
+ span(ng-if="!coupon.singleUse && coupon.discountMonths > 0 && monthlyBilling")
|
|
|
+ | !{translate("then_x_price_per_month", { price: noDiscountPriceAngularExp } )}
|
|
|
+ span(ng-if="!coupon.singleUse && !coupon.discountMonths && monthlyBilling")
|
|
|
+ | !{translate("normally_x_price_per_month", { price: noDiscountPriceAngularExp } )}
|
|
|
+ span(ng-if="!coupon.singleUse && !monthlyBilling")
|
|
|
+ | !{translate("normally_x_price_per_year", { price: noDiscountPriceAngularExp } )}
|
|
|
+ span(ng-if="coupon.singleUse && monthlyBilling")
|
|
|
+ | !{translate("then_x_price_per_month", { price: noDiscountPriceAngularExp } )}
|
|
|
+ span(ng-if="coupon.singleUse && !monthlyBilling")
|
|
|
+ | !{translate("then_x_price_per_year", { price: noDiscountPriceAngularExp } )}
|
|
|
+ hr.thin
|
|
|
+
|
|
|
+ p.price-cancel-anytime.text-center(ng-non-bindable) !{translate("cancel_anytime", { appName:'{{settings.appName}}' })}
|
|
|
+
|
|
|
+ .col-md-5.col-md-push-1
|
|
|
+ .card.card-highlighted.card-border(ng-hide="threeDSecureFlow")
|
|
|
+ .alert.alert-danger(ng-show="recurlyLoadError")
|
|
|
+ strong #{translate('payment_provider_unreachable_error')}
|
|
|
+ .price-switch-header(ng-hide="recurlyLoadError")
|
|
|
+ .row
|
|
|
+ .col-xs-9
|
|
|
+ h2 #{translate('select_a_payment_method')}
|
|
|
+ .row(ng-if="planCode == 'student-annual' || planCode == 'student-monthly' || planCode == 'student_free_trial_7_days'")
|
|
|
+ .col-xs-12
|
|
|
+ p.student-disclaimer #{translate('student_disclaimer')}
|
|
|
+
|
|
|
+ .row(ng-hide="recurlyLoadError")
|
|
|
+ div()
|
|
|
+ .col-md-12()
|
|
|
+ form(
|
|
|
+ name="simpleCCForm"
|
|
|
+ novalidate
|
|
|
+ )
|
|
|
+ .alert.alert-warning.small(ng-show="genericError")
|
|
|
+ strong {{genericError}}
|
|
|
+
|
|
|
+ .alert.alert-warning.small(ng-show="couponError")
|
|
|
+ strong {{couponError}}
|
|
|
+
|
|
|
+ div
|
|
|
+ .form-group.payment-method-toggle
|
|
|
+ hr.thin
|
|
|
+ .radio
|
|
|
+ .col-xs-8
|
|
|
+ label
|
|
|
+ input(
|
|
|
+ type="radio"
|
|
|
+ ng-model="paymentMethod.value"
|
|
|
+ name="payment_method"
|
|
|
+ checked=true
|
|
|
+ value="credit_card"
|
|
|
+ )
|
|
|
+ strong
|
|
|
+ | #{translate("card_payment")}
|
|
|
+ span.hidden-xs
|
|
|
+ |
|
|
|
+ i.fa.fa-cc-visa(aria-hidden="true")
|
|
|
+ |
|
|
|
+ i.fa.fa-cc-mastercard(aria-hidden="true")
|
|
|
+ |
|
|
|
+ i.fa.fa-cc-amex(aria-hidden="true")
|
|
|
+
|
|
|
+ .col-xs-4
|
|
|
+ label
|
|
|
+ input(
|
|
|
+ type="radio"
|
|
|
+ ng-model="paymentMethod.value"
|
|
|
+ name="payment_method"
|
|
|
+ checked=false
|
|
|
+ value="paypal"
|
|
|
+ )
|
|
|
+ strong PayPal
|
|
|
+ span.hidden-xs
|
|
|
+ |
|
|
|
+ i.fa.fa-cc-paypal(aria-hidden="true")
|
|
|
+
|
|
|
+ div(ng-show="paymentMethod.value === 'credit_card'")
|
|
|
+ .form-group(ng-class="showCardElementInvalid ? 'has-error' : ''")
|
|
|
+ label(for="recurly-card-input") #{translate("card_details")}
|
|
|
+ div#recurly-card-input
|
|
|
+ span.input-feedback-message(ng-if="showCardElementInvalid") Card details are not valid
|
|
|
+
|
|
|
+ .row
|
|
|
+ .col-xs-6
|
|
|
+ .form-group(ng-class="validation.errorFields.first_name || inputHasError(simpleCCForm.firstName) ? 'has-error' : ''")
|
|
|
+ label(for="first-name") #{translate('first_name')}
|
|
|
+ input#first-name.form-control(
|
|
|
+ type="text"
|
|
|
+ maxlength='255'
|
|
|
+ data-recurly="first_name"
|
|
|
+ name="firstName"
|
|
|
+ ng-model="data.first_name"
|
|
|
+ required
|
|
|
+ )
|
|
|
+ span.input-feedback-message(ng-if="simpleCCForm.firstName.$error.required") #{translate('this_field_is_required')}
|
|
|
+ .col-xs-6
|
|
|
+ .form-group(ng-class="validation.errorFields.last_name || inputHasError(simpleCCForm.lastName)? 'has-error' : ''")
|
|
|
+ label(for="last-name") #{translate('last_name')}
|
|
|
+ input#last-name.form-control(
|
|
|
+ type="text"
|
|
|
+ maxlength='255'
|
|
|
+ data-recurly="last_name"
|
|
|
+ name="lastName"
|
|
|
+ ng-model="data.last_name"
|
|
|
+ required
|
|
|
+ )
|
|
|
+ span.input-feedback-message(ng-if="simpleCCForm.lastName.$error.required") #{translate('this_field_is_required')}
|
|
|
+
|
|
|
+ div
|
|
|
+ .row
|
|
|
+ .col-xs-12
|
|
|
+ .form-group(ng-class="validation.errorFields.address1 || inputHasError(simpleCCForm.address1) ? 'has-error' : ''")
|
|
|
+ label(for="address-line-1") #{translate('address_line_1')}
|
|
|
+ i.fa.fa-question-circle(
|
|
|
+ aria-label=translate('this_address_will_be_shown_on_the_invoice'),
|
|
|
+ tooltip=translate('this_address_will_be_shown_on_the_invoice'),
|
|
|
+ tooltip-placement="right",
|
|
|
+ tooltip-append-to-body="true",
|
|
|
+ )
|
|
|
+ input#address-line-1.form-control(
|
|
|
+ type="text"
|
|
|
+ maxlength="255"
|
|
|
+ data-recurly="address1"
|
|
|
+ name="address1"
|
|
|
+ ng-model="data.address1"
|
|
|
+ required
|
|
|
+ )
|
|
|
+ span.input-feedback-message(ng-if="simpleCCForm.address1.$error.required") #{translate('this_field_is_required')}
|
|
|
+
|
|
|
+ .row.toggle-address-second-line(ng-hide="ui.showAddressSecondLine")
|
|
|
+ .col-xs-12
|
|
|
+ a.text-small(
|
|
|
+ href="#"
|
|
|
+ ng-click="showAddressSecondLine($event)"
|
|
|
+ ) + Add another address line
|
|
|
+
|
|
|
+ .row(ng-show="ui.showAddressSecondLine")
|
|
|
+ .col-xs-12
|
|
|
+ .form-group.has-feedback(ng-class="validation.errorFields.address2 ? 'has-error' : ''")
|
|
|
+ label(for="address-line-2") #{translate('address_second_line_optional')}
|
|
|
+ input#address-line-2.form-control(
|
|
|
+ type="text"
|
|
|
+ maxlength="255"
|
|
|
+ data-recurly="address2"
|
|
|
+ name="address2"
|
|
|
+ ng-model="data.address2"
|
|
|
+ )
|
|
|
+
|
|
|
+ .row
|
|
|
+ .col-xs-4
|
|
|
+ .form-group(ng-class="validation.errorFields.postal_code || inputHasError(simpleCCForm.postalCode) ? 'has-error' : ''")
|
|
|
+ label(for="postal-code") #{translate('postal_code')}
|
|
|
+ input#postal-code.form-control(
|
|
|
+ type="text"
|
|
|
+ maxlength="255"
|
|
|
+ data-recurly="postal_code"
|
|
|
+ name="postalCode"
|
|
|
+ ng-model="data.postal_code"
|
|
|
+ required
|
|
|
+ )
|
|
|
+ span.input-feedback-message(ng-if="simpleCCForm.postalCode.$error.required") #{translate('this_field_is_required')}
|
|
|
+
|
|
|
+ .col-xs-8
|
|
|
+ .form-group(ng-class="validation.errorFields.country || inputHasError(simpleCCForm.country) ? 'has-error' : ''")
|
|
|
+ label(for="country") #{translate('country')}
|
|
|
+ select#country.form-control(
|
|
|
+ data-recurly="country"
|
|
|
+ ng-model="data.country"
|
|
|
+ name="country"
|
|
|
+ ng-change="updateCountry()"
|
|
|
+ ng-selected="{{country.code == data.country}}"
|
|
|
+ ng-model-options="{ debounce: 200 }"
|
|
|
+ required
|
|
|
+ )
|
|
|
+ option(value='', disabled) #{translate("country")}
|
|
|
+ option(value='-', disabled) --------------
|
|
|
+ option(ng-repeat="country in countries" ng-bind-html="country.name" value="{{country.code}}")
|
|
|
+ span.input-feedback-message(ng-if="simpleCCForm.country.$error.required") #{translate('this_field_is_required')}
|
|
|
+
|
|
|
+ .form-group
|
|
|
+ .checkbox
|
|
|
+ label
|
|
|
+ input(
|
|
|
+ type="checkbox"
|
|
|
+ ng-model="ui.addCompanyDetails"
|
|
|
+ )
|
|
|
+ |
|
|
|
+ | #{translate("add_company_details")}
|
|
|
+
|
|
|
+ .form-group(ng-show="ui.addCompanyDetails")
|
|
|
+ label(for="company-name") #{translate("company_name")}
|
|
|
+ input#company-name.form-control(
|
|
|
+ type="text"
|
|
|
+ name="companyName"
|
|
|
+ ng-model="data.company"
|
|
|
+ )
|
|
|
+
|
|
|
+ .form-group(ng-show="ui.addCompanyDetails && taxes.length")
|
|
|
+ label(for="vat-number") #{translate("vat_number")}
|
|
|
+ input#vat-number.form-control(
|
|
|
+ type="text"
|
|
|
+ name="vatNumber"
|
|
|
+ ng-model="data.vat_number"
|
|
|
+ ng-blur="applyVatNumber()"
|
|
|
+ )
|
|
|
+
|
|
|
+ if (showCouponField)
|
|
|
+ .form-group
|
|
|
+ label(for="coupon-code") #{translate('coupon_code')}
|
|
|
+ input#coupon-code.form-control(
|
|
|
+ type="text"
|
|
|
+ ng-blur="applyCoupon()"
|
|
|
+ ng-model="data.coupon"
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+ p(ng-if="paymentMethod.value === 'paypal'") #{translate("proceeding_to_paypal_takes_you_to_the_paypal_site_to_pay")}
|
|
|
+
|
|
|
+ hr.thin
|
|
|
+
|
|
|
+ div.payment-submit
|
|
|
+ button.btn.btn-success.btn-block(
|
|
|
+ ng-click="submit()"
|
|
|
+ ng-disabled="processing || !isFormValid(simpleCCForm);"
|
|
|
+ )
|
|
|
+ span(ng-show="processing")
|
|
|
+ i.fa.fa-spinner.fa-spin(aria-hidden="true")
|
|
|
+ span.sr-only #{translate('processing')}
|
|
|
+ |
|
|
|
+ span(ng-if="paymentMethod.value === 'credit_card'")
|
|
|
+ | {{ trialLength ? '#{translate("upgrade_cc_btn")}' : '#{translate("upgrade_now")}'}}
|
|
|
+ span(ng-if="paymentMethod.value !== 'credit_card'") #{translate("proceed_to_paypal")}
|
|
|
+
|
|
|
+ p.tos-agreement-notice !{translate("by_subscribing_you_agree_to_our_terms_of_service", {}, [{name: 'a', attrs: {href: '/legal#Terms', target:'_blank', rel:'noopener noreferrer'}}])}
|
|
|
+
|
|
|
+ div.three-d-secure-container.card.card-highlighted.card-border(ng-show="threeDSecureFlow")
|
|
|
+ .alert.alert-info.small(aria-live="assertive")
|
|
|
+ strong #{translate('card_must_be_authenticated_by_3dsecure')}
|
|
|
+ div.three-d-secure-recurly-container
|
|
|
+
|
|
|
+ script(type="text/javascript", nonce=scriptNonce).
|
|
|
+ ga('send', 'event', 'pageview', 'payment_form', "#{plan_code}")
|
|
|
+
|
|
|
+ script(
|
|
|
+ type="text/ng-template"
|
|
|
+ id="cvv-tooltip-tpl.html"
|
|
|
+ )
|
|
|
+ p !{translate("for_visa_mastercard_and_discover", {}, ['strong', 'strong', 'strong'])}
|
|
|
+ p !{translate("for_american_express", {}, ['strong', 'strong', 'strong'])}
|