UNPKG

@financial-times/n-conversion-forms

Version:

Containing jsx components and styles for forms included on Accounts and Acqusition apps (next-signup, next-profile, next-retention, etc).

325 lines (322 loc) 18.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.PaymentTerm = PaymentTerm; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _nPricing = require("@financial-times/n-pricing"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function PaymentTerm(_ref) { var _ref$fieldId = _ref.fieldId, fieldId = _ref$fieldId === void 0 ? 'paymentTermField' : _ref$fieldId, _ref$inputName = _ref.inputName, inputName = _ref$inputName === void 0 ? 'paymentTerm' : _ref$inputName, _ref$isPrintOrBundle = _ref.isPrintOrBundle, isPrintOrBundle = _ref$isPrintOrBundle === void 0 ? false : _ref$isPrintOrBundle, _ref$isEpaper = _ref.isEpaper, isEpaper = _ref$isEpaper === void 0 ? false : _ref$isEpaper, _ref$options = _ref.options, options = _ref$options === void 0 ? [] : _ref$options, _ref$isFixedTermOffer = _ref.isFixedTermOffer, isFixedTermOffer = _ref$isFixedTermOffer === void 0 ? false : _ref$isFixedTermOffer, offerDisplayName = _ref.offerDisplayName, _ref$showLegal = _ref.showLegal, showLegal = _ref$showLegal === void 0 ? true : _ref$showLegal, _ref$largePrice = _ref.largePrice, largePrice = _ref$largePrice === void 0 ? false : _ref$largePrice, _ref$optionsInARow = _ref.optionsInARow, optionsInARow = _ref$optionsInARow === void 0 ? false : _ref$optionsInARow, _ref$billingCountry = _ref.billingCountry, billingCountry = _ref$billingCountry === void 0 ? '' : _ref$billingCountry, _ref$isTermedSubscrip = _ref.isTermedSubscriptionTermType, isTermedSubscriptionTermType = _ref$isTermedSubscrip === void 0 ? false : _ref$isTermedSubscrip, _ref$isTrialOfferAsNo = _ref.isTrialOfferAsNonTrialOverride, isTrialOfferAsNonTrialOverride = _ref$isTrialOfferAsNo === void 0 ? false : _ref$isTrialOfferAsNo, _ref$labelOverride = _ref.labelOverride, labelOverride = _ref$labelOverride === void 0 ? '' : _ref$labelOverride; /** * Compute monthly price for given term name * @param {number} amount price in number format * @param {string} currency country id of the currency * @param {string} period (expressed in IS0 8601 duration format): e.g. PxY (yearly) or PxM (montly) where x is the amount of years/months * @returns {string} */ var getMonthlyPriceFromPeriod = function getMonthlyPriceFromPeriod(amount, currency, period) { var periodObj = new _nPricing.Period(period); var monthlyPrice = periodObj.calculatePrice('P1M', amount); return new _nPricing.Monthly({ value: monthlyPrice, currency: currency }).getAmount('monthly'); }; /** * returns period converted to time if found * otherwise returns empty string to avoid show information not mapped * @param {string} period (expressed in IS0 8601 duration format): PxY (yearly), PxM (montly), PxW (weekly), of PxD (daily), where x is the amount of years/months/weeks/days * @returns {string} */ var getTimeFromPeriod = function getTimeFromPeriod(period) { var periodUnitCodeToWordMap = { Y: 'years', M: 'months', W: 'weeks', D: 'days' }; var periodUnitCode = period.substring(period.length - 1); var freq = periodUnitCodeToWordMap[periodUnitCode] || ''; var amount = period.substring(1, period.length - 1); return period ? "".concat(amount, " ").concat(freq) : ''; }; var isValidPeriod = function isValidPeriod(period) { try { // Period should throw an error if it is not properly provided // in order to validate it, we just send in case type is string new _nPricing.Period(typeof period === 'string' ? period : ''); return true; } catch (e) { return false; } }; var nameMap = { annual: { title: 'Annual', price: function price(_price) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Single", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price ncf__strong" }, _price), ' ', "payment"); }, trialPrice: function trialPrice(price) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price" }, price), " per year after the trial period."); }, monthlyPrice: function monthlyPrice(price) { return price && /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__equivalent-price" }, "That\u2019s equivalent to", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__monthly-price" }, price), ' ', "per month"); }, renewsText: function renewsText() { return /*#__PURE__*/_react["default"].createElement("p", { className: "ncf__payment-term__renews-text" }, "Renews annually unless cancelled"); } }, quarterly: { title: 'Quarterly', price: function price(_price2) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price" }, _price2), " per quarter"); }, trialPrice: function trialPrice(price) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price" }, price), " per quarter after the trial period."); }, monthlyPrice: function monthlyPrice() {}, renewsText: function renewsText() { return /*#__PURE__*/_react["default"].createElement("p", { className: "ncf__payment-term__renews-text" }, "Renews quarterly unless cancelled"); } }, monthly: { title: 'Monthly', price: function price(_price3) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price" }, _price3), " per month"); }, trialPrice: function trialPrice(price) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price" }, price), " per month after the trial period."); }, monthlyPrice: function monthlyPrice() {}, renewsText: function renewsText(isFixedTermOffer) { var textToDisplay = isFixedTermOffer ? 'This subscription is for 3 months, charged monthly. You can cancel at anytime' : 'Renews monthly unless cancelled'; return /*#__PURE__*/_react["default"].createElement("p", { className: "ncf__payment-term__renews-text" }, textToDisplay); } }, custom: { price: function price(_price4) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Single", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price ncf__strong" }, _price4), ' ', "payment"); }, trialPrice: function trialPrice(_trialPrice, trialPeriod) { return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__price" }, _trialPrice), " per", ' ', trialPeriod, "after the trial period."); }, monthlyPrice: function monthlyPrice(_monthlyPrice) { return Boolean(_monthlyPrice) && /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__equivalent-price" }, "That\u2019s equivalent to", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__monthly-price" }, _monthlyPrice), ' ', "per month"); }, renewsText: function renewsText(renewalPeriod) { return !isTermedSubscriptionTermType && Boolean(renewalPeriod) && /*#__PURE__*/_react["default"].createElement("p", { className: "ncf__payment-term__renews-text" }, "Renews every ", renewalPeriod, " unless cancelled"); } } }; var createPaymentTerm = function createPaymentTerm(option) { var className = (0, _classnames["default"])(['ncf__payment-term__item', 'o-forms-input--radio-round', { 'ncf__payment-term__item--discount': option.discount }]); var props = _objectSpread({ type: 'radio', id: option.value, 'data-base-amount': option.isTrial ? option.trialAmount : option.amount, name: inputName, value: option.value, className: 'o-forms-input__radio o-forms-input__radio--right ncf__payment-term__input' }, option.selected && { defaultChecked: true }); var createDiscount = function createDiscount() { return option.discount && /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__discount" }, option.bestOffer ? 'Best offer' : "Save ".concat(option.discount, " off RRP")); }; var createB2cDiscountCopy = function createB2cDiscountCopy() { return option.name === 'annual' && option.b2cPartnership && option.b2cDiscountCopy && /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__discount" }, option.b2cDiscountCopy); }; var createDescription = function createDescription() { return option.isTrial ? /*#__PURE__*/_react["default"].createElement("div", { className: "ncf__payment-term__description" }, option.trialDuration || '4 weeks', " for", ' ', /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__payment-term__trial-price" }, option.trialPrice), /*#__PURE__*/_react["default"].createElement("br", null), nameMap[option.name] && nameMap[option.name].trialPrice(option.price)) : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, nameMap[option.name] ? /*#__PURE__*/_react["default"].createElement("div", { className: "ncf__payment-term__description" }, nameMap[option.name].price(option.price), nameMap[option.name].monthlyPrice(option.monthlyPrice), nameMap[option.name].renewsText(isFixedTermOffer)) : // this should cover the cases different than annual, quarterly and monthly // for those containing period on option.value, render custom template, for the rest keep legacy render isValidPeriod(option.value) ? /*#__PURE__*/_react["default"].createElement("div", { className: "ncf__payment-term__description" }, nameMap['custom'].price(option.price), nameMap['custom'].monthlyPrice(option.monthlyPrice && option.monthlyPrice !== '0' ? Number(option.monthlyPrice) : getMonthlyPriceFromPeriod(option.amount, option.currency, option.value)), nameMap['custom'].renewsText(getTimeFromPeriod(option.value))) : /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("span", { className: largePrice ? 'ncf__payment-term__large-price' : '' }, option.price), option.chargeOnText && /*#__PURE__*/_react["default"].createElement("p", { className: "ncf__payment-term__charge-on-text" }, option.chargeOnText))); }; var getTermDisplayName = function getTermDisplayName() { var showTrialCopyInTitle = option.isTrial && !isPrintOrBundle && !isEpaper; // https://financialtimes.atlassian.net/browse/ACQ-2592 // We need to have one specific trial offer to have terms displayed as non-trial. // The offer is a trial offer and should use trial mechanics but should show as non-trial. // There is nothing in the offer payload to identify when this should happen, we need to rely on the offer id. // This is a TEMPORARY hack and will be removed once the campaign is over. // A ticket as been raised already to deal with the clean up: https://financialtimes.atlassian.net/browse/ACQ-2593. if (isTrialOfferAsNonTrialOverride && labelOverride) { return labelOverride; } var defaultTitle = option.name && nameMap[option.name] ? nameMap[option.name].title : ''; var title = isFixedTermOffer ? "".concat(offerDisplayName, " - ").concat(defaultTitle) : defaultTitle; var termDisplayName = ''; if (showTrialCopyInTitle) { var termName = option.displayName ? option.displayName : 'Premium Digital'; termDisplayName = "Trial: ".concat(termName, " - "); } var getTermPeriod = function getTermPeriod() { // annual, quarterly and monthly if (nameMap[option.name]) { return title; } // custom offer with period provided if (isValidPeriod(option.value)) { return getTimeFromPeriod(option.value); } // custom legacy cases, where period is not provided return option.title; }; var termPeriod = getTermPeriod(); termDisplayName = "".concat(termDisplayName).concat(termPeriod, " "); return termDisplayName; }; return /*#__PURE__*/_react["default"].createElement("div", { key: option.value, className: className }, /*#__PURE__*/_react["default"].createElement("input", props), /*#__PURE__*/_react["default"].createElement("label", { htmlFor: option.value, className: "o-forms-input__label ncf__payment-term__label" }, createDiscount(), createB2cDiscountCopy(), /*#__PURE__*/_react["default"].createElement("span", { className: (0, _classnames["default"])(['ncf__payment-term__title', { 'ncf__payment-term__title--large-price': largePrice }]) }, getTermDisplayName(), option.subTitle && /*#__PURE__*/_react["default"].createElement("span", { className: "ncf__regular ncf__payment-term__sub-title" }, option.subTitle)), createDescription())); }; return /*#__PURE__*/_react["default"].createElement("div", { id: fieldId, className: "o-forms__group ncf__payment-term", "data-country-code": billingCountry }, /*#__PURE__*/_react["default"].createElement("div", { className: optionsInARow ? 'ncf__payment-term__options-grid' : '' }, options.map(function (option) { return createPaymentTerm(option); })), showLegal && /*#__PURE__*/_react["default"].createElement("div", { className: "ncf__payment-term__legal" }, isTermedSubscriptionTermType || isFixedTermOffer ? /*#__PURE__*/_react["default"].createElement("p", null, "Find out more about our cancellation policy in our", ' ', /*#__PURE__*/_react["default"].createElement("a", { className: "ncf__link--external", href: "https://help.ft.com/legal-privacy/terms-and-conditions/", title: "FT Legal Terms and Conditions help page", target: "_blank", rel: "noopener noreferrer" }, "Terms & Conditions"), ".") : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("p", null, "With all subscription types, we will automatically renew your subscription using the payment method provided unless you cancel before your renewal date."), /*#__PURE__*/_react["default"].createElement("p", null, "We will notify you at least 14 days in advance of any changes to the price in your subscription that would apply upon next renewal. Find out more about our cancellation policy in our", ' ', /*#__PURE__*/_react["default"].createElement("a", { className: "ncf__link--external", href: "https://help.ft.com/legal-privacy/terms-and-conditions/", title: "FT Legal Terms and Conditions help page", target: "_blank", rel: "noopener noreferrer" }, "Terms & Conditions"), ".")))); } PaymentTerm.propTypes = { fieldId: _propTypes["default"].string, inputName: _propTypes["default"].string, isPrintOrBundle: _propTypes["default"].bool, isEpaper: _propTypes["default"].bool, options: _propTypes["default"].arrayOf(_propTypes["default"].shape({ b2cDiscountCopy: _propTypes["default"].string, isB2cPartnership: _propTypes["default"].bool, discount: _propTypes["default"].string, isTrial: _propTypes["default"].bool, name: _propTypes["default"].string.isRequired, price: _propTypes["default"].string.isRequired, selected: _propTypes["default"].bool, trialDuration: _propTypes["default"].string, trialPrice: _propTypes["default"].string, amount: _propTypes["default"].string, trialAmount: _propTypes["default"].number, value: _propTypes["default"].string.isRequired, monthlyPrice: _propTypes["default"].string, title: _propTypes["default"].string, subTitle: _propTypes["default"].string, bestOffer: _propTypes["default"].bool, chargeOnText: _propTypes["default"].string, fulfilmentOption: _propTypes["default"].string })), isFixedTermOffer: _propTypes["default"].bool, isTermedSubscriptionTermType: _propTypes["default"].bool, offerDisplayName: _propTypes["default"].string, showLegal: _propTypes["default"].bool, largePrice: _propTypes["default"].bool, optionsInARow: _propTypes["default"].bool, billingCountry: _propTypes["default"].string, isTrialOfferAsNonTrialOverride: _propTypes["default"].bool };