@financial-times/n-conversion-forms 26.0.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.
Files changed (111) hide show
  1. package/.circleci/config.yml +4 -4
  2. package/.eslintignore +1 -0
  3. package/.github/workflows/gh-pages-deploy.yml +1 -0
  4. package/.storybook/main.js +0 -1
  5. package/__mocks__/@financial-times/o-expander.js +9 -0
  6. package/__mocks__/@financial-times/o-forms-input.js +11 -0
  7. package/__mocks__/@financial-times/o-forms.js +40 -0
  8. package/build-state/npm-shrinkwrap.json +294 -6334
  9. package/components/__snapshots__/b2c-partnership-confirmation.spec.js.snap +1 -1
  10. package/components/__snapshots__/confirmation.spec.js.snap +0 -3
  11. package/components/__snapshots__/debug.spec.js.snap +25 -13
  12. package/components/__snapshots__/delivery-postcode.spec.js.snap +1 -1
  13. package/components/__snapshots__/payment-term.spec.js.snap +1 -1
  14. package/components/__snapshots__/payment-type.spec.js.snap +19 -0
  15. package/components/__snapshots__/registration-confirmation.spec.js.snap +230 -74
  16. package/components/accept-terms.jsx +57 -36
  17. package/components/accept-terms.stories.js +28 -1
  18. package/components/b2c-partnership-confirmation.jsx +1 -1
  19. package/components/confirmation.jsx +15 -8
  20. package/components/confirmation.spec.js +1 -1
  21. package/components/debug.jsx +19 -12
  22. package/components/debug.stories.js +13 -0
  23. package/components/delivery-address.jsx +21 -58
  24. package/components/delivery-address.stories.js +7 -0
  25. package/components/delivery-city.jsx +4 -2
  26. package/components/delivery-city.stories.js +9 -0
  27. package/components/delivery-option.jsx +5 -3
  28. package/components/delivery-option.stories.js +7 -1
  29. package/components/delivery-postcode.jsx +32 -13
  30. package/components/delivery-postcode.stories.js +2 -1
  31. package/components/delivery-security-instructions.spec.js +3 -3
  32. package/components/graduation-date.spec.js +8 -8
  33. package/components/index.jsx +1 -1
  34. package/components/message.jsx +1 -1
  35. package/components/payment-term.jsx +152 -25
  36. package/components/payment-term.spec.js +46 -4
  37. package/components/payment-term.stories.js +69 -14
  38. package/components/payment-type.jsx +3 -1
  39. package/components/position.jsx +6 -3
  40. package/components/position.spec.js +15 -5
  41. package/components/registration-confirmation.jsx +111 -32
  42. package/components/responsibility.jsx +6 -3
  43. package/components/responsibility.spec.js +15 -5
  44. package/components/text-input.jsx +73 -0
  45. package/components/text-input.spec.js +118 -0
  46. package/components/text-input.stories.js +31 -0
  47. package/dist/accept-terms.js +15 -7
  48. package/dist/b2c-partnership-confirmation.js +1 -1
  49. package/dist/confirmation.js +11 -2
  50. package/dist/debug.js +6 -6
  51. package/dist/delivery-address.js +19 -32
  52. package/dist/delivery-city.js +4 -2
  53. package/dist/delivery-option.js +5 -2
  54. package/dist/delivery-postcode.js +31 -12
  55. package/dist/index.js +9 -9
  56. package/dist/message.js +1 -1
  57. package/dist/payment-term.js +117 -11
  58. package/dist/payment-type.js +5 -2
  59. package/dist/position.js +6 -2
  60. package/dist/registration-confirmation.js +87 -29
  61. package/dist/responsibility.js +6 -2
  62. package/dist/text-input.js +84 -0
  63. package/helpers/constants.js +7 -0
  64. package/helpers/deliveryAddressMap.js +167 -0
  65. package/helpers/index.js +7 -0
  66. package/helpers/index.spec.js +11 -0
  67. package/helpers/ncf-common-data.spec.js +34 -0
  68. package/helpers/ncf-countries.spec.js +136 -0
  69. package/helpers/supportedCountries.js +76 -0
  70. package/helpers/supportedPostcodeExamples.js +57 -0
  71. package/helpers/supportedPostcodeValidators.js +53 -0
  72. package/helpers/utilities.js +14 -0
  73. package/jest.config.js +8 -1
  74. package/main.scss +461 -0
  75. package/package.json +6 -3
  76. package/styles/confirmation.scss +122 -0
  77. package/styles/payment-term.scss +3 -0
  78. package/utils/app-banner.spec.js +68 -0
  79. package/utils/apple-pay.spec.js +177 -0
  80. package/utils/billing-country.spec.js +87 -0
  81. package/utils/billing-postcode.spec.js +138 -0
  82. package/utils/company-name.spec.js +3 -7
  83. package/utils/country.spec.js +87 -0
  84. package/utils/delivery-address-type.spec.js +24 -11
  85. package/utils/delivery-option-messages.js +15 -0
  86. package/utils/delivery-option-messages.spec.js +3 -3
  87. package/utils/delivery-option.spec.js +100 -15
  88. package/utils/delivery-postcode.spec.js +138 -0
  89. package/utils/delivery-start-date.spec.js +177 -0
  90. package/utils/email.spec.js +210 -0
  91. package/utils/event-notifier.spec.js +116 -0
  92. package/utils/form-element.spec.js +71 -0
  93. package/utils/loader.spec.js +161 -0
  94. package/utils/password.spec.js +65 -0
  95. package/utils/payment-term.js +25 -1
  96. package/utils/payment-term.spec.js +198 -0
  97. package/utils/payment-type.js +1 -1
  98. package/utils/payment-type.spec.js +136 -0
  99. package/utils/postcode.spec.js +122 -0
  100. package/utils/salesforce.spec.js +30 -0
  101. package/utils/submit.spec.js +81 -0
  102. package/utils/tracking.spec.js +174 -0
  103. package/utils/validation.js +2 -2
  104. package/utils/validation.spec.js +234 -0
  105. package/utils/zuora.spec.js +249 -0
  106. package/components/__snapshots__/b2c-partnership-payment-term.spec.js.snap +0 -193
  107. package/components/b2c-partnership-payment-term.jsx +0 -126
  108. package/components/b2c-partnership-payment-term.spec.js +0 -52
  109. package/components/b2c-partnership-payment-term.stories.js +0 -44
  110. package/dist/b2c-partnership-payment-term.js +0 -91
  111. package/styles/b2c-partnership-payment-term.scss +0 -20
@@ -22,6 +22,8 @@ export function AcceptTerms ({
22
22
  isPrintProduct = false,
23
23
  specialTerms = null,
24
24
  isSingleTerm = false,
25
+ isNewDigitalBuyFlowConsent = false,
26
+ hideConfirmTermsAndConditions = false,
25
27
  }) {
26
28
  const divProps = {
27
29
  id: 'acceptTermsField',
@@ -50,49 +52,66 @@ export function AcceptTerms ({
50
52
 
51
53
  const authFirstStepTerms = (
52
54
  <>
53
- <ul className="o-typography-list ncf__accept-terms-list">
54
- <li>
55
- <span className="terms-auth-first-step">
56
- For more information about how we use your data, please refer to our <a
57
- className="ncf__link--external"
58
- href="http://help.ft.com/help/legal-privacy/terms-conditions/"
59
- target='_blank'
60
- rel="noopener noreferrer"
61
- data-trackable="terms-and-conditions"
62
- >
63
- privacy
64
- </a> and&nbsp;
55
+ {
56
+ // TODO: clean up the code in https://financialtimes.atlassian.net/browse/ACQ-1593
57
+ // isNewDigitalBuyFlowConsent flag for new A/B testing of consents auth first buy flow
58
+ // after the test it will be one of the conditions for the below flow
59
+ }
60
+ {isNewDigitalBuyFlowConsent && (
61
+ <hr className=" ncf ncf__divider-horizontal" />
62
+ )}
63
+ {!isNewDigitalBuyFlowConsent && (
64
+ <ul className="o-typography-list ncf__accept-terms-list">
65
+ <li>
66
+ <span className="terms-auth-first-step">
67
+ For more information about how we use your data, please refer to
68
+ our{' '}
69
+ <a
70
+ className="ncf__link--external"
71
+ href="http://help.ft.com/help/legal-privacy/terms-conditions/"
72
+ target="_blank"
73
+ rel="noopener noreferrer"
74
+ data-trackable="terms-and-conditions"
75
+ >
76
+ privacy
77
+ </a>{' '}
78
+ and&nbsp;
79
+ <a
80
+ className="ncf__link--external"
81
+ href="http://help.ft.com/help/legal-privacy/terms-conditions/"
82
+ target="_blank"
83
+ rel="noopener noreferrer"
84
+ data-trackable="terms-and-conditions"
85
+ >
86
+ cookie
87
+ </a>{' '}
88
+ policies.
89
+ </span>
90
+ </li>
91
+ </ul>
92
+ )}
93
+ {!hideConfirmTermsAndConditions && (
94
+ <label className={labelClassName} htmlFor="termsAcceptance">
95
+ <input {...inputProps} />
96
+ <span className="o-forms-input__label terms-auth-first-step">
97
+ I confirm that I am {ageRestriction} years or older and agree to the
98
+ full{' '}
65
99
  <a
66
100
  className="ncf__link--external"
67
101
  href="http://help.ft.com/help/legal-privacy/terms-conditions/"
68
- target='_blank'
102
+ target={isEmbedded ? '_top' : '_blank'}
69
103
  rel="noopener noreferrer"
70
104
  data-trackable="terms-and-conditions"
71
105
  >
72
- cookie
73
- </a> policies.
106
+ Terms &amp; Conditions
107
+ </a>
108
+ .
74
109
  </span>
75
- </li>
76
- </ul>
77
- <label className={labelClassName} htmlFor="termsAcceptance">
78
- <input {...inputProps} />
79
- <span className="o-forms-input__label terms-auth-first-step">
80
- I confirm that I am {ageRestriction} years or older and agree to the full {' '}
81
- <a
82
- className="ncf__link--external"
83
- href="http://help.ft.com/help/legal-privacy/terms-conditions/"
84
- target={isEmbedded ? '_top' : '_blank'}
85
- rel="noopener noreferrer"
86
- data-trackable="terms-and-conditions"
87
- >
88
- Terms &amp; Conditions
89
- </a>
90
- .
91
- </span>
92
- <p className="o-forms-input__error">
93
- Please accept our terms &amp; conditions
94
- </p>
95
- </label>
110
+ <p className="o-forms-input__error">
111
+ Please accept our terms &amp; conditions
112
+ </p>
113
+ </label>
114
+ )}
96
115
  </>
97
116
  );
98
117
 
@@ -391,4 +410,6 @@ AcceptTerms.propTypes = {
391
410
  isPrintProduct: PropTypes.bool,
392
411
  specialTerms: PropTypes.string,
393
412
  isSingleTerm: PropTypes.bool,
413
+ isNewDigitalBuyFlowConsent: PropTypes.bool,
414
+ hideConfirmTermsAndConditions: PropTypes.bool,
394
415
  };
@@ -11,8 +11,35 @@ export default {
11
11
  options: ['immediate', 'endOfTerm'],
12
12
  },
13
13
  },
14
+ isAuthFirstAccount: { control: 'boolean' },
15
+ isAuthFirstPayment: { control: 'boolean' },
16
+ hasError: { control: 'boolean' },
17
+ isSignup: { control: 'boolean' },
18
+ isRegister: { control: 'boolean' },
19
+ isChecked: { control: 'boolean' },
20
+ isB2b: { control: 'boolean' },
21
+ isB2cPartnership: { control: 'boolean' },
22
+ isEmbedded: { control: 'boolean' },
23
+ isCorpSignup: { control: 'boolean' },
24
+ isTrial: { control: 'boolean' },
25
+ isTransition: { control: 'boolean' },
26
+ isPrintProduct: { control: 'boolean' },
27
+ isSingleTerm: { control: 'boolean' },
28
+ isNewDigitalBuyFlowConsent: { control: 'boolean' },
29
+ hideConfirmTermsAndConditions: { control: 'boolean' },
14
30
  },
15
31
  };
16
32
 
17
33
  export const Basic = (args) => <AcceptTerms {...args} />;
18
- Basic.parameters = {};
34
+ Basic.args = {};
35
+
36
+ export const NewBuyFlow = (args) => <AcceptTerms {...args} />;
37
+ NewBuyFlow.args = {
38
+ isAuthFirstAccount: true,
39
+ };
40
+
41
+ export const NewBuyFlowEmailVerification = (args) => <AcceptTerms {...args} />;
42
+ NewBuyFlowEmailVerification.args = {
43
+ isAuthFirstAccount: true,
44
+ hideConfirmTermsAndConditions: true,
45
+ };
@@ -19,7 +19,7 @@ export function B2CPartnershipConfirmation ({ ctaElement = null }) {
19
19
  <div className="ncf__paragraph">
20
20
  {
21
21
  <h1 className="ncf__header ncf__header--confirmation">
22
- {'Welcome to your three months\' Premium access'}
22
+ {'Welcome to your 30 days\' Premium access'}
23
23
  </h1>
24
24
  }
25
25
  </div>
@@ -7,6 +7,7 @@ export function Confirmation ({
7
7
  // isTrial prop is needed for the floodlight pixel tracking.
8
8
  isTrial = false,
9
9
  isB2cPartnership = false,
10
+ b2cPartnershipCopy = [],
10
11
  offer = '',
11
12
  email = EMAIL_DEFAULT_TEXT,
12
13
  details = null,
@@ -19,6 +20,8 @@ export function Confirmation ({
19
20
  ...(isTrial && { 'data-signup-is-trial': 'true' }),
20
21
  };
21
22
 
23
+ const isB2cPartnershipCopyAvailable = isB2cPartnership && b2cPartnershipCopy.length > 0;
24
+
22
25
  const detailElements = details && (
23
26
  <React.Fragment>
24
27
  <h2 className="ncf__header2--afterline">Your billing details</h2>
@@ -63,15 +66,18 @@ export function Confirmation ({
63
66
  </div>
64
67
 
65
68
  {nextActionTop}
69
+ {!isB2cPartnershipCopyAvailable && (
70
+ <p className="ncf__paragraph">
71
+ We’ve sent confirmation to {email}. Make sure you check your spam folder
72
+ if you don’t receive it.
73
+ </p>
74
+ )}
66
75
 
67
- <p className="ncf__paragraph">
68
- We’ve sent confirmation to {email}. Make sure you check your spam folder
69
- if you don’t receive it.
70
- </p>
71
- {isB2cPartnership ? (
72
- <p>
73
- We&apos;ve also sent you an email to start your 90-day All Access
74
- Digital subscription with The Washington Post.
76
+ {isB2cPartnershipCopyAvailable ? (
77
+ <p className="ncf__paragraph">
78
+ {b2cPartnershipCopy[0]}
79
+ <span className="ncf__legend">{` ${email}. `}</span>
80
+ {b2cPartnershipCopy[1]}
75
81
  </p>
76
82
  ) : (
77
83
  ''
@@ -126,6 +132,7 @@ export function Confirmation ({
126
132
  Confirmation.propTypes = {
127
133
  isTrial: PropTypes.bool,
128
134
  isB2cPartnership: PropTypes.bool,
135
+ b2cPartnershipCopy: PropTypes.array,
129
136
  offer: PropTypes.string.isRequired,
130
137
  email: PropTypes.string,
131
138
  details: PropTypes.arrayOf(
@@ -21,7 +21,7 @@ describe('Confirmation', () => {
21
21
  });
22
22
 
23
23
  it('renders appropriately if is B2C Partnership', () => {
24
- const props = { isB2cPartnership: true };
24
+ const props = { isB2cPartnership: true, b2cDiscountCopy: ['Send email'] };
25
25
 
26
26
  expect(Confirmation).toRenderCorrectly(props);
27
27
  });
@@ -8,18 +8,19 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
8
8
  // entirely this component should be rethought.
9
9
  const testEnvironment = `
10
10
  <span class="ncf__debug-environment">
11
- <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>
11
+ <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>
12
12
  </span>
13
13
  `;
14
14
  const productionEnvironment = `
15
15
  <span class="ncf__debug-environment">
16
- <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>
16
+ <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>
17
17
  </span>
18
18
  `;
19
19
  const testCards = `
20
- <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>
21
- <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>
22
- <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>
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 challenge code -Checkout1!- to clipboard">EU 3ds challenge</button>
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
+ <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>
23
24
  `;
24
25
  const linksString = Object.keys(links).map(
25
26
  (link) =>
@@ -27,9 +28,9 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
27
28
  );
28
29
  const helpers = `
29
30
  <span class="ncf__debug-helpers">
30
- <button class="ncf__button ncf__button--inverse" onclick="logout();" title="Logout and refresh">Logout</button>
31
- <button class="ncf__button ncf__button--inverse" onclick="fillForm();" title="Fill form with debug data">Fill</button>
32
- <button class="ncf__button ncf__button--inverse" onclick="fillForm(); submitForm();" title="Fill form with debug data and submit">Fill &amp; Submit</button>
31
+ <button class="ncf__button ncf__button--debug ncf__button--inverse" onclick="logout();" title="Logout and refresh">Logout</button>
32
+ <button class="ncf__button ncf__button--debug ncf__button--inverse" onclick="fillForm();" title="Fill form with debug data">Fill</button>
33
+ <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>
33
34
  ${isTest ? testCards : ''}
34
35
  ${links.length ? linksString : ''}
35
36
  </span>
@@ -55,7 +56,7 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
55
56
  GBR: 'EC4M9BT',
56
57
  USA: '10028',
57
58
  CAN: 'K0E 9Z9'
58
- }
59
+ };
59
60
 
60
61
  var debugData = {
61
62
  billingCity: 'London',
@@ -79,9 +80,12 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
79
80
  postCode: postcodeByCountry[COUNTRY_CODE],
80
81
  primaryTelephone: '0987654321',
81
82
  responsibility: 'ADL',
82
- ukVisa: '4111111111111111',
83
+ ukVisaWorldpay: '4111111111111111',
83
84
  usAmex: '378282246310005',
84
- usVisa: '4112344112344113'
85
+ usVisaWorldpay: '4112344112344113',
86
+ checkoutVisa: '4242424242424242',
87
+ checkout3dsChallenge: 'Checkout1!',
88
+ chaseVisa: '4011361100000010',
85
89
  };
86
90
 
87
91
  function logout () {
@@ -100,7 +104,7 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
100
104
 
101
105
  var inputs = document.querySelectorAll(INPUT_SELECTOR + ', ' + SELECT_SELECTOR);
102
106
  inputs.forEach(function (input) {
103
- if (!/hidden/i.test(input.type)) {
107
+ if (!/hidden/i.test(input.type) && input.disabled === false) {
104
108
  var value = debugData[input.name];
105
109
  input.value = value;
106
110
  input.dispatchEvent(changeEvent);
@@ -157,6 +161,9 @@ export function Debug ({ isTest = false, showHelpers = false, links = {} }) {
157
161
  .ncf__debug-button--production {
158
162
  background-color: #990000;
159
163
  }
164
+ .ncf__button--debug {
165
+ padding: 0px 5px;
166
+ }
160
167
  `,
161
168
  };
162
169
 
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { Debug } from './debug';
3
+
4
+ export default {
5
+ title: 'Debug helpers',
6
+ component: Debug,
7
+ };
8
+
9
+ export const Basic = (args) => <Debug {...args} />;
10
+ Basic.args = {
11
+ isTest: true,
12
+ showHelpers: true,
13
+ };
@@ -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
  },