@financial-times/n-conversion-forms 24.0.0 → 25.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/debug.js CHANGED
@@ -22,21 +22,21 @@ function Debug(_ref) {
22
22
  // along with onclick handlers, styles and javascript. JSX will escape and
23
23
  // modify the HTML which we do not want. Once our applications are on JSX
24
24
  // entirely this component should be rethought.
25
- var testEnvironment = "\n\t\t<span class=\"ncf__debug-environment\">\n\t\t\t<a class=\"ncf__button ncf__button--inverse ncf__debug-button--test\" onclick=\"setTestEnvironment('off');\"><strong>TEST</strong> relax you are using the test API</a>\n\t\t</span>\n\t";
26
- var productionEnvironment = "\n\t\t<span class=\"ncf__debug-environment\">\n\t\t\t<a class=\"ncf__button ncf__button--inverse ncf__debug-button--production\" onclick=\"setTestEnvironment('on');\"><strong>PRODUCTION</strong> careful you are using the production API</a>\n\t\t</span>\n\t";
27
- var testCards = "\n\t\t<button id=\"ncf-copy-uk-visa\" class=\"ncf__button ncf__button--inverse\" onclick=\"copyToClipboard('ukVisa');\" title=\"Copy UK Visa card number to clipboard\">UK Visa</button>\n\t\t<button id=\"ncf-copy-us-visa\" class=\"ncf__button ncf__button--inverse\" onclick=\"copyToClipboard('usVisa');\" title=\"Copy US Visa card number to clipboard\">US Visa</button>\n\t\t<button id=\"ncf-copy-us-amex\" class=\"ncf__button ncf__button--inverse\" onclick=\"copyToClipboard('usAmex');\" title=\"Copy US Amex card number to clipboard\">US Amex</button>\n\t";
25
+ var testEnvironment = "\n\t\t<span class=\"ncf__debug-environment\">\n\t\t\t<a class=\"ncf__button ncf__button--debug ncf__button--inverse ncf__debug-button--test\" onclick=\"setTestEnvironment('off');\"><strong>TEST</strong> relax you are using the test API</a>\n\t\t</span>\n\t";
26
+ var productionEnvironment = "\n\t\t<span class=\"ncf__debug-environment\">\n\t\t\t<a class=\"ncf__button ncf__button--debug ncf__button--inverse ncf__debug-button--production\" onclick=\"setTestEnvironment('on');\"><strong>PRODUCTION</strong> careful you are using the production API</a>\n\t\t</span>\n\t";
27
+ var testCards = "\n\t\t<button id=\"ncf-copy-visa-checkout-card\" class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"copyToClipboard('checkoutVisa');\" title=\"Copy Checkout Visa test card number to clipboard\">EU Visa (cvv:100)</button>\n\t\t<button id=\"ncf-copy-visa-checkout-3ds\" class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"copyToClipboard('checkout3dsChallenge');\" title=\"Copy Checkout cvv number (default success) to clipboard\">EU 3ds challenge</button>\n\t\t<button id=\"ncf-copy-visa-chase-card\" class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"copyToClipboard('chaseVisa');\" title=\"Copy Chase card number to clipboard\">US Visa (exp:1230,cvv:111)</button>\n\t\t<button id=\"ncf-link-checkout-cards\" class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"window.open('https://www.checkout.com/docs/testing/test-card-numbers#Credit_cards', '_blank');\" title=\"Checkout test cards documentation\">Doc:Checkout</button>\n\t";
28
28
  var linksString = Object.keys(links).map(function (link) {
29
29
  return "<a key=".concat(link, " class=\"ncf__button ncf__button--inverse ncf__link\" href=\"").concat(links[link], "\">").concat(link, "</a>");
30
30
  });
31
- var helpers = "\n\t\t<span class=\"ncf__debug-helpers\">\n\t\t\t<button class=\"ncf__button ncf__button--inverse\" onclick=\"logout();\" title=\"Logout and refresh\">Logout</button>\n\t\t\t<button class=\"ncf__button ncf__button--inverse\" onclick=\"fillForm();\" title=\"Fill form with debug data\">Fill</button>\n\t\t\t<button class=\"ncf__button ncf__button--inverse\" onclick=\"fillForm(); submitForm();\" title=\"Fill form with debug data and submit\">Fill &amp; Submit</button>\n\t\t\t".concat(isTest ? testCards : '', "\n\t\t\t").concat(links.length ? linksString : '', "\n\t\t</span>\n\t");
31
+ var helpers = "\n\t\t<span class=\"ncf__debug-helpers\">\n\t\t\t<button class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"logout();\" title=\"Logout and refresh\">Logout</button>\n\t\t\t<button class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"fillForm();\" title=\"Fill form with debug data\">Fill</button>\n\t\t\t<button class=\"ncf__button ncf__button--debug ncf__button--inverse\" onclick=\"fillForm(); submitForm();\" title=\"Fill form with debug data and submit\">Fill &amp; Submit</button>\n\t\t\t".concat(isTest ? testCards : '', "\n\t\t\t").concat(links.length ? linksString : '', "\n\t\t</span>\n\t");
32
32
  var html = {
33
33
  __html: "".concat(isTest ? testEnvironment : productionEnvironment).concat(showHelpers ? helpers : '')
34
34
  };
35
35
  var javascript = {
36
- __html: "\n\tvar FORM_SELECTOR = 'form.ncf';\n\tvar INPUT_SELECTOR = FORM_SELECTOR + ' input:not([type=\"checkbox\"]):not([type=\"radio\"])';\n\tvar SELECT_SELECTOR = FORM_SELECTOR + ' select';\n\tvar CHECKBOX_SELECTOR = FORM_SELECTOR + ' input[type=\"checkbox\"]';\n\tvar RADIO_SELECTOR = FORM_SELECTOR + ' input[type=\"radio\"]';\n\t// This env var gets set in production. We use this when creating email addresses in case any\n\t// get into production so Membership know who to come to about deleting them.\n\tvar SYSTEM_CODE = document.documentElement.getAttribute('data-next-app') || 'n-conversion-forms';\n\tvar COUNTRY_CODE = window.FT && window.FT.country || 'GBR';\n\n\tvar postcodeByCountry = {\n\t\tGBR: 'EC4M9BT',\n\t\tUSA: '10028',\n\t\tCAN: 'K0E 9Z9'\n\t}\n\n\tvar debugData = {\n\t\tbillingCity: 'London',\n\t\tbillingCountry: COUNTRY_CODE,\n\t\tbillingPostcode: postcodeByCountry[COUNTRY_CODE],\n\t\tcountry: COUNTRY_CODE,\n\t\tdeliveryAddressLine1: 'delivery test1',\n\t\tdeliveryAddressLine2: 'delivery test2',\n\t\tdeliveryAddressLine3: 'delivery test3',\n\t\tdeliveryCity: 'delivery city',\n\t\tdeliveryCounty: 'delivery county',\n\t\tdeliveryPostcode: postcodeByCountry[COUNTRY_CODE],\n\t\temail: SYSTEM_CODE + '-' + Date.now() + '@ftqa.org',\n\t\tfirstName: 'Test',\n\t\tindustry: 'DEF',\n\t\tlastName: 'Test',\n\t\tjobTitle: 'CEO',\n\t\torganisation: 'ft-org',\n\t\tpassword: 'password123',\n\t\tposition: 'AS',\n\t\tpostCode: postcodeByCountry[COUNTRY_CODE],\n\t\tprimaryTelephone: '0987654321',\n\t\tresponsibility: 'ADL',\n\t\tukVisa: '4111111111111111',\n\t\tusAmex: '378282246310005',\n\t\tusVisa: '4112344112344113'\n\t};\n\n\tfunction logout () {\n\t\tconst options = {\n\t\t\tmode: 'no-cors',\n\t\t\tcredentials: 'include'\n\t\t};\n\t\tfetch('https://www.ft.com/logout', options).then(function () {\n\t\t\twindow.location.reload();\n\t\t});\n\t}\n\n\tfunction fillForm () {\n\t\tvar changeEvent = document.createEvent('HTMLEvents');\n\t\tchangeEvent.initEvent('change', false, true);\n\n\t\tvar inputs = document.querySelectorAll(INPUT_SELECTOR + ', ' + SELECT_SELECTOR);\n\t\tinputs.forEach(function (input) {\n\t\t\tif (!/hidden/i.test(input.type)) {\n\t\t\t\tvar value = debugData[input.name];\n\t\t\t\tinput.value = value;\n\t\t\t\tinput.dispatchEvent(changeEvent);\n\t\t\t}\n\t\t});\n\t\tvar checkboxes = document.querySelectorAll(CHECKBOX_SELECTOR + ', ' + RADIO_SELECTOR);\n\t\tcheckboxes.forEach(function (checkbox) {\n\t\t\tcheckbox.checked = true;\n\t\t\tcheckbox.dispatchEvent(changeEvent);\n\t\t});\n\t}\n\n\tfunction submitForm () {\n\t\tdocument.querySelector(FORM_SELECTOR).submit();\n\t}\n\n\tfunction copyToClipboard (name) {\n\t\tvar string = debugData[name];\n\t\tvar textarea = document.createElement('textarea');\n\t\ttextarea.value = string;\n\t\tdocument.body.appendChild(textarea);\n\t\ttextarea.select();\n\t\tdocument.execCommand('copy');\n\t\tdocument.body.removeChild(textarea);\n\t}\n\n\tfunction setTestEnvironment (state) {\n\t\tvar flags = document.cookie.match('(^|[^;]+)\\\\s*next-flags\\\\s*=\\\\s*([^;]+)').pop();\n\t\tvar flag = 'conversionSandbox%3A';\n\t\tflags = flags.replace(flag + 'on', '');\n\t\tflags = flags.replace(flag + 'off', '');\n\t\tdocument.cookie = 'next-flags=' + flags + '%2C' + flag + state + '; path=/; domain=.ft.com;';\n\t\twindow.location.reload();\n\t}\n\t"
36
+ __html: "\n\tvar FORM_SELECTOR = 'form.ncf';\n\tvar INPUT_SELECTOR = FORM_SELECTOR + ' input:not([type=\"checkbox\"]):not([type=\"radio\"])';\n\tvar SELECT_SELECTOR = FORM_SELECTOR + ' select';\n\tvar CHECKBOX_SELECTOR = FORM_SELECTOR + ' input[type=\"checkbox\"]';\n\tvar RADIO_SELECTOR = FORM_SELECTOR + ' input[type=\"radio\"]';\n\t// This env var gets set in production. We use this when creating email addresses in case any\n\t// get into production so Membership know who to come to about deleting them.\n\tvar SYSTEM_CODE = document.documentElement.getAttribute('data-next-app') || 'n-conversion-forms';\n\tvar COUNTRY_CODE = window.FT && window.FT.country || 'GBR';\n\n\tvar postcodeByCountry = {\n\t\tGBR: 'EC4M9BT',\n\t\tUSA: '10028',\n\t\tCAN: 'K0E 9Z9'\n\t};\n\n\tvar debugData = {\n\t\tbillingCity: 'London',\n\t\tbillingCountry: COUNTRY_CODE,\n\t\tbillingPostcode: postcodeByCountry[COUNTRY_CODE],\n\t\tcountry: COUNTRY_CODE,\n\t\tdeliveryAddressLine1: 'delivery test1',\n\t\tdeliveryAddressLine2: 'delivery test2',\n\t\tdeliveryAddressLine3: 'delivery test3',\n\t\tdeliveryCity: 'delivery city',\n\t\tdeliveryCounty: 'delivery county',\n\t\tdeliveryPostcode: postcodeByCountry[COUNTRY_CODE],\n\t\temail: SYSTEM_CODE + '-' + Date.now() + '@ftqa.org',\n\t\tfirstName: 'Test',\n\t\tindustry: 'DEF',\n\t\tlastName: 'Test',\n\t\tjobTitle: 'CEO',\n\t\torganisation: 'ft-org',\n\t\tpassword: 'password123',\n\t\tposition: 'AS',\n\t\tpostCode: postcodeByCountry[COUNTRY_CODE],\n\t\tprimaryTelephone: '0987654321',\n\t\tresponsibility: 'ADL',\n\t\tukVisaWorldpay: '4111111111111111',\n\t\tusAmex: '378282246310005',\n\t\tusVisaWorldpay: '4112344112344113',\n\t\tcheckoutVisa: '4242424242424242',\n\t\tcheckout3dsChallenge: 'Checkout1!',\n\t\tchaseVisa: '4011361100000010',\n\t};\n\n\tfunction logout () {\n\t\tconst options = {\n\t\t\tmode: 'no-cors',\n\t\t\tcredentials: 'include'\n\t\t};\n\t\tfetch('https://www.ft.com/logout', options).then(function () {\n\t\t\twindow.location.reload();\n\t\t});\n\t}\n\n\tfunction fillForm () {\n\t\tvar changeEvent = document.createEvent('HTMLEvents');\n\t\tchangeEvent.initEvent('change', false, true);\n\n\t\tvar inputs = document.querySelectorAll(INPUT_SELECTOR + ', ' + SELECT_SELECTOR);\n\t\tinputs.forEach(function (input) {\n\t\t\tif (!/hidden/i.test(input.type)) {\n\t\t\t\tvar value = debugData[input.name];\n\t\t\t\tinput.value = value;\n\t\t\t\tinput.dispatchEvent(changeEvent);\n\t\t\t}\n\t\t});\n\t\tvar checkboxes = document.querySelectorAll(CHECKBOX_SELECTOR + ', ' + RADIO_SELECTOR);\n\t\tcheckboxes.forEach(function (checkbox) {\n\t\t\tcheckbox.checked = true;\n\t\t\tcheckbox.dispatchEvent(changeEvent);\n\t\t});\n\t}\n\n\tfunction submitForm () {\n\t\tdocument.querySelector(FORM_SELECTOR).submit();\n\t}\n\n\tfunction copyToClipboard (name) {\n\t\tvar string = debugData[name];\n\t\tvar textarea = document.createElement('textarea');\n\t\ttextarea.value = string;\n\t\tdocument.body.appendChild(textarea);\n\t\ttextarea.select();\n\t\tdocument.execCommand('copy');\n\t\tdocument.body.removeChild(textarea);\n\t}\n\n\tfunction setTestEnvironment (state) {\n\t\tvar flags = document.cookie.match('(^|[^;]+)\\\\s*next-flags\\\\s*=\\\\s*([^;]+)').pop();\n\t\tvar flag = 'conversionSandbox%3A';\n\t\tflags = flags.replace(flag + 'on', '');\n\t\tflags = flags.replace(flag + 'off', '');\n\t\tdocument.cookie = 'next-flags=' + flags + '%2C' + flag + state + '; path=/; domain=.ft.com;';\n\t\twindow.location.reload();\n\t}\n\t"
37
37
  };
38
38
  var style = {
39
- __html: "\n\t.ncf__debug-panel {\n\t\tposition: absolute;\n\t\tbackground-color: #262a33;\n\t\tcolor: #ffffff;\n\t\tbottom: 0;\n\t\tleft: 0;\n\t\twidth: 100%;\n\t\tpadding: 10px;\n\t\tposition: fixed;\n\t\tz-index: 1000;\n\t\topacity: 0.8;\n\t}\n\t.ncf__debug-button--test {\n\t\tbackground-color: #008040;\n\t}\n\t.ncf__debug-button--production {\n\t\tbackground-color: #990000;\n\t}\n\t"
39
+ __html: "\n\t.ncf__debug-panel {\n\t\tposition: absolute;\n\t\tbackground-color: #262a33;\n\t\tcolor: #ffffff;\n\t\tbottom: 0;\n\t\tleft: 0;\n\t\twidth: 100%;\n\t\tpadding: 10px;\n\t\tposition: fixed;\n\t\tz-index: 1000;\n\t\topacity: 0.8;\n\t}\n\t.ncf__debug-button--test {\n\t\tbackground-color: #008040;\n\t}\n\t.ncf__debug-button--production {\n\t\tbackground-color: #990000;\n\t}\n\t.ncf__button--debug {\n\t\tpadding: 0px 5px;\n\t}\n\t"
40
40
  };
41
41
  return (isTest || showHelpers) && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("div", {
42
42
  className: "ncf__debug-panel",
package/dist/index.js CHANGED
@@ -21,12 +21,6 @@ Object.defineProperty(exports, "B2CPartnershipConfirmation", {
21
21
  return _b2cPartnershipConfirmation.B2CPartnershipConfirmation;
22
22
  }
23
23
  });
24
- Object.defineProperty(exports, "B2cPartnershipPaymentTerm", {
25
- enumerable: true,
26
- get: function get() {
27
- return _b2cPartnershipPaymentTerm.B2cPartnershipPaymentTerm;
28
- }
29
- });
30
24
  Object.defineProperty(exports, "BillingCity", {
31
25
  enumerable: true,
32
26
  get: function get() {
@@ -333,6 +327,12 @@ Object.defineProperty(exports, "Submit", {
333
327
  return _submit.Submit;
334
328
  }
335
329
  });
330
+ Object.defineProperty(exports, "TextInput", {
331
+ enumerable: true,
332
+ get: function get() {
333
+ return _textInput.TextInput;
334
+ }
335
+ });
336
336
  Object.defineProperty(exports, "TrialBanner", {
337
337
  enumerable: true,
338
338
  get: function get() {
@@ -344,8 +344,6 @@ var _acceptTerms = require("./accept-terms");
344
344
 
345
345
  var _appBanner = require("./app-banner");
346
346
 
347
- var _b2cPartnershipPaymentTerm = require("./b2c-partnership-payment-term");
348
-
349
347
  var _billingCity = require("./billing-city");
350
348
 
351
349
  var _billingCountry = require("./billing-country");
@@ -450,4 +448,6 @@ var _graduationDate = require("./graduation-date");
450
448
 
451
449
  var _liteSubConfirmation = require("./lite-sub-confirmation");
452
450
 
453
- var _googleSignIn = require("./google-sign-in");
451
+ var _googleSignIn = require("./google-sign-in");
452
+
453
+ var _textInput = require("./text-input");
@@ -49,14 +49,14 @@ function PaymentTerm(_ref) {
49
49
  * @param {string} period PxY (yearly) or PxM (montly) where x is the amount of years/months
50
50
  * @returns {string}
51
51
  */
52
- function getMontlyPriceFromPeriod(amount, currency, period) {
52
+ var getMontlyPriceFromPeriod = function getMontlyPriceFromPeriod(amount, currency, period) {
53
53
  var periodObj = new _nPricing.Period(period);
54
54
  var monthlyPrice = periodObj.calculatePrice('P1M', amount);
55
55
  return new _nPricing.Monthly({
56
56
  value: monthlyPrice,
57
57
  currency: currency
58
58
  }).getAmount('monthly');
59
- }
59
+ };
60
60
  /**
61
61
  * returns period converted to time if found
62
62
  * otherwise returns empty string to avoid show information not mapped
@@ -195,6 +195,12 @@ function PaymentTerm(_ref) {
195
195
  }, option.bestOffer ? 'Best offer' : "Save ".concat(option.discount, " off RRP"));
196
196
  };
197
197
 
198
+ var createB2cDiscountCopy = function createB2cDiscountCopy() {
199
+ return option.name === 'annual' && option.b2cPartnership && option.b2cDiscountCopy && /*#__PURE__*/_react["default"].createElement("span", {
200
+ className: "ncf__payment-term__discount"
201
+ }, option.b2cDiscountCopy);
202
+ };
203
+
198
204
  var createDescription = function createDescription() {
199
205
  return option.isTrial ? /*#__PURE__*/_react["default"].createElement("div", {
200
206
  className: "ncf__payment-term__description"
@@ -250,7 +256,7 @@ function PaymentTerm(_ref) {
250
256
  }, /*#__PURE__*/_react["default"].createElement("input", props), /*#__PURE__*/_react["default"].createElement("label", {
251
257
  htmlFor: option.value,
252
258
  className: "o-forms-input__label ncf__payment-term__label"
253
- }, createDiscount(), /*#__PURE__*/_react["default"].createElement("span", {
259
+ }, createDiscount(), createB2cDiscountCopy(), /*#__PURE__*/_react["default"].createElement("span", {
254
260
  className: (0, _classnames["default"])(['ncf__payment-term__title', {
255
261
  'ncf__payment-term__title--large-price': largePrice
256
262
  }])
@@ -289,6 +295,8 @@ PaymentTerm.propTypes = {
289
295
  isPrintOrBundle: _propTypes["default"].bool,
290
296
  isEpaper: _propTypes["default"].bool,
291
297
  options: _propTypes["default"].arrayOf(_propTypes["default"].shape({
298
+ b2cDiscountCopy: _propTypes["default"].string,
299
+ isB2cPartnership: _propTypes["default"].bool,
292
300
  discount: _propTypes["default"].string,
293
301
  isTrial: _propTypes["default"].bool,
294
302
  name: _propTypes["default"].string.isRequired,
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.TextInput = TextInput;
9
+
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
+
14
+ var _classnames = _interopRequireDefault(require("classnames"));
15
+
16
+ function TextInput(_ref) {
17
+ var dataTrackable = _ref.dataTrackable,
18
+ _ref$errorText = _ref.errorText,
19
+ errorText = _ref$errorText === void 0 ? 'Please enter a value' : _ref$errorText,
20
+ fieldId = _ref.fieldId,
21
+ _ref$hasError = _ref.hasError,
22
+ hasError = _ref$hasError === void 0 ? false : _ref$hasError,
23
+ inputId = _ref.inputId,
24
+ inputName = _ref.inputName,
25
+ _ref$isDisabled = _ref.isDisabled,
26
+ isDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled,
27
+ _ref$isRequired = _ref.isRequired,
28
+ isRequired = _ref$isRequired === void 0 ? false : _ref$isRequired,
29
+ _ref$label = _ref.label,
30
+ label = _ref$label === void 0 ? '' : _ref$label,
31
+ _ref$placeHolder = _ref.placeHolder,
32
+ placeHolder = _ref$placeHolder === void 0 ? '' : _ref$placeHolder,
33
+ _ref$value = _ref.value,
34
+ value = _ref$value === void 0 ? '' : _ref$value,
35
+ description = _ref.description;
36
+ // Use inputId if inputName is not explicitly passed.
37
+ inputName = inputName || inputId;
38
+ var inputWrapperClassNames = (0, _classnames["default"])(['o-forms-input', 'o-forms-input--text', {
39
+ 'o-forms-input--invalid': hasError
40
+ }, {
41
+ 'o-forms-field--optional': !isRequired
42
+ }]);
43
+ return /*#__PURE__*/_react["default"].createElement("label", {
44
+ id: fieldId,
45
+ className: "o-forms-field ncf__validation-error",
46
+ "data-validate": "required",
47
+ htmlFor: inputId
48
+ }, /*#__PURE__*/_react["default"].createElement("span", {
49
+ className: "o-forms-title"
50
+ }, /*#__PURE__*/_react["default"].createElement("span", {
51
+ className: "o-forms-title__main"
52
+ }, label), description ? /*#__PURE__*/_react["default"].createElement("span", {
53
+ className: "o-forms-title__prompt"
54
+ }, description) : null), /*#__PURE__*/_react["default"].createElement("span", {
55
+ className: inputWrapperClassNames
56
+ }, /*#__PURE__*/_react["default"].createElement("input", {
57
+ type: "text",
58
+ id: inputId,
59
+ name: inputName,
60
+ placeholder: placeHolder,
61
+ "data-trackable": dataTrackable,
62
+ "aria-required": isRequired,
63
+ required: isRequired,
64
+ disabled: isDisabled,
65
+ defaultValue: value
66
+ }), /*#__PURE__*/_react["default"].createElement("span", {
67
+ className: "o-forms-input__error"
68
+ }, errorText)));
69
+ }
70
+
71
+ TextInput.propTypes = {
72
+ dataTrackable: _propTypes["default"].string,
73
+ errorText: _propTypes["default"].string,
74
+ fieldId: _propTypes["default"].string,
75
+ hasError: _propTypes["default"].bool,
76
+ inputId: _propTypes["default"].string,
77
+ inputName: _propTypes["default"].string,
78
+ isDisabled: _propTypes["default"].bool,
79
+ isRequired: _propTypes["default"].bool,
80
+ label: _propTypes["default"].string,
81
+ placeHolder: _propTypes["default"].string,
82
+ value: _propTypes["default"].string,
83
+ description: _propTypes["default"].string
84
+ };
package/main.scss CHANGED
@@ -10,7 +10,6 @@
10
10
  @import '@financial-times/o-fonts/main';
11
11
  @import './styles/package-change';
12
12
  @import './styles/payment-term';
13
- @import './styles/b2c-partnership-payment-term';
14
13
  @import './styles/payment-type';
15
14
  @import './styles/loader';
16
15
  @import './styles/accept-terms';
@@ -436,7 +435,6 @@
436
435
  @include ncfMessage();
437
436
  @include ncfPackageChange();
438
437
  @include ncfPaymentTerm();
439
- @include ncfB2cPartnershipPaymentTerm();
440
438
  @include ncfPaymentType();
441
439
  @include ncfLoader();
442
440
  @include ncfContinueReading();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-conversion-forms",
3
- "version": "24.0.0",
3
+ "version": "25.1.0",
4
4
  "description": "Containing jsx components and styles for forms included on Accounts and Acqusition apps (next-signup, next-profile, next-retention, etc).",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -1,3 +1,8 @@
1
+ const {
2
+ Period,
3
+ Monthly,
4
+ } = require('@financial-times/n-pricing');
5
+
1
6
  /**
2
7
  * Utility for the `n-conversion-forms/partial/payment-term.html` partial
3
8
  * @example
@@ -75,6 +80,23 @@ class PaymentTerm {
75
80
  return this.$paymentTerm.addEventListener('change', callback);
76
81
  }
77
82
 
83
+ isValidPeriod (period) {
84
+ try {
85
+ // Period should throw an error if it is not properly provided
86
+ // in order to validate it, we just send in case type is string
87
+ new Period(typeof period === 'string' ? period : '');
88
+ return true;
89
+ } catch (e) {
90
+ return false;
91
+ }
92
+ };
93
+
94
+ getMontlyPriceFromPeriod (amount, currency, period) {
95
+ const periodObj = new Period(period);
96
+ const monthlyPrice = periodObj.calculatePrice('P1M', amount);
97
+ return new Monthly({ value: monthlyPrice, currency }).getAmount('monthly');
98
+ }
99
+
78
100
  /**
79
101
  * Update the payment term options
80
102
  * @param {Array} options Array of objects contain terms information
@@ -104,7 +126,9 @@ class PaymentTerm {
104
126
  trialPrice.innerHTML = update.trialPrice;
105
127
  }
106
128
  if (monthlyPrice) {
107
- monthlyPrice.innerHTML = update.monthlyPrice;
129
+ monthlyPrice.innerHTML = this.isValidPeriod(update.value) ?
130
+ this.getMontlyPriceFromPeriod(update.amount, update.currency, update.value) :
131
+ update.monthlyPrice;
108
132
  }
109
133
  }
110
134
  }
@@ -1,193 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`B2cPartnershipPaymentTerm render with minimum props required 1`] = `
4
- <div id="paymentTermField"
5
- class="o-forms__group ncf__payment-term ncf__b2c-partnership-payment-term"
6
- >
7
- <div class="ncf__payment-term__item o-forms-input--radio-round">
8
- <input type="radio"
9
- id="299.99"
10
- name="paymentTerm"
11
- value="299.99"
12
- checked
13
- >
14
- <label for="299.99"
15
- class="o-forms-input__label ncf__payment-term__label"
16
- >
17
- <span class="ncf__payment-term__title">
18
- £299.99 - Digital FT + The Washington Post
19
- </span>
20
- <div class="ncf__b2c-partnership-payment-term__description">
21
- <p>
22
- Includes:
23
- <br>
24
- 1 year Digital subscription to the Financial Times
25
- <br>
26
- 90-day All-Access Digital subscription to The Washington Post
27
- </p>
28
- </div>
29
- </label>
30
- </div>
31
- <div class="ncf__payment-term__legal">
32
- <p>
33
- We will automatically renew your subscription using the payment method provided unless you cancel before your renewal date.
34
- </p>
35
- <p>
36
- 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
37
- <a class="ncf__link--external"
38
- href="https://help.ft.com/help/legal-privacy/terms-conditions/"
39
- title="FT Legal Terms and Conditions help page"
40
- target="_blank"
41
- rel="noopener noreferrer"
42
- >
43
- Terms &amp; Conditions
44
- </a>
45
- .
46
- </p>
47
- </div>
48
- </div>
49
- `;
50
-
51
- exports[`B2cPartnershipPaymentTerm renders with annual option 1`] = `
52
- <div id="paymentTermField"
53
- class="o-forms__group ncf__payment-term ncf__b2c-partnership-payment-term"
54
- >
55
- <div class="ncf__payment-term__item o-forms-input--radio-round">
56
- <input type="radio"
57
- id="annual"
58
- name="paymentTerm"
59
- value="annual"
60
- checked
61
- >
62
- <label for="annual"
63
- class="o-forms-input__label ncf__payment-term__label"
64
- >
65
- <span class="ncf__payment-term__title">
66
- £20.00 - Digital FT + The Washington Post
67
- </span>
68
- <div class="ncf__b2c-partnership-payment-term__description">
69
- <p>
70
- Includes:
71
- <br>
72
- 1 year Digital subscription to the Financial Times
73
- <br>
74
- 90-day All-Access Digital subscription to The Washington Post
75
- </p>
76
- </div>
77
- </label>
78
- </div>
79
- <div class="ncf__payment-term__legal">
80
- <p>
81
- We will automatically renew your subscription using the payment method provided unless you cancel before your renewal date.
82
- </p>
83
- <p>
84
- 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
85
- <a class="ncf__link--external"
86
- href="https://help.ft.com/help/legal-privacy/terms-conditions/"
87
- title="FT Legal Terms and Conditions help page"
88
- target="_blank"
89
- rel="noopener noreferrer"
90
- >
91
- Terms &amp; Conditions
92
- </a>
93
- .
94
- </p>
95
- </div>
96
- </div>
97
- `;
98
-
99
- exports[`B2cPartnershipPaymentTerm renders with monthly option 1`] = `
100
- <div id="paymentTermField"
101
- class="o-forms__group ncf__payment-term ncf__b2c-partnership-payment-term"
102
- >
103
- <div class="ncf__payment-term__item o-forms-input--radio-round">
104
- <input type="radio"
105
- id="monthly"
106
- name="paymentTerm"
107
- value="monthly"
108
- checked
109
- >
110
- <label for="monthly"
111
- class="o-forms-input__label ncf__payment-term__label"
112
- >
113
- <span class="ncf__payment-term__title">
114
- £20.00 - Digital FT + The Washington Post
115
- </span>
116
- <div class="ncf__b2c-partnership-payment-term__description">
117
- <p>
118
- Includes:
119
- <br>
120
- 1 month Digital subscription to the Financial Times
121
- <br>
122
- 90-day All-Access Digital subscription to The Washington Post
123
- </p>
124
- </div>
125
- </label>
126
- </div>
127
- <div class="ncf__payment-term__legal">
128
- <p>
129
- We will automatically renew your subscription using the payment method provided unless you cancel before your renewal date.
130
- </p>
131
- <p>
132
- 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
133
- <a class="ncf__link--external"
134
- href="https://help.ft.com/help/legal-privacy/terms-conditions/"
135
- title="FT Legal Terms and Conditions help page"
136
- target="_blank"
137
- rel="noopener noreferrer"
138
- >
139
- Terms &amp; Conditions
140
- </a>
141
- .
142
- </p>
143
- </div>
144
- </div>
145
- `;
146
-
147
- exports[`B2cPartnershipPaymentTerm renders with quarterly option 1`] = `
148
- <div id="paymentTermField"
149
- class="o-forms__group ncf__payment-term ncf__b2c-partnership-payment-term"
150
- >
151
- <div class="ncf__payment-term__item o-forms-input--radio-round">
152
- <input type="radio"
153
- id="quarterly"
154
- name="paymentTerm"
155
- value="quarterly"
156
- checked
157
- >
158
- <label for="quarterly"
159
- class="o-forms-input__label ncf__payment-term__label"
160
- >
161
- <span class="ncf__payment-term__title">
162
- £20.00 - Digital FT + The Washington Post
163
- </span>
164
- <div class="ncf__b2c-partnership-payment-term__description">
165
- <p>
166
- Includes:
167
- <br>
168
- 3 month Digital subscription to the Financial Times
169
- <br>
170
- 90-day All-Access Digital subscription to The Washington Post
171
- </p>
172
- </div>
173
- </label>
174
- </div>
175
- <div class="ncf__payment-term__legal">
176
- <p>
177
- We will automatically renew your subscription using the payment method provided unless you cancel before your renewal date.
178
- </p>
179
- <p>
180
- 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
181
- <a class="ncf__link--external"
182
- href="https://help.ft.com/help/legal-privacy/terms-conditions/"
183
- title="FT Legal Terms and Conditions help page"
184
- target="_blank"
185
- rel="noopener noreferrer"
186
- >
187
- Terms &amp; Conditions
188
- </a>
189
- .
190
- </p>
191
- </div>
192
- </div>
193
- `;
@@ -1,126 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- export function B2cPartnershipPaymentTerm ({
5
- fieldId = 'paymentTermField',
6
- inputName = 'paymentTerm',
7
- options = [],
8
- displayName,
9
- offerType,
10
- partnerOffer,
11
- conditions = [],
12
- }) {
13
- const durations = {
14
- annual: '1 year',
15
- quarterly: '3 month',
16
- monthly: '1 month',
17
- };
18
-
19
- // convert to Title Case
20
- offerType = offerType
21
- .split('')
22
- .map((letter, i) => (i !== 0 ? letter.toLowerCase() : letter.toUpperCase()))
23
- .join('');
24
-
25
- return (
26
- <div
27
- id={fieldId}
28
- className="o-forms__group ncf__payment-term ncf__b2c-partnership-payment-term"
29
- >
30
- {options.map(
31
- (option) =>
32
- option.selected && (
33
- <div
34
- className="ncf__payment-term__item o-forms-input--radio-round"
35
- key={option.value}
36
- >
37
- <input
38
- type="radio"
39
- id={option.value}
40
- name={inputName}
41
- value={option.value}
42
- defaultChecked={true}
43
- />
44
- <label
45
- htmlFor={option.value}
46
- className="o-forms-input__label ncf__payment-term__label"
47
- >
48
- <span className="ncf__payment-term__title">
49
- {option.price} - {displayName}
50
- </span>
51
- <div className="ncf__b2c-partnership-payment-term__description">
52
- <p>
53
- Includes:
54
- <br />
55
- {durations[option.name]} {offerType} subscription to the
56
- Financial Times
57
- <br />
58
- {partnerOffer.duration} {partnerOffer.name} subscription to{' '}
59
- {partnerOffer.vendor}
60
- </p>
61
- {conditions.length > 0 && (
62
- <p>
63
- {conditions.map((line) => (
64
- <>
65
- {line}
66
- <br />
67
- </>
68
- ))}
69
- </p>
70
- )}
71
- </div>
72
- </label>
73
- </div>
74
- )
75
- )}
76
-
77
- <div className="ncf__payment-term__legal">
78
- <p>
79
- We will automatically renew your subscription using the payment method
80
- provided unless you cancel before your renewal date.
81
- </p>
82
- <p>
83
- We will notify you at least 14 days in advance of any changes to the
84
- price in your subscription that would apply upon next renewal. Find
85
- out more about our cancellation policy in our{' '}
86
- <a
87
- className="ncf__link--external"
88
- href="https://help.ft.com/help/legal-privacy/terms-conditions/"
89
- title="FT Legal Terms and Conditions help page"
90
- target="_blank"
91
- rel="noopener noreferrer"
92
- >
93
- Terms &amp; Conditions
94
- </a>
95
- .
96
- </p>
97
- </div>
98
- </div>
99
- );
100
- }
101
-
102
- B2cPartnershipPaymentTerm.propTypes = {
103
- fieldId: PropTypes.string,
104
- inputName: PropTypes.string,
105
- options: PropTypes.arrayOf(
106
- PropTypes.shape({
107
- discount: PropTypes.string,
108
- isTrial: PropTypes.bool,
109
- name: PropTypes.string.isRequired,
110
- price: PropTypes.string.isRequired,
111
- selected: PropTypes.bool,
112
- trialDuration: PropTypes.string,
113
- trialPrice: PropTypes.string,
114
- value: PropTypes.string.isRequired,
115
- monthlyPrice: PropTypes.string,
116
- })
117
- ).isRequired,
118
- displayName: PropTypes.string.isRequired,
119
- partnerOffer: PropTypes.shape({
120
- duration: PropTypes.string.isRequired,
121
- name: PropTypes.string.isRequired,
122
- vendor: PropTypes.string.isRequired,
123
- }).isRequired,
124
- conditions: PropTypes.arrayOf(PropTypes.string),
125
- offerType: PropTypes.string.isRequired,
126
- };
@@ -1,52 +0,0 @@
1
- import { B2cPartnershipPaymentTerm } from './index';
2
- import { expectToRenderCorrectly } from '../test-jest/helpers/expect-to-render-correctly';
3
-
4
- expect.extend(expectToRenderCorrectly);
5
-
6
- const defaultProps = {
7
- displayName: 'Digital FT + The Washington Post',
8
- partnerOffer: {
9
- duration: '90-day',
10
- name: 'All-Access Digital',
11
- vendor: 'The Washington Post',
12
- },
13
- offerType: 'DIGITAL',
14
- options: [
15
- {
16
- name: 'annual',
17
- price: '£299.99',
18
- value: 299.99,
19
- isTrial: false,
20
- discount: null,
21
- selected: true,
22
- },
23
- ],
24
- };
25
-
26
- describe('B2cPartnershipPaymentTerm', () => {
27
- it('render with minimum props required', () => {
28
- const props = {
29
- ...defaultProps,
30
- };
31
-
32
- expect(B2cPartnershipPaymentTerm).toRenderCorrectly(props);
33
- });
34
-
35
- ['annual', 'quarterly', 'monthly'].forEach((type) => {
36
- it(`renders with ${type} option`, () => {
37
- const props = {
38
- ...defaultProps,
39
- options: [
40
- {
41
- name: type,
42
- value: type,
43
- price: '£20.00',
44
- selected: true,
45
- },
46
- ],
47
- };
48
-
49
- expect(B2cPartnershipPaymentTerm).toRenderCorrectly(props);
50
- });
51
- });
52
- });