@financial-times/n-conversion-forms 25.2.0 → 27.0.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.
@@ -78,7 +78,7 @@ exports[`Debug renders with isTest 1`] = `
78
78
 
79
79
  var inputs = document.querySelectorAll(INPUT_SELECTOR + ', ' + SELECT_SELECTOR);
80
80
  inputs.forEach(function (input) {
81
- if (!/hidden/i.test(input.type)) {
81
+ if (!/hidden/i.test(input.type) && input.disabled === false) {
82
82
  var value = debugData[input.name];
83
83
  input.value = value;
84
84
  input.dispatchEvent(changeEvent);
@@ -237,7 +237,7 @@ exports[`Debug renders with showHelpers 1`] = `
237
237
 
238
238
  var inputs = document.querySelectorAll(INPUT_SELECTOR + ', ' + SELECT_SELECTOR);
239
239
  inputs.forEach(function (input) {
240
- if (!/hidden/i.test(input.type)) {
240
+ if (!/hidden/i.test(input.type) && input.disabled === false) {
241
241
  var value = debugData[input.name];
242
242
  input.value = value;
243
243
  input.dispatchEvent(changeEvent);
@@ -175,7 +175,7 @@ exports[`Delivery Postcode renders a postcode input with a label set as postal c
175
175
  <input type="text"
176
176
  id="deliveryPostcode"
177
177
  name="deliveryPostcode"
178
- placeholder="e.g. M4W 2C6"
178
+ placeholder="e.g. M5H 3E5"
179
179
  autocomplete="postal-code"
180
180
  data-trackable="delivery-postcode"
181
181
  aria-required="true"
@@ -18,7 +18,7 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
18
18
  `;
19
19
  const testCards = `
20
20
  <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>
21
- <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>
21
+ <button id="ncf-copy-visa-checkout-3ds" class="ncf__button ncf__button--debug ncf__button--inverse" onclick="copyToClipboard('checkout3dsChallenge');" title="Copy Checkout challenge code -Checkout1!- to clipboard">EU 3ds challenge</button>
22
22
  <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>
23
23
  <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>
24
24
  `;
@@ -104,7 +104,7 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
104
104
 
105
105
  var inputs = document.querySelectorAll(INPUT_SELECTOR + ', ' + SELECT_SELECTOR);
106
106
  inputs.forEach(function (input) {
107
- if (!/hidden/i.test(input.type)) {
107
+ if (!/hidden/i.test(input.type) && input.disabled === false) {
108
108
  var value = debugData[input.name];
109
109
  input.value = value;
110
110
  input.dispatchEvent(changeEvent);
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
-
4
+ import deliveryAddressMap from '../helpers/deliveryAddressMap';
5
+ import { identifyFTShippingZone, countriesSupportedISO } from '../helpers/supportedCountries';
5
6
  export function DeliveryAddress ({
6
7
  fieldId = 'deliveryAddressFields',
7
8
  hasError = false,
@@ -11,36 +12,16 @@ export function DeliveryAddress ({
11
12
  isDisabled = false,
12
13
  isHidden = false,
13
14
  country = 'GBR',
15
+ addressType = 'home',
14
16
  }) {
15
17
  const divClassNames = classNames([{ ncf__hidden: isHidden }]);
16
-
17
18
  const inputWrapperClassNames = classNames([
18
19
  'o-forms-input',
19
20
  'o-forms-input--text',
20
21
  { 'o-forms-input--invalid': hasError },
21
22
  ]);
23
+ const FTShippingZone = identifyFTShippingZone(country);
22
24
 
23
- const addressLine3Title = {
24
- GBR: 'Address line 3',
25
- USA: 'APT/FL/STE',
26
- CAN: 'APT/FL/STE',
27
- };
28
-
29
- const addressLine3Prompt = {
30
- USA: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
31
- CAN: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
32
- };
33
-
34
- const addressLine3Placeholder = {
35
- USA: 'e.g Apt 2C / FL 10 / STE 50',
36
- CAN: 'e.g Apt 2C / FL 10 / STE 50',
37
- };
38
-
39
- const addressLine1Placeholder = {
40
- GBR: 'e.g. 10 Elm Street',
41
- USA: 'e.g. 10 Elm St.',
42
- CAN: 'e.g. 36 Poirier Blvd.',
43
- };
44
25
 
45
26
  const addressLine1 = (
46
27
  <label
@@ -48,7 +29,9 @@ export function DeliveryAddress ({
48
29
  htmlFor="deliveryAddressLine1"
49
30
  >
50
31
  <span className="o-forms-title">
51
- <span className="o-forms-title__main">Address line 1</span>
32
+ <span className="o-forms-title__main">
33
+ {deliveryAddressMap[addressType].addressLine1Title[FTShippingZone] || 'Address line 1'}
34
+ </span>
52
35
  </span>
53
36
  <span className={inputWrapperClassNames}>
54
37
  <input
@@ -57,7 +40,7 @@ export function DeliveryAddress ({
57
40
  name="deliveryAddressLine1"
58
41
  data-trackable="field-deliveryAddressLine1"
59
42
  autoComplete="address-line1"
60
- placeholder={addressLine1Placeholder[country]}
43
+ placeholder={deliveryAddressMap[addressType].addressLine1Placeholder[FTShippingZone]}
61
44
  maxLength={50}
62
45
  aria-required="true"
63
46
  required
@@ -86,7 +69,7 @@ export function DeliveryAddress ({
86
69
  name="deliveryAddressLine2"
87
70
  data-trackable="field-deliveryAddressLine2"
88
71
  autoComplete="address-line2"
89
- placeholder=""
72
+ placeholder={deliveryAddressMap[addressType].addressLine2Placeholder[FTShippingZone] || ''}
90
73
  maxLength={50}
91
74
  disabled={isDisabled}
92
75
  defaultValue={line2}
@@ -102,10 +85,10 @@ export function DeliveryAddress ({
102
85
  >
103
86
  <span className="o-forms-title">
104
87
  <span className="o-forms-title__main">
105
- {addressLine3Title[country]}
88
+ {deliveryAddressMap[addressType].addressLine3Title[FTShippingZone]}
106
89
  </span>
107
90
  <span className="o-forms-title__prompt">
108
- {addressLine3Prompt[country]}
91
+ {deliveryAddressMap[addressType].addressLine3Prompt[FTShippingZone]}
109
92
  </span>
110
93
  </span>
111
94
  <span className={inputWrapperClassNames}>
@@ -115,7 +98,7 @@ export function DeliveryAddress ({
115
98
  name="deliveryAddressLine3"
116
99
  data-trackable="field-deliveryAddressLine3"
117
100
  autoComplete="address-line3"
118
- placeholder={addressLine3Placeholder[country] || 'e.g. Apt. 1'}
101
+ placeholder={deliveryAddressMap[addressType].addressLine3Placeholder[FTShippingZone] || 'e.g. Apt. 1'}
119
102
  maxLength={50}
120
103
  disabled={isDisabled}
121
104
  defaultValue={line3}
@@ -123,37 +106,16 @@ export function DeliveryAddress ({
123
106
  </span>
124
107
  </label>
125
108
  );
126
-
127
- const addressLines = {
128
- GBR: (
129
- <>
130
- {' '}
131
- {addressLine1}
132
- {addressLine2}
133
- {addressLine3}{' '}
134
- </>
135
- ),
136
- USA: (
137
- <>
138
- {' '}
139
- {addressLine1}
140
- {addressLine3}
141
- {addressLine2}{' '}
142
- </>
143
- ),
144
- CAN: (
145
- <>
146
- {' '}
147
- {addressLine1}
148
- {addressLine3}
149
- {addressLine2}{' '}
150
- </>
151
- ),
152
- };
109
+ const addressLines = deliveryAddressMap[addressType].template(
110
+ addressLine1,
111
+ addressLine2,
112
+ addressLine3,
113
+ FTShippingZone
114
+ );
153
115
 
154
116
  return (
155
117
  <div id={fieldId} data-validate="required" className={divClassNames}>
156
- {addressLines[country]}
118
+ {addressLines}
157
119
  </div>
158
120
  );
159
121
  }
@@ -166,5 +128,6 @@ DeliveryAddress.propTypes = {
166
128
  line3: PropTypes.string,
167
129
  isDisabled: PropTypes.bool,
168
130
  isHidden: PropTypes.bool,
169
- country: PropTypes.oneOf(['GBR', 'USA', 'CAN']),
131
+ country: PropTypes.oneOf(countriesSupportedISO),
132
+ addressType: PropTypes.oneOf(['home', 'company', 'pobox']),
170
133
  };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { DeliveryAddress } from './delivery-address';
3
+ import { countriesSupportedISO } from '../helpers/supportedCountries';
3
4
 
4
5
  export default {
5
6
  title: 'Delivery Address',
@@ -12,6 +13,12 @@ export default {
12
13
  line3: { control: 'string' },
13
14
  isDisabled: { control: 'boolean' },
14
15
  isHidden: { control: 'boolean' },
16
+ country: {
17
+ control: {
18
+ type: 'inline-radio',
19
+ options: countriesSupportedISO,
20
+ },
21
+ },
15
22
  },
16
23
  };
17
24
 
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
+ import { countriesSupportedISO } from '../helpers/supportedCountries';
5
+
4
6
 
5
7
  export function DeliveryCity ({
6
8
  hasError = false,
@@ -37,7 +39,7 @@ export function DeliveryCity ({
37
39
  name="deliveryCity"
38
40
  data-trackable="field-deliveryCity"
39
41
  autoComplete="address-level2"
40
- placeholder={inputPlaceholder[country]}
42
+ placeholder={inputPlaceholder[country] || ''}
41
43
  maxLength={40}
42
44
  aria-required="true"
43
45
  required
@@ -57,5 +59,5 @@ DeliveryCity.propTypes = {
57
59
  value: PropTypes.string,
58
60
  isDisabled: PropTypes.bool,
59
61
  maxlength: PropTypes.number,
60
- country: PropTypes.oneOf(['GBR', 'USA', 'CAN']),
62
+ country: PropTypes.oneOf(countriesSupportedISO),
61
63
  };
@@ -1,9 +1,18 @@
1
1
  import React from 'react';
2
2
  import { DeliveryCity } from './delivery-city';
3
+ import { countriesSupportedISO } from '../helpers/supportedCountries';
3
4
 
4
5
  export default {
5
6
  title: 'Delivery City',
6
7
  component: DeliveryCity,
8
+ argTypes: {
9
+ country: {
10
+ control: {
11
+ type: 'inline-radio',
12
+ options: countriesSupportedISO,
13
+ },
14
+ },
15
+ },
7
16
  };
8
17
 
9
18
  export const Basic = (args) => <DeliveryCity {...args} />;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import { getDeliveryOption } from '../utils/delivery-option-messages';
5
+ import { identifyFTShippingZone, countriesSupportedISO } from '../helpers/supportedCountries';
5
6
 
6
7
  export function DeliveryOption ({
7
8
  fieldId = 'deliveryOptionField',
@@ -16,6 +17,8 @@ export function DeliveryOption ({
16
17
  { 'ncf__delivery-option--single': isSingle },
17
18
  ]);
18
19
 
20
+ const FTShippingZone = identifyFTShippingZone(country);
21
+
19
22
  return (
20
23
  <div
21
24
  id={fieldId}
@@ -26,11 +29,10 @@ export function DeliveryOption ({
26
29
  <span className="o-forms-input o-forms-input--radio-round">
27
30
  {options.map((option) => {
28
31
  const { value, isValidDeliveryOption, isSelected } = option;
29
-
30
32
  const deliveryOptionValue = getDeliveryOption(
31
33
  productCode,
32
34
  option,
33
- country
35
+ FTShippingZone
34
36
  );
35
37
 
36
38
  if (!isValidDeliveryOption || !deliveryOptionValue) {
@@ -73,7 +75,7 @@ export function DeliveryOption ({
73
75
  }
74
76
 
75
77
  DeliveryOption.propTypes = {
76
- country: PropTypes.oneOf(['GBR', 'USA', 'CAN']).isRequired,
78
+ country: PropTypes.oneOf(countriesSupportedISO).isRequired,
77
79
  productCode: PropTypes.string,
78
80
  options: PropTypes.arrayOf(
79
81
  PropTypes.shape({
@@ -1,12 +1,18 @@
1
1
  import React from 'react';
2
2
  import { DeliveryOption } from './delivery-option';
3
+ import { countriesSupportedISO } from '../helpers/supportedCountries';
3
4
 
4
5
  export default {
5
6
  title: 'Delivery Options',
6
7
  component: DeliveryOption,
7
8
  argTypes: {
8
9
  options: { control: 'array' },
9
- country: { control: 'string' },
10
+ country: {
11
+ control: {
12
+ type: 'inline-radio',
13
+ options: countriesSupportedISO,
14
+ },
15
+ },
10
16
  productCode: { control: 'string' },
11
17
  },
12
18
  };
@@ -1,22 +1,41 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
+ import { countriesSupported } from '../helpers/supportedCountries';
5
+ import { allSupportedPostcodeExamples } from '../helpers/supportedPostcodeExamples';
4
6
 
5
- const postcodeLabel = {
6
- USA: 'Zip Code',
7
- CAN: 'Postal Code',
8
- };
9
-
10
- const promptLabel = {
11
- USA: 'Please enter your 5 digit Zip Code',
12
- CAN: 'Please enter your 6 digit postal code',
13
- };
7
+ const postcodeLabel = Object.keys(countriesSupported).reduce((previous, countryCode) => {
8
+ if (countryCode === 'USA') {
9
+ previous[countryCode] = 'Zip Code';
10
+ } else if (countryCode === 'GBR') {
11
+ previous[countryCode] = 'Postcode';
12
+ } else {
13
+ previous[countryCode] = 'Postal Code';
14
+ }
15
+ return previous;
16
+ }
17
+ , {}
18
+ );
14
19
 
15
- const placeholderLabel = {
16
- USA: 'e.g. 60411',
17
- CAN: 'e.g. M4W 2C6',
18
- };
20
+ const promptLabel = Object.keys(countriesSupported).reduce((previous, countryCode) => {
21
+ if (countryCode === 'USA') {
22
+ previous[countryCode] = 'Please enter your 5 digit Zip Code';
23
+ } else if (countryCode === 'CAN') {
24
+ previous[countryCode] = 'Please enter your 6 digit postal code';
25
+ } else if (countryCode !== 'GBR') { //GBR has no label
26
+ previous[countryCode] = 'Please enter your postal code';
27
+ }
28
+ return previous;
29
+ }
30
+ , {}
31
+ );
19
32
 
33
+ const placeholderLabel = Object.keys(allSupportedPostcodeExamples).reduce((previous, countryCode) => {
34
+ previous[countryCode] = 'e.g. ' + allSupportedPostcodeExamples[countryCode];
35
+ return previous;
36
+ }
37
+ , {}
38
+ );
20
39
  export function DeliveryPostcode ({
21
40
  value = '',
22
41
  country = '',
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { DeliveryPostcode } from './delivery-postcode';
3
+ import { countriesSupportedISO } from '../helpers/supportedCountries';
3
4
 
4
5
  export default {
5
6
  title: 'Delivery Postcode',
@@ -9,7 +10,7 @@ export default {
9
10
  country: {
10
11
  control: {
11
12
  type: 'inline-radio',
12
- options: ['USA', 'CAN', 'Other'],
13
+ options: countriesSupportedISO,
13
14
  },
14
15
  },
15
16
  },
package/dist/debug.js CHANGED
@@ -24,7 +24,7 @@ function Debug(_ref) {
24
24
  // entirely this component should be rethought.
25
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
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";
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 challenge code -Checkout1!- 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
  });
@@ -33,7 +33,7 @@ function Debug(_ref) {
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\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"
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) && input.disabled === false) {\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
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"
@@ -13,6 +13,10 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
14
  var _classnames = _interopRequireDefault(require("classnames"));
15
15
 
16
+ var _deliveryAddressMap = _interopRequireDefault(require("../helpers/deliveryAddressMap"));
17
+
18
+ var _supportedCountries = require("../helpers/supportedCountries");
19
+
16
20
  function DeliveryAddress(_ref) {
17
21
  var _ref$fieldId = _ref.fieldId,
18
22
  fieldId = _ref$fieldId === void 0 ? 'deliveryAddressFields' : _ref$fieldId,
@@ -29,31 +33,16 @@ function DeliveryAddress(_ref) {
29
33
  _ref$isHidden = _ref.isHidden,
30
34
  isHidden = _ref$isHidden === void 0 ? false : _ref$isHidden,
31
35
  _ref$country = _ref.country,
32
- country = _ref$country === void 0 ? 'GBR' : _ref$country;
36
+ country = _ref$country === void 0 ? 'GBR' : _ref$country,
37
+ _ref$addressType = _ref.addressType,
38
+ addressType = _ref$addressType === void 0 ? 'home' : _ref$addressType;
33
39
  var divClassNames = (0, _classnames["default"])([{
34
40
  ncf__hidden: isHidden
35
41
  }]);
36
42
  var inputWrapperClassNames = (0, _classnames["default"])(['o-forms-input', 'o-forms-input--text', {
37
43
  'o-forms-input--invalid': hasError
38
44
  }]);
39
- var addressLine3Title = {
40
- GBR: 'Address line 3',
41
- USA: 'APT/FL/STE',
42
- CAN: 'APT/FL/STE'
43
- };
44
- var addressLine3Prompt = {
45
- USA: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
46
- CAN: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”'
47
- };
48
- var addressLine3Placeholder = {
49
- USA: 'e.g Apt 2C / FL 10 / STE 50',
50
- CAN: 'e.g Apt 2C / FL 10 / STE 50'
51
- };
52
- var addressLine1Placeholder = {
53
- GBR: 'e.g. 10 Elm Street',
54
- USA: 'e.g. 10 Elm St.',
55
- CAN: 'e.g. 36 Poirier Blvd.'
56
- };
45
+ var FTShippingZone = (0, _supportedCountries.identifyFTShippingZone)(country);
57
46
 
58
47
  var addressLine1 = /*#__PURE__*/_react["default"].createElement("label", {
59
48
  className: "o-forms-field ncf__validation-error",
@@ -62,7 +51,7 @@ function DeliveryAddress(_ref) {
62
51
  className: "o-forms-title"
63
52
  }, /*#__PURE__*/_react["default"].createElement("span", {
64
53
  className: "o-forms-title__main"
65
- }, "Address line 1")), /*#__PURE__*/_react["default"].createElement("span", {
54
+ }, _deliveryAddressMap["default"][addressType].addressLine1Title[FTShippingZone] || 'Address line 1')), /*#__PURE__*/_react["default"].createElement("span", {
66
55
  className: inputWrapperClassNames
67
56
  }, /*#__PURE__*/_react["default"].createElement("input", {
68
57
  type: "text",
@@ -70,7 +59,7 @@ function DeliveryAddress(_ref) {
70
59
  name: "deliveryAddressLine1",
71
60
  "data-trackable": "field-deliveryAddressLine1",
72
61
  autoComplete: "address-line1",
73
- placeholder: addressLine1Placeholder[country],
62
+ placeholder: _deliveryAddressMap["default"][addressType].addressLine1Placeholder[FTShippingZone],
74
63
  maxLength: 50,
75
64
  "aria-required": "true",
76
65
  required: true,
@@ -95,7 +84,7 @@ function DeliveryAddress(_ref) {
95
84
  name: "deliveryAddressLine2",
96
85
  "data-trackable": "field-deliveryAddressLine2",
97
86
  autoComplete: "address-line2",
98
- placeholder: "",
87
+ placeholder: _deliveryAddressMap["default"][addressType].addressLine2Placeholder[FTShippingZone] || '',
99
88
  maxLength: 50,
100
89
  disabled: isDisabled,
101
90
  defaultValue: line2
@@ -108,9 +97,9 @@ function DeliveryAddress(_ref) {
108
97
  className: "o-forms-title"
109
98
  }, /*#__PURE__*/_react["default"].createElement("span", {
110
99
  className: "o-forms-title__main"
111
- }, addressLine3Title[country]), /*#__PURE__*/_react["default"].createElement("span", {
100
+ }, _deliveryAddressMap["default"][addressType].addressLine3Title[FTShippingZone]), /*#__PURE__*/_react["default"].createElement("span", {
112
101
  className: "o-forms-title__prompt"
113
- }, addressLine3Prompt[country])), /*#__PURE__*/_react["default"].createElement("span", {
102
+ }, _deliveryAddressMap["default"][addressType].addressLine3Prompt[FTShippingZone])), /*#__PURE__*/_react["default"].createElement("span", {
114
103
  className: inputWrapperClassNames
115
104
  }, /*#__PURE__*/_react["default"].createElement("input", {
116
105
  type: "text",
@@ -118,22 +107,19 @@ function DeliveryAddress(_ref) {
118
107
  name: "deliveryAddressLine3",
119
108
  "data-trackable": "field-deliveryAddressLine3",
120
109
  autoComplete: "address-line3",
121
- placeholder: addressLine3Placeholder[country] || 'e.g. Apt. 1',
110
+ placeholder: _deliveryAddressMap["default"][addressType].addressLine3Placeholder[FTShippingZone] || 'e.g. Apt. 1',
122
111
  maxLength: 50,
123
112
  disabled: isDisabled,
124
113
  defaultValue: line3
125
114
  })));
126
115
 
127
- var addressLines = {
128
- GBR: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, ' ', addressLine1, addressLine2, addressLine3, ' '),
129
- USA: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, ' ', addressLine1, addressLine3, addressLine2, ' '),
130
- CAN: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, ' ', addressLine1, addressLine3, addressLine2, ' ')
131
- };
116
+ var addressLines = _deliveryAddressMap["default"][addressType].template(addressLine1, addressLine2, addressLine3, FTShippingZone);
117
+
132
118
  return /*#__PURE__*/_react["default"].createElement("div", {
133
119
  id: fieldId,
134
120
  "data-validate": "required",
135
121
  className: divClassNames
136
- }, addressLines[country]);
122
+ }, addressLines);
137
123
  }
138
124
 
139
125
  DeliveryAddress.propTypes = {
@@ -144,5 +130,6 @@ DeliveryAddress.propTypes = {
144
130
  line3: _propTypes["default"].string,
145
131
  isDisabled: _propTypes["default"].bool,
146
132
  isHidden: _propTypes["default"].bool,
147
- country: _propTypes["default"].oneOf(['GBR', 'USA', 'CAN'])
133
+ country: _propTypes["default"].oneOf(_supportedCountries.countriesSupportedISO),
134
+ addressType: _propTypes["default"].oneOf(['home', 'company', 'pobox'])
148
135
  };
@@ -13,6 +13,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
14
  var _classnames = _interopRequireDefault(require("classnames"));
15
15
 
16
+ var _supportedCountries = require("../helpers/supportedCountries");
17
+
16
18
  function DeliveryCity(_ref) {
17
19
  var _ref$hasError = _ref.hasError,
18
20
  hasError = _ref$hasError === void 0 ? false : _ref$hasError,
@@ -47,7 +49,7 @@ function DeliveryCity(_ref) {
47
49
  name: "deliveryCity",
48
50
  "data-trackable": "field-deliveryCity",
49
51
  autoComplete: "address-level2",
50
- placeholder: inputPlaceholder[country],
52
+ placeholder: inputPlaceholder[country] || '',
51
53
  maxLength: 40,
52
54
  "aria-required": "true",
53
55
  required: true,
@@ -63,5 +65,5 @@ DeliveryCity.propTypes = {
63
65
  value: _propTypes["default"].string,
64
66
  isDisabled: _propTypes["default"].bool,
65
67
  maxlength: _propTypes["default"].number,
66
- country: _propTypes["default"].oneOf(['GBR', 'USA', 'CAN'])
68
+ country: _propTypes["default"].oneOf(_supportedCountries.countriesSupportedISO)
67
69
  };
@@ -15,6 +15,8 @@ var _classnames = _interopRequireDefault(require("classnames"));
15
15
 
16
16
  var _deliveryOptionMessages = require("../utils/delivery-option-messages");
17
17
 
18
+ var _supportedCountries = require("../helpers/supportedCountries");
19
+
18
20
  function DeliveryOption(_ref) {
19
21
  var _ref$fieldId = _ref.fieldId,
20
22
  fieldId = _ref$fieldId === void 0 ? 'deliveryOptionField' : _ref$fieldId,
@@ -28,6 +30,7 @@ function DeliveryOption(_ref) {
28
30
  var divClassName = (0, _classnames["default"])(['o-forms-field', 'ncf__delivery-option', {
29
31
  'ncf__delivery-option--single': isSingle
30
32
  }]);
33
+ var FTShippingZone = (0, _supportedCountries.identifyFTShippingZone)(country);
31
34
  return /*#__PURE__*/_react["default"].createElement("div", {
32
35
  id: fieldId,
33
36
  className: divClassName,
@@ -39,7 +42,7 @@ function DeliveryOption(_ref) {
39
42
  var value = option.value,
40
43
  isValidDeliveryOption = option.isValidDeliveryOption,
41
44
  isSelected = option.isSelected;
42
- var deliveryOptionValue = (0, _deliveryOptionMessages.getDeliveryOption)(productCode, option, country);
45
+ var deliveryOptionValue = (0, _deliveryOptionMessages.getDeliveryOption)(productCode, option, FTShippingZone);
43
46
 
44
47
  if (!isValidDeliveryOption || !deliveryOptionValue) {
45
48
  return null;
@@ -70,7 +73,7 @@ function DeliveryOption(_ref) {
70
73
  }
71
74
 
72
75
  DeliveryOption.propTypes = {
73
- country: _propTypes["default"].oneOf(['GBR', 'USA', 'CAN']).isRequired,
76
+ country: _propTypes["default"].oneOf(_supportedCountries.countriesSupportedISO).isRequired,
74
77
  productCode: _propTypes["default"].string,
75
78
  options: _propTypes["default"].arrayOf(_propTypes["default"].shape({
76
79
  value: _propTypes["default"].oneOf(['PV', 'HD', 'EV']),
@@ -13,18 +13,37 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
14
  var _classnames = _interopRequireDefault(require("classnames"));
15
15
 
16
- var postcodeLabel = {
17
- USA: 'Zip Code',
18
- CAN: 'Postal Code'
19
- };
20
- var promptLabel = {
21
- USA: 'Please enter your 5 digit Zip Code',
22
- CAN: 'Please enter your 6 digit postal code'
23
- };
24
- var placeholderLabel = {
25
- USA: 'e.g. 60411',
26
- CAN: 'e.g. M4W 2C6'
27
- };
16
+ var _supportedCountries = require("../helpers/supportedCountries");
17
+
18
+ var _supportedPostcodeExamples = require("../helpers/supportedPostcodeExamples");
19
+
20
+ var postcodeLabel = Object.keys(_supportedCountries.countriesSupported).reduce(function (previous, countryCode) {
21
+ if (countryCode === 'USA') {
22
+ previous[countryCode] = 'Zip Code';
23
+ } else if (countryCode === 'GBR') {
24
+ previous[countryCode] = 'Postcode';
25
+ } else {
26
+ previous[countryCode] = 'Postal Code';
27
+ }
28
+
29
+ return previous;
30
+ }, {});
31
+ var promptLabel = Object.keys(_supportedCountries.countriesSupported).reduce(function (previous, countryCode) {
32
+ if (countryCode === 'USA') {
33
+ previous[countryCode] = 'Please enter your 5 digit Zip Code';
34
+ } else if (countryCode === 'CAN') {
35
+ previous[countryCode] = 'Please enter your 6 digit postal code';
36
+ } else if (countryCode !== 'GBR') {
37
+ //GBR has no label
38
+ previous[countryCode] = 'Please enter your postal code';
39
+ }
40
+
41
+ return previous;
42
+ }, {});
43
+ var placeholderLabel = Object.keys(_supportedPostcodeExamples.allSupportedPostcodeExamples).reduce(function (previous, countryCode) {
44
+ previous[countryCode] = 'e.g. ' + _supportedPostcodeExamples.allSupportedPostcodeExamples[countryCode];
45
+ return previous;
46
+ }, {});
28
47
 
29
48
  function DeliveryPostcode(_ref) {
30
49
  var _ref$value = _ref.value,
@@ -0,0 +1,7 @@
1
+ const printRegions = {
2
+ cemeaV1: 'CEMEA_V1',
3
+ cemeaV2: 'CEMEA_V2',
4
+ apac: 'APAC'
5
+ };
6
+
7
+ module.exports = { printRegions };
@@ -0,0 +1,167 @@
1
+ const React = require('react');
2
+
3
+ const addressTemplateGenerator = (addressLine1, addressLine2, addressLine3) => (<>
4
+ {' '}
5
+ {addressLine1}
6
+ {addressLine2}
7
+ {addressLine3}{' '}
8
+ </>);
9
+
10
+ const deliveryAddressMap = {
11
+ 'home': {
12
+ addressLine1Placeholder: {
13
+ GBR: 'e.g. 10 Elm Street',
14
+ USA: 'e.g. 10 Elm St.',
15
+ CAN: 'e.g. 36 Poirier Blvd.',
16
+ CEMEA_V1: 'Street and House Number',
17
+ CEMEA_V2: 'House Number and Street',
18
+ APAC: 'Street name',
19
+ ARE: 'PO Box 12345'
20
+ },
21
+ addressLine2Placeholder: {
22
+ CEMEA_V1: 'Apt No./Floor/Building',
23
+ CEMEA_V2: 'Apt No./Floor/Building',
24
+ APAC: 'House/Apartment/Building name',
25
+ },
26
+ addressLine3Placeholder: {
27
+ USA: 'e.g Apt 2C / FL 10 / STE 50',
28
+ CAN: 'e.g Apt 2C / FL 10 / STE 50',
29
+ CEMEA_V1: ' ',
30
+ CEMEA_V2: ' ',
31
+ APAC: 'District/County/Province/Ward',
32
+ },
33
+ addressLine1Title:{
34
+ 'ARE': 'PO Box',
35
+ },
36
+ addressLine3Title: {
37
+ GBR: 'Address line 3',
38
+ USA: 'APT/FL/STE',
39
+ CAN: 'APT/FL/STE',
40
+ CEMEA_V1: 'Address line 3',
41
+ CEMEA_V2: 'Address line 3',
42
+ },
43
+ addressLine3Prompt: {
44
+ USA: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
45
+ CAN: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
46
+ },
47
+ template: (addressLine1, addressLine2, addressLine3, region) => {
48
+ const addressLines = {
49
+ GBR: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
50
+ USA: addressTemplateGenerator(addressLine1, addressLine3, addressLine2),
51
+ CAN: addressTemplateGenerator(addressLine1, addressLine3, addressLine2),
52
+
53
+ CEMEA_V1: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
54
+ CEMEA_V2: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
55
+ APAC: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
56
+ ARE:(
57
+ <>
58
+ {' '}
59
+ {addressLine1}{' '}
60
+ </>
61
+ )
62
+ };
63
+ return addressLines[region];
64
+ }
65
+ },
66
+ 'company': {
67
+ addressLine1Placeholder: {
68
+ GBR: 'e.g. 10 Elm Street',
69
+ USA: 'e.g. 10 Elm St.',
70
+ CAN: 'e.g. 36 Poirier Blvd.',
71
+ CEMEA_V1: 'Street and House Number',
72
+ CEMEA_V2: 'House Number and Street',
73
+ APAC: 'Street name',
74
+ ARE: 'PO Box 12345'
75
+ },
76
+ addressLine2Placeholder: {
77
+ CEMEA_V1: 'Apt No./Floor/Building/Department',
78
+ CEMEA_V2: 'Apt No./Floor/Building/Department',
79
+ APAC: 'House/Apartment/Building name',
80
+ },
81
+ addressLine3Placeholder: {
82
+ USA: 'e.g Apt 2C / FL 10 / STE 50',
83
+ CAN: 'e.g Apt 2C / FL 10 / STE 50',
84
+ CEMEA_V1: 'Department name/job title',
85
+ CEMEA_V2: 'Department name/job title',
86
+ APAC: 'District/County/Province/Ward',
87
+ },
88
+ addressLine3Title: {
89
+ GBR: 'Address line 3',
90
+ USA: 'APT/FL/STE',
91
+ CAN: 'APT/FL/STE',
92
+ CEMEA_V1: 'Address line 3',
93
+ CEMEA_V3: 'Address line 3',
94
+ },
95
+ addressLine3Prompt: {
96
+ USA: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
97
+ CAN: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
98
+ },
99
+ addressLine1Title:{
100
+ 'ARE': 'PO Box',
101
+ },
102
+ template: (addressLine1, addressLine2, addressLine3, region) => {
103
+ const addressLines = {
104
+ GBR: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
105
+ USA: addressTemplateGenerator(addressLine1, addressLine3, addressLine2),
106
+ CAN: addressTemplateGenerator(addressLine1, addressLine3, addressLine2),
107
+
108
+ CEMEA_V1: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
109
+ CEMEA_V2: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
110
+ APAC: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
111
+ ARE:(
112
+ <>
113
+ {' '}
114
+ {addressLine1}{' '}
115
+ </>
116
+ )
117
+ };
118
+ return addressLines[region];
119
+ }
120
+ },
121
+ 'pobox': {
122
+ addressLine1Placeholder: {
123
+ GBR: 'e.g. 10 Elm Street',
124
+ USA: 'e.g. 10 Elm St.',
125
+ CAN: 'e.g. 36 Poirier Blvd.',
126
+ CEMEA_V1: 'P.O. Box',
127
+ CEMEA_V2: 'P.O. Box',
128
+ },
129
+ addressLine2Placeholder: {
130
+ },
131
+ addressLine3Placeholder: {
132
+ },
133
+ addressLine1Title:{},
134
+ addressLine3Title: {
135
+ GBR: 'Address line 3',
136
+ USA: 'APT/FL/STE',
137
+ CAN: 'APT/FL/STE',
138
+ },
139
+ addressLine3Prompt: {
140
+ USA: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
141
+ CAN: 'Max. 6 characters. Please enter “Apartment 2C” as “Apt 2C”, “Floor 10 as FL 10”',
142
+ },
143
+ template: (addressLine1, addressLine2, addressLine3, region) => {
144
+ const addressLines = {
145
+ GBR: addressTemplateGenerator(addressLine1, addressLine2, addressLine3),
146
+ USA: addressTemplateGenerator(addressLine1, addressLine3, addressLine2),
147
+ CAN: addressTemplateGenerator(addressLine1, addressLine3, addressLine2),
148
+
149
+ CEMEA_V1: (
150
+ <>
151
+ {' '}
152
+ {addressLine1}{' '}
153
+ </>
154
+ ),
155
+ CEMEA_V2:(
156
+ <>
157
+ {' '}
158
+ {addressLine1}{' '}
159
+ </>
160
+ )
161
+ };
162
+ return addressLines[region];
163
+ }
164
+ },
165
+ };
166
+
167
+ module.exports = deliveryAddressMap;
package/helpers/index.js CHANGED
@@ -1,4 +1,11 @@
1
1
  module.exports = {
2
2
  'ncf-countries': require('./ncf-countries'),
3
3
  'ncf-common-data': require('./ncf-common-data'),
4
+ 'cemeaV1ISO': require('./supportedCountries').cemeaV1ISO,
5
+ 'cemeaV2ISO': require('./supportedCountries').cemeaV2ISO,
6
+ 'apacISO': require('./supportedCountries').apacISO,
7
+ 'countriesSupported': require('./supportedCountries').countriesSupported,
8
+ 'countriesSupportedISO': require('./supportedCountries').countriesSupportedISO,
9
+ 'supportedPostcodeValidators': require('./supportedPostcodeValidators').supportedPostcodeValidators,
10
+ 'allSupportedPostcodeExamples': require('./supportedPostcodeExamples').allSupportedPostcodeExamples,
4
11
  };
@@ -0,0 +1,76 @@
1
+ const { flattenObj } = require('./utilities');
2
+ const { printRegions } = require('./constants');
3
+
4
+ const supportedCountriesMasterList = {
5
+ cemeaV1: {
6
+ AUT: 'Austria',
7
+ ARE: 'United Arab Emirates',
8
+ BEL: 'Belgium',
9
+ BGR: 'Bulgaria',
10
+ HRV: 'Croatia',
11
+ CZE: 'Czechia',
12
+ DNK: 'Denmark',
13
+ FIN: 'Finland',
14
+ DEU: 'Germany',
15
+ GRC: 'Greece',
16
+ HUN: 'Hungary',
17
+ ISL: 'Iceland',
18
+ ITA: 'Italy',
19
+ LIE: 'Liechtenstein',
20
+ LTU: 'Lithuania',
21
+ NLD: 'Netherlands',
22
+ NOR: 'Norway',
23
+ POL: 'Poland',
24
+ PRT: 'Portugal',
25
+ QAT: 'Qatar',
26
+ ROU: 'Romania',
27
+ RUS: 'Russian Federation',
28
+ SVK: 'Slovakia',
29
+ SVN: 'Slovenia',
30
+ ZAF: 'South Africa',
31
+ ESP: 'Spain',
32
+ SWE: 'Sweden',
33
+ CHE: 'Switzerland'
34
+ },
35
+ cemeaV2: { FRA: 'France', LUX: 'Luxembourg', MCO: 'Monaco' },
36
+ apac: {
37
+ CHN: 'China',
38
+ HKG: 'Hong Kong',
39
+ IND: 'India',
40
+ IDN: 'Indonesia',
41
+ JPN: 'Japan',
42
+ KOR: 'Korea, Republic of',
43
+ MYS: 'Malaysia',
44
+ PHL: 'Philippines',
45
+ SGP: 'Singapore',
46
+ TWN: 'Taiwan, Province of China',
47
+ THA: 'Thailand'
48
+ },
49
+ other: {
50
+ GBR: 'United Kingdom',
51
+ USA: 'United States',
52
+ CAN: 'Canada'
53
+ }
54
+ };
55
+
56
+ const cemeaV1ISO = Object.keys(supportedCountriesMasterList.cemeaV1);
57
+ const cemeaV2ISO = Object.keys(supportedCountriesMasterList.cemeaV2);
58
+ const apacISO = Object.keys(supportedCountriesMasterList.apac);
59
+
60
+ const countriesSupported = flattenObj(supportedCountriesMasterList);
61
+ const countriesSupportedISO = Object.keys(countriesSupported);
62
+
63
+ const identifyFTShippingZone = (country) => {
64
+ if (cemeaV1ISO.includes(country)) {
65
+ return printRegions.cemeaV1;
66
+ }
67
+ if (cemeaV2ISO.includes(country)) {
68
+ return printRegions.cemeaV2;
69
+ }
70
+ if (apacISO.includes(country)) {
71
+ return printRegions.apac;
72
+ }
73
+ return country;
74
+ };
75
+
76
+ module.exports = { cemeaV1ISO, cemeaV2ISO, apacISO, countriesSupported, countriesSupportedISO, identifyFTShippingZone };
@@ -0,0 +1,57 @@
1
+ const { flattenObj } = require('./utilities');
2
+
3
+ const supportedPostcodeExamples = {
4
+ cemeaV1: {
5
+ AUT: '17087',
6
+ ARE: '', //match anything
7
+ BEL: '6596',
8
+ BGR: '4000',
9
+ HRV: '10000',
10
+ CZE: '00 100',
11
+ DNK: '1819',
12
+ FIN: '39500',
13
+ DEU: '17087',
14
+ GRC: '241 00',
15
+ HUN: '3821',
16
+ ISL: '60411',
17
+ ITA: '23844',
18
+ LIE: '9480',
19
+ LTU: 'LT-12345',
20
+ NLD: '6971 HJ',
21
+ NOR: '1608',
22
+ POL: '43-190',
23
+ PRT: '2525-517',
24
+ QAT: '',//match anything
25
+ ROU: '71234',
26
+ RUS: '191028',
27
+ SVK: '98401',
28
+ SVN: '8263',
29
+ ZAF: '5189',
30
+ ESP: '37752',
31
+ SWE: '260 38',
32
+ CHE: '9424'
33
+ },
34
+ cemeaV2: { FRA: '95000', LUX: '1009', MCO: '98000' },
35
+ apac: {
36
+ CHN: '610000',
37
+ HKG: '', //match anything
38
+ IND: '401107',
39
+ IDN: '55165',
40
+ JPN: '100-0001',
41
+ KOR: '46500',
42
+ MYS: '59100',
43
+ PHL: '2799',
44
+ SGP: '58416',
45
+ TWN: '100',
46
+ THA: '10330'
47
+ },
48
+ other: {
49
+ GBR: 'EC4M 9BT',
50
+ USA: '60411',
51
+ CAN: 'M5H 3E5'
52
+ }
53
+ };
54
+
55
+ const allSupportedPostcodeExamples = flattenObj(supportedPostcodeExamples);
56
+
57
+ module.exports = { allSupportedPostcodeExamples };
@@ -0,0 +1,53 @@
1
+ const supportedPostcodeValidators = {
2
+ cemeaV1: {
3
+ AUT: /^\\d{4}$/,
4
+ ARE: /.*$/, //match anything
5
+ BEL: /^\\d{4}$/,
6
+ BGR: /^\\d{4}$/,
7
+ HRV: /^\\d{5}$/,
8
+ CZE: /^\\d{5}\\s\\(\\d{3}\\s\\d{2}\\)$/,
9
+ DNK: /^\\d{4}$/,
10
+ FIN: /^\\d{5}$/,
11
+ DEU: /^\\d{5}$/,
12
+ GRC: /^\\d{3}\\s{0,1}\\d{2}$/,
13
+ HUN: /^\\d{4}$/,
14
+ ISL: /^\\d{3}$/,
15
+ ITA: /^\\d{5}$/,
16
+ LIE: /^\\d{4}$/,
17
+ LTU: /^[Ll][Tt][- ]{0,1}\\d{5}$/,
18
+ NLD: /^\\d{4}\\s{0,1}[A-Za-z]{2}$/,
19
+ NOR: /^\\d{4}$/,
20
+ POL: /^\\d{2}[- ]{0,1}\\d{3}$/,
21
+ PRT: /^\\d{4}$/,
22
+ QAT: /.*$/,//match anything
23
+ ROU: /^\\d{6}$/,
24
+ RUS: /^\\d{6}$/,
25
+ SVK: /^\\d{5}\\s\\(\\d{3}\\s\\d{2}\\)$/,
26
+ SVN: /^([Ss][Ii][- ]{0,1}){0,1}\\d{4}$/,
27
+ ZAF: /^\\d{4}$/,
28
+ ESP: /^\\d{5}$/,
29
+ SWE: /^\\d{3}\\s*\\d{2}$/,
30
+ CHE: /^\\d{4}$/
31
+ },
32
+ cemeaV2: { FRA: /^[0-9]{5}$/, LUX: /^\\d{4}$/, MCO: /^980\\d{2}$/ },
33
+ apac: {
34
+ CHN: /^\\d{6}$/,
35
+ HKG: /.*$/, //match anything
36
+ IND: /^\\d{6}$/,
37
+ IDN: /^\\d{5}$/,
38
+ JPN: /^\\d{7}\\s\\(\\d{3}-\\d{4}\\)$/,
39
+ KOR: /^\\d{6}\\s\\(\\d{3}-\\d{3}\\)$/,
40
+ MYS: /^\\d{5}$/,
41
+ PHL: /^\\d{4}$/,
42
+ SGP: /^\\d{2}$/,
43
+ TWN: /^\\d{5}$/,
44
+ THA: /^\\d{5}$/
45
+ },
46
+ other: {
47
+ GBR: /^[A-Za-z]{1,2}[0-9][0-9A-Za-z]?[\s-]?[0-9][A-Za-z]{2}$/,
48
+ USA: /^[0-9]{5}$/,
49
+ CAN: /^[A-Za-z]\d[A-Za-z][\s-]?\d[A-Za-z]\d$/
50
+ }
51
+ };
52
+
53
+ module.exports = { supportedPostcodeValidators };
@@ -0,0 +1,14 @@
1
+ //Recursively flattens a nested object.
2
+ //For example: input: {a:{b:1}} -> output: {b:1}
3
+ const flattenObj = (obj, out={}) => {
4
+ Object.keys(obj).forEach(key => {
5
+ if (typeof obj[key] === 'object') {
6
+ out = flattenObj(obj[key], out); //recursively call for nesteds
7
+ } else {
8
+ out[key] = obj[key]; //direct assign for values
9
+ }
10
+ });
11
+ return out;
12
+ };
13
+
14
+ module.exports = { flattenObj };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-conversion-forms",
3
- "version": "25.2.0",
3
+ "version": "27.0.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,5 @@
1
+ const { printRegions } = require('../helpers/constants');
2
+
1
3
  // Delivery Frequency codes
2
4
  const ONLY_WEEKEND_DELIVERY_FREQ = 'A1';
3
5
  const FIVE_DAYS_WEEK_DELIVERY_FREQ = 'A5';
@@ -103,6 +105,19 @@ const deliveryOptionMessages = [
103
105
  description:
104
106
  'Enjoy delivery of the newspaper daily to your home or office address. \nPlease note: Your FT Weekend will be delivered on Sunday or Monday.',
105
107
  },
108
+ {
109
+ deliveryFrequency: [
110
+ FIVE_DAYS_WEEK_DELIVERY_FREQ,
111
+ SIX_DAYS_WEEK_DELIVERY_FREQ,
112
+ ],
113
+ distributorType: HAND_DELIVERY,
114
+ deliveryOnPublicationDate: true,
115
+ flightMarket: false,
116
+ country: [printRegions.cemeaV1, printRegions.cemeaV2, printRegions.apac],
117
+ title: 'Hand delivery',
118
+ description:
119
+ 'Enjoy the delivery of the newspaper to your home or office address. Please note we fly the newspaper to your location which means delivery is subject to flight delays/cancellations outside of the FT’s control. In those circumstances, your newspaper will be delivered the next delivery day. Please also be aware that your FT weekend will be delivered on Sunday.',
120
+ },
106
121
  {
107
122
  deliveryFrequency: [
108
123
  FIVE_DAYS_WEEK_DELIVERY_FREQ,