@financial-times/n-conversion-forms 32.0.0 → 32.3.2

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/.eslintignore CHANGED
@@ -2,3 +2,5 @@
2
2
  /dist
3
3
  /.eslintrc.js
4
4
  /public
5
+ secret-squirrel.js
6
+ secret-squirrel.cjs
package/.toolkitrc.yml CHANGED
@@ -5,11 +5,9 @@ plugins:
5
5
  - "@dotcom-tool-kit/eslint"
6
6
  - "@dotcom-tool-kit/prettier"
7
7
  - "@dotcom-tool-kit/lint-staged"
8
+ - "@dotcom-tool-kit/husky-npm"
8
9
  - './toolkit/run-storybook'
9
10
  hooks:
10
- git:precommit:
11
- - SecretSquirrel
12
- - LintStaged
13
11
  test:local:
14
12
  - Eslint
15
13
  - JestLocal
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "branch": "",
3
3
  "repo": "n-conversion-forms",
4
- "version": "a19d57d84173cfb0a14e4247f2cd3b902f6a338c",
5
- "tag": "v32.0.0"
4
+ "version": "dbf4d85ef93c98eced9c5d9293344ff7542f492d",
5
+ "tag": "v32.3.2"
6
6
  }
@@ -70,7 +70,7 @@ exports[`DeliveryOption renders with a context of being single 1`] = `
70
70
  Paper vouchers
71
71
  </span>
72
72
  <div class="ncf__delivery-option__description">
73
- 13-week voucher pack delivered quarterly and redeemable at retailers nationwide. COVID-19 - make sure your preferred newsagent or retailer is open and/or delivering before you select this option.
73
+ 13-week voucher pack delivered quarterly and redeemable at retailers nationwide.
74
74
  </div>
75
75
  </span>
76
76
  </label>
@@ -85,7 +85,7 @@ exports[`DeliveryOption renders with a context of being single 1`] = `
85
85
  >
86
86
  <span class="o-forms-input__label ncf__delivery-option__label">
87
87
  <span class="ncf__delivery-option__title o-forms-title__main">
88
- Home delivery
88
+ Hand delivery
89
89
  </span>
90
90
  <div class="ncf__delivery-option__description">
91
91
  Free delivery to your home or office before 7am.
@@ -166,7 +166,7 @@ exports[`DeliveryOption renders with minimum mandatory props 1`] = `
166
166
  Paper vouchers
167
167
  </span>
168
168
  <div class="ncf__delivery-option__description">
169
- 13-week voucher pack delivered quarterly and redeemable at retailers nationwide. COVID-19 - make sure your preferred newsagent or retailer is open and/or delivering before you select this option.
169
+ 13-week voucher pack delivered quarterly and redeemable at retailers nationwide.
170
170
  </div>
171
171
  </span>
172
172
  </label>
@@ -181,7 +181,7 @@ exports[`DeliveryOption renders with minimum mandatory props 1`] = `
181
181
  >
182
182
  <span class="o-forms-input__label ncf__delivery-option__label">
183
183
  <span class="ncf__delivery-option__title o-forms-title__main">
184
- Home delivery
184
+ Hand delivery
185
185
  </span>
186
186
  <div class="ncf__delivery-option__description">
187
187
  Free delivery to your home or office before 7am.
@@ -232,7 +232,7 @@ exports[`DeliveryOption renders without unrecognised delivery options 1`] = `
232
232
  Paper vouchers
233
233
  </span>
234
234
  <div class="ncf__delivery-option__description">
235
- 13-week voucher pack delivered quarterly and redeemable at retailers nationwide. COVID-19 - make sure your preferred newsagent or retailer is open and/or delivering before you select this option.
235
+ 13-week voucher pack delivered quarterly and redeemable at retailers nationwide.
236
236
  </div>
237
237
  </span>
238
238
  </label>
@@ -247,7 +247,7 @@ exports[`DeliveryOption renders without unrecognised delivery options 1`] = `
247
247
  >
248
248
  <span class="o-forms-input__label ncf__delivery-option__label">
249
249
  <span class="ncf__delivery-option__title o-forms-title__main">
250
- Home delivery
250
+ Hand delivery
251
251
  </span>
252
252
  <div class="ncf__delivery-option__description">
253
253
  Free delivery to your home or office before 7am.
@@ -1,5 +1,20 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`PackageChange annual render when is7DayPassExperiment is true 1`] = `
4
+ <div class="ncf__package-change">
5
+ <div class="ncf__package-change__package">
6
+ <div class="ncf__package-change__content">
7
+ <p>
8
+ You have chosen
9
+ <span class="ncf__strong">
10
+ Trial
11
+ </span>
12
+ </p>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ `;
17
+
3
18
  exports[`PackageChange annual render with defaults 1`] = `
4
19
  <div class="ncf__package-change">
5
20
  <div class="ncf__package-change__package">
@@ -9,6 +9,7 @@ export function AcceptTermsSubscription({
9
9
  isTrial = false,
10
10
  isPrintProduct = false,
11
11
  isSingleTerm = false,
12
+ is7DayPassExperiment = false,
12
13
  isTransition = false,
13
14
  transitionType = null,
14
15
  isDeferredBilling = false,
@@ -37,6 +38,56 @@ export function AcceptTermsSubscription({
37
38
  required: true,
38
39
  };
39
40
 
41
+ if (is7DayPassExperiment) {
42
+ return (
43
+ <div {...divProps}>
44
+ <ul className="o-typography-list ncf__accept-terms-list">
45
+ <li>
46
+ <span className="terms-transition terms-transition--immediate">
47
+ I give consent for my chosen payment method to be charged
48
+ automatically.
49
+ </span>
50
+ </li>
51
+ <li>
52
+ <span className="terms-transition terms-transition--immediate">
53
+ By placing your order subject to the Terms & Conditions (save for
54
+ section 2) referred to below, you agree that we may start your
55
+ 7-day pass immediately upon our acceptance of your order and that
56
+ you are waiving your statutory right to cancel our contract within
57
+ 14 days of confirmation. Your payment is a one-time payment
58
+ collected at the time of checkout, and cancelling at any point
59
+ (whether before or after the 14-day period) will not entitle you
60
+ to a refund.
61
+ </span>
62
+ </li>
63
+ <li>
64
+ <span className="terms-transition">
65
+ Please see here for the complete{' '}
66
+ <a
67
+ className="ncf__link--external"
68
+ href="http://help.ft.com/help/legal-privacy/terms-conditions/"
69
+ target="_blank"
70
+ rel="noopener noreferrer"
71
+ >
72
+ Terms &amp; Conditions
73
+ </a>
74
+ .
75
+ </span>
76
+ </li>
77
+ </ul>
78
+ <label className={labelClassName} htmlFor="termsAcceptance">
79
+ <input {...inputProps} />
80
+ <span className="o-forms-input__label">
81
+ I agree to the above terms &amp; conditions.
82
+ </span>
83
+ <p className="o-forms-input__error">
84
+ Please accept our terms &amp; conditions
85
+ </p>
86
+ </label>
87
+ </div>
88
+ );
89
+ }
90
+
40
91
  const transitionTerms = isTransition && (
41
92
  <>
42
93
  {!isSingleTerm && (
@@ -209,6 +260,7 @@ AcceptTermsSubscription.propTypes = {
209
260
  isTrial: PropTypes.bool,
210
261
  isPrintProduct: PropTypes.bool,
211
262
  isSingleTerm: PropTypes.bool,
263
+ is7DayPassExperiment: PropTypes.bool,
212
264
  isTransition: PropTypes.bool,
213
265
  transitionType: PropTypes.string,
214
266
  isDeferredBilling: PropTypes.bool,
@@ -24,28 +24,28 @@ PrintProductTrial.args = {
24
24
  isTrial: true,
25
25
  };
26
26
 
27
- export const isSingleTerm = (args) => <AcceptTermsSubscription {...args} />;
27
+ export const IsSingleTerm = (args) => <AcceptTermsSubscription {...args} />;
28
28
 
29
- isSingleTerm.args = {
29
+ IsSingleTerm.args = {
30
30
  isSingleTerm: true,
31
31
  };
32
32
 
33
- export const isTransition = (args) => <AcceptTermsSubscription {...args} />;
33
+ export const IsTransition = (args) => <AcceptTermsSubscription {...args} />;
34
34
 
35
- isTransition.args = {
35
+ IsTransition.args = {
36
36
  isTransition: true,
37
37
  };
38
38
 
39
- export const transitionType = (args) => <AcceptTermsSubscription {...args} />;
39
+ export const TransitionType = (args) => <AcceptTermsSubscription {...args} />;
40
40
 
41
- transitionType.args = {
41
+ TransitionType.args = {
42
42
  transitionType: true,
43
43
  };
44
44
 
45
- export const isDeferredBilling = (args) => (
45
+ export const IsDeferredBilling = (args) => (
46
46
  <AcceptTermsSubscription {...args} />
47
47
  );
48
48
 
49
- isDeferredBilling.args = {
49
+ IsDeferredBilling.args = {
50
50
  isDeferredBilling: true,
51
51
  };
@@ -49,6 +49,7 @@ export { Province } from './province';
49
49
  export { RegistrationConfirmation } from './registration-confirmation';
50
50
  export { Responsibility } from './responsibility';
51
51
  export { Section } from './section';
52
+ export { SevenDayPassExperimentConfirmation } from './seven-day-pass-experiment-confirmation';
52
53
  export { State } from './state';
53
54
  export { Submit } from './submit';
54
55
  export { TrialBanner } from './trial-banner';
@@ -5,6 +5,7 @@ export function PackageChange({
5
5
  changePackageUrl,
6
6
  currentPackage,
7
7
  packageDescription,
8
+ is7DayPassExperiment,
8
9
  }) {
9
10
  return (
10
11
  <div className="ncf__package-change">
@@ -20,15 +21,17 @@ export function PackageChange({
20
21
  </p>
21
22
  )}
22
23
  </div>
23
- <div className="ncf__package-change__actions">
24
- <a
25
- href={changePackageUrl}
26
- className="ncf__button ncf__button--mono ncf__button--baseline"
27
- data-trackable="change"
28
- >
29
- Change
30
- </a>
31
- </div>
24
+ {!is7DayPassExperiment && (
25
+ <div className="ncf__package-change__actions">
26
+ <a
27
+ href={changePackageUrl}
28
+ className="ncf__button ncf__button--mono ncf__button--baseline"
29
+ data-trackable="change"
30
+ >
31
+ Change
32
+ </a>
33
+ </div>
34
+ )}
32
35
  </div>
33
36
  </div>
34
37
  );
@@ -38,4 +41,5 @@ PackageChange.propTypes = {
38
41
  changePackageUrl: PropTypes.string.isRequired,
39
42
  currentPackage: PropTypes.string.isRequired,
40
43
  packageDescription: PropTypes.string,
44
+ is7DayPassExperiment: PropTypes.bool,
41
45
  };
@@ -74,6 +74,23 @@ describe('PackageChange', () => {
74
74
 
75
75
  expect(PackageChange).toRenderCorrectly(props);
76
76
  });
77
+
78
+ it('render when is7DayPassExperiment is true', () => {
79
+ const props = {
80
+ changePackageUrl: 'https://www.ft.com',
81
+ currentPackage: 'Trial',
82
+ is7DayPassExperiment: true,
83
+ terms: [
84
+ {
85
+ name: term,
86
+ price: '£4.99',
87
+ weeklyPrice: '£4.99',
88
+ },
89
+ ],
90
+ };
91
+
92
+ expect(PackageChange).toRenderCorrectly(props);
93
+ });
77
94
  });
78
95
  });
79
96
  });
@@ -18,3 +18,11 @@ WithPackageDescription.args = {
18
18
  changePackageUrl: 'https://ft.com/products',
19
19
  packageDescription: 'Personalised email briefings and alerts',
20
20
  };
21
+
22
+ export const SevenDayPassExperiment = (args) => <PackageChange {...args} />;
23
+ SevenDayPassExperiment.args = {
24
+ currentPackage: 'Premium Digital',
25
+ changePackageUrl: 'https://ft.com/products',
26
+ packageDescription: 'Personalised email briefings and alerts',
27
+ is7DayPassExperiment: true,
28
+ };
@@ -15,6 +15,7 @@ export function PaymentTerm({
15
15
  largePrice = false,
16
16
  optionsInARow = false,
17
17
  billingCountry = '',
18
+ is7DayPassExperiment = false,
18
19
  }) {
19
20
  /**
20
21
  * Compute monthly price for given term name
@@ -107,11 +108,22 @@ export function PaymentTerm({
107
108
  },
108
109
  monthly: {
109
110
  title: 'Monthly',
110
- price: (price) => (
111
- <React.Fragment>
112
- <span className="ncf__payment-term__price">{price}</span> per month
113
- </React.Fragment>
114
- ),
111
+ price: (price, is7DayPassExperiment) => {
112
+ const paymentIntervalTextToDisplay = (() => {
113
+ if (is7DayPassExperiment) {
114
+ return ' one-time payment';
115
+ }
116
+
117
+ return ' per month';
118
+ })();
119
+
120
+ return (
121
+ <React.Fragment>
122
+ <span className="ncf__payment-term__price">{price}</span>
123
+ {paymentIntervalTextToDisplay}
124
+ </React.Fragment>
125
+ );
126
+ },
115
127
  trialPrice: (price) => (
116
128
  <React.Fragment>
117
129
  Unless you cancel during your trial you will be billed{' '}
@@ -121,9 +133,17 @@ export function PaymentTerm({
121
133
  ),
122
134
  monthlyPrice: () => {},
123
135
  renewsText: (isFixedTermOffer) => {
124
- const textToDisplay = isFixedTermOffer
125
- ? 'This subscription is for 3 months, charged monthly. You can cancel at anytime'
126
- : 'Renews monthly unless cancelled';
136
+ const textToDisplay = (() => {
137
+ if (is7DayPassExperiment) {
138
+ return 'This subscription is for 7 days, charged at the outset.';
139
+ }
140
+
141
+ if (isFixedTermOffer) {
142
+ return 'This subscription is for 3 months, charged monthly. You can cancel at anytime';
143
+ }
144
+
145
+ return 'Renews monthly unless cancelled';
146
+ })();
127
147
 
128
148
  return (
129
149
  <p className="ncf__payment-term__renews-text">{textToDisplay}</p>
@@ -219,9 +239,12 @@ export function PaymentTerm({
219
239
  <React.Fragment>
220
240
  {nameMap[option.name] ? (
221
241
  <div className="ncf__payment-term__description">
222
- {nameMap[option.name].price(option.price)}
242
+ {nameMap[option.name].price(option.price, is7DayPassExperiment)}
223
243
  {nameMap[option.name].monthlyPrice(option.monthlyPrice)}
224
- {nameMap[option.name].renewsText(isFixedTermOffer)}
244
+ {nameMap[option.name].renewsText(
245
+ isFixedTermOffer,
246
+ is7DayPassExperiment
247
+ )}
225
248
  {/* Remove this discount text temporarily in favour of monthly price */}
226
249
  {/* <br />Save up to 25% when you pay annually */}
227
250
  </div>
@@ -263,11 +286,20 @@ export function PaymentTerm({
263
286
  const showTrialCopyInTitle =
264
287
  option.isTrial && !isPrintOrBundle && !isEpaper;
265
288
 
266
- const defaultTitle =
267
- option.name && nameMap[option.name] ? nameMap[option.name].title : '';
289
+ const defaultTitle = (() => {
290
+ if (is7DayPassExperiment) {
291
+ return '';
292
+ }
293
+
294
+ if (Boolean(option.name && nameMap[option.name])) {
295
+ return nameMap[option.name].title;
296
+ }
297
+
298
+ return '';
299
+ })();
268
300
 
269
301
  const title = isFixedTermOffer
270
- ? `${offerDisplayName} - ${defaultTitle}`
302
+ ? [offerDisplayName, defaultTitle].filter(Boolean).join(' - ')
271
303
  : defaultTitle;
272
304
 
273
305
  let termDisplayName = '';
@@ -153,6 +153,37 @@ describe('PaymentTerm', () => {
153
153
  });
154
154
  });
155
155
 
156
+ describe('given is7DayPassExperiment is true', () => {
157
+ const options = [
158
+ {
159
+ name: 'monthly',
160
+ price: '$5.00',
161
+ value: 'monthly',
162
+ monthlyPrice: '$5.00',
163
+ },
164
+ ];
165
+ const wrapper = shallow(
166
+ <PaymentTerm
167
+ isFixedTermOffer={true}
168
+ options={options}
169
+ offerDisplayName="7-day pass"
170
+ is7DayPassExperiment={true}
171
+ />
172
+ );
173
+
174
+ it('renders renewal text that actually reflects how the 7-day pass is a fixed term subscription with a one-off payment made at the outset', () => {
175
+ expect(wrapper.find('.ncf__payment-term__renews-text').text()).toMatch(
176
+ /This subscription is for 7 days, charged at the outset./
177
+ );
178
+ });
179
+
180
+ it('renders offer name and omits payment term title', () => {
181
+ expect(wrapper.find('.ncf__payment-term__title').text()).toMatch(
182
+ '7-day pass'
183
+ );
184
+ });
185
+ });
186
+
156
187
  describe('getDisplayName', () => {
157
188
  const baseOptions = {
158
189
  name: 'monthly',
@@ -199,6 +230,22 @@ describe('PaymentTerm', () => {
199
230
  );
200
231
  });
201
232
  });
233
+ describe('7-day pass experiment', () => {
234
+ const options = [
235
+ {
236
+ ...baseOptions,
237
+ isTrial: false,
238
+ },
239
+ ];
240
+ it('renders with time period only if trial.option == false', () => {
241
+ const wrapper = shallow(
242
+ <PaymentTerm options={options} is7DayPassExperiment={true} />
243
+ );
244
+ expect(wrapper.find('.ncf__payment-term__label').text().trim()).toMatch(
245
+ '£20.00 one-time paymentThis subscription is for 7 days, charged at the outset.'
246
+ );
247
+ });
248
+ });
202
249
  });
203
250
 
204
251
  describe('[data-base-amount]', () => {
@@ -109,6 +109,26 @@ FixedTermOffer.args = {
109
109
  offerDisplayName: 'Mix & Match',
110
110
  };
111
111
 
112
+ export const SevenDayPassExperimentOffer = (args) => (
113
+ <div className="ncf">
114
+ <Fieldset>
115
+ <PaymentTerm {...args} />
116
+ </Fieldset>
117
+ </div>
118
+ );
119
+ SevenDayPassExperimentOffer.args = {
120
+ options: [
121
+ {
122
+ name: 'monthly',
123
+ price: '$5.00',
124
+ value: 5.0,
125
+ },
126
+ ],
127
+ isFixedTermOffer: true,
128
+ is7DayPassExperiment: true,
129
+ offerDisplayName: '7-day pass',
130
+ };
131
+
112
132
  export const RenewOffers = (args) => (
113
133
  <div className="ncf">
114
134
  <Fieldset>
@@ -0,0 +1,110 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ const DetailsMobileView = ({ details }) => (
5
+ <dl className="ncf__list ncf__lite-sub__details ncf__lite-sub-confirmation--hidden-md ncf__lite-sub-confirmation--hidden-lg">
6
+ {details.map((detail, index) => (
7
+ <React.Fragment key={index}>
8
+ <dt className="ncf__list-title">{detail.title}</dt>
9
+ <dd className="ncf__list-data">{detail.data}</dd>
10
+ </React.Fragment>
11
+ ))}
12
+ </dl>
13
+ );
14
+
15
+ export function SevenDayPassExperimentConfirmation({
16
+ offerName = '',
17
+ details = [],
18
+ }) {
19
+ const detailElements = details && (
20
+ <React.Fragment>
21
+ <h2 className="ncf__header2--afterline">Your billing details</h2>
22
+ <dl className="ncf__list ncf__lite-sub-confirmation--hidden-sm">
23
+ {details.map((detail, index) => (
24
+ <React.Fragment key={index}>
25
+ <dt className="ncf__list-title">{detail.title}</dt>
26
+ <dd className="ncf__list-data">{detail.data}</dd>
27
+ </React.Fragment>
28
+ ))}
29
+ </dl>
30
+ <DetailsMobileView details={details} />
31
+ </React.Fragment>
32
+ );
33
+
34
+ return (
35
+ <div className="ncf ncf__wrapper">
36
+ <div className="ncf__center">
37
+ <div className="ncf__icon ncf__icon--tick ncf__icon--large"></div>
38
+ <p className="ncf__paragraph--reduced-padding ncf__paragraph--subscription-confirmation">
39
+ You are now subscribed to:
40
+ </p>
41
+ <h1 className="ncf__header ncf__header--confirmation">
42
+ {'Premium Digital'}
43
+ </h1>
44
+ </div>
45
+ <p className="ncf__paragraph">
46
+ Exciting news! You are one of the first to try a{' '}
47
+ <strong>{offerName}</strong>. As a thank you, we are pleased to extend
48
+ your subscription to one month at no additional cost.
49
+ </p>
50
+ <p className="ncf__center">
51
+ <a
52
+ href="/"
53
+ className="ncf__button ncf__button--submit ncf__button--margin ncf__lite-sub-confirmation--lite-sub-cta"
54
+ >
55
+ Go to FT.com
56
+ </a>
57
+ </p>
58
+ <p className="ncf__paragraph">
59
+ Please save or print this page for your records as your purchase
60
+ confirmation.
61
+ </p>
62
+
63
+ <p className="ncf__paragraph">
64
+ Here&apos;s a summary of your Premium Digital subscription:
65
+ </p>
66
+
67
+ {detailElements}
68
+
69
+ <div className="ncf__headed-paragraph">
70
+ <h3 className="ncf__header">Something not right?</h3>
71
+ <p className="ncf__paragraph">
72
+ Go to your{' '}
73
+ <a
74
+ className="ncf__link ncf__link--external"
75
+ href="https://www.ft.com/myaccount/personal-details"
76
+ target="_blank"
77
+ rel="noopener noreferrer"
78
+ data-trackable="yourAccount"
79
+ >
80
+ account settings
81
+ </a>{' '}
82
+ to view or edit your account. If you need to get in touch call us on{' '}
83
+ <a href="tel:+442077556248" className="ncf__link ncf__link--external">
84
+ +44 20 7755 6248
85
+ </a>
86
+ . Or{' '}
87
+ <a
88
+ className="ncf__link ncf__link--external"
89
+ href="https://help.ft.com/contact/"
90
+ target="_blank"
91
+ rel="noopener noreferrer"
92
+ >
93
+ contact us
94
+ </a>{' '}
95
+ for additional support.
96
+ </p>
97
+ </div>
98
+ </div>
99
+ );
100
+ }
101
+
102
+ SevenDayPassExperimentConfirmation.propTypes = {
103
+ offerName: PropTypes.string.isRequired,
104
+ details: PropTypes.arrayOf(
105
+ PropTypes.shape({
106
+ title: PropTypes.string.isRequired,
107
+ data: PropTypes.string.isRequired,
108
+ })
109
+ ),
110
+ };
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { SevenDayPassExperimentConfirmation } from './seven-day-pass-experiment-confirmation';
3
+
4
+ export default {
5
+ title: '7-day pass experiment confirmation',
6
+ component: SevenDayPassExperimentConfirmation,
7
+ argTypes: {
8
+ details: { control: 'array' },
9
+ offerType: { control: 'string' },
10
+ offerName: { control: 'string' },
11
+ },
12
+ };
13
+
14
+ export const Basic = (args) => <SevenDayPassExperimentConfirmation {...args} />;
15
+ Basic.args = {
16
+ offerType: 'Premium',
17
+ details: [
18
+ {
19
+ title: 'End Date',
20
+ data: 'September 18, 2023',
21
+ },
22
+ {
23
+ title: 'One-time payment',
24
+ data: '£4.99',
25
+ },
26
+ {
27
+ title: 'Payment method',
28
+ data: 'Credit / Debit Card',
29
+ },
30
+ ],
31
+ offerName: '7-day pass',
32
+ subscriptionAmount: '£4.99',
33
+ };
@@ -24,6 +24,8 @@ function AcceptTermsSubscription(_ref) {
24
24
  isPrintProduct = _ref$isPrintProduct === void 0 ? false : _ref$isPrintProduct,
25
25
  _ref$isSingleTerm = _ref.isSingleTerm,
26
26
  isSingleTerm = _ref$isSingleTerm === void 0 ? false : _ref$isSingleTerm,
27
+ _ref$is7DayPassExperi = _ref.is7DayPassExperiment,
28
+ is7DayPassExperiment = _ref$is7DayPassExperi === void 0 ? false : _ref$is7DayPassExperi,
27
29
  _ref$isTransition = _ref.isTransition,
28
30
  isTransition = _ref$isTransition === void 0 ? false : _ref$isTransition,
29
31
  _ref$transitionType = _ref.transitionType,
@@ -49,6 +51,29 @@ function AcceptTermsSubscription(_ref) {
49
51
  'aria-required': 'true',
50
52
  required: true
51
53
  };
54
+ if (is7DayPassExperiment) {
55
+ return /*#__PURE__*/_react["default"].createElement("div", divProps, /*#__PURE__*/_react["default"].createElement("ul", {
56
+ className: "o-typography-list ncf__accept-terms-list"
57
+ }, /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
58
+ className: "terms-transition terms-transition--immediate"
59
+ }, "I give consent for my chosen payment method to be charged automatically.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
60
+ className: "terms-transition terms-transition--immediate"
61
+ }, "By placing your order subject to the Terms & Conditions (save for section 2) referred to below, you agree that we may start your 7-day pass immediately upon our acceptance of your order and that you are waiving your statutory right to cancel our contract within 14 days of confirmation. Your payment is a one-time payment collected at the time of checkout, and cancelling at any point (whether before or after the 14-day period) will not entitle you to a refund.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
62
+ className: "terms-transition"
63
+ }, "Please see here for the complete", ' ', /*#__PURE__*/_react["default"].createElement("a", {
64
+ className: "ncf__link--external",
65
+ href: "http://help.ft.com/help/legal-privacy/terms-conditions/",
66
+ target: "_blank",
67
+ rel: "noopener noreferrer"
68
+ }, "Terms & Conditions"), "."))), /*#__PURE__*/_react["default"].createElement("label", {
69
+ className: labelClassName,
70
+ htmlFor: "termsAcceptance"
71
+ }, /*#__PURE__*/_react["default"].createElement("input", inputProps), /*#__PURE__*/_react["default"].createElement("span", {
72
+ className: "o-forms-input__label"
73
+ }, "I agree to the above terms & conditions."), /*#__PURE__*/_react["default"].createElement("p", {
74
+ className: "o-forms-input__error"
75
+ }, "Please accept our terms & conditions")));
76
+ }
52
77
  var transitionTerms = isTransition && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, !isSingleTerm && /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
53
78
  className: "terms-transition"
54
79
  }, "I give consent for my chosen payment method to be charged automatically at the end of each subscription term until I cancel it by contacting", ' ', /*#__PURE__*/_react["default"].createElement("a", {
@@ -118,6 +143,7 @@ AcceptTermsSubscription.propTypes = {
118
143
  isTrial: _propTypes["default"].bool,
119
144
  isPrintProduct: _propTypes["default"].bool,
120
145
  isSingleTerm: _propTypes["default"].bool,
146
+ is7DayPassExperiment: _propTypes["default"].bool,
121
147
  isTransition: _propTypes["default"].bool,
122
148
  transitionType: _propTypes["default"].string,
123
149
  isDeferredBilling: _propTypes["default"].bool
package/dist/index.js CHANGED
@@ -339,6 +339,12 @@ Object.defineProperty(exports, "Section", {
339
339
  return _section.Section;
340
340
  }
341
341
  });
342
+ Object.defineProperty(exports, "SevenDayPassExperimentConfirmation", {
343
+ enumerable: true,
344
+ get: function get() {
345
+ return _sevenDayPassExperimentConfirmation.SevenDayPassExperimentConfirmation;
346
+ }
347
+ });
342
348
  Object.defineProperty(exports, "State", {
343
349
  enumerable: true,
344
350
  get: function get() {
@@ -414,6 +420,7 @@ var _province = require("./province");
414
420
  var _registrationConfirmation = require("./registration-confirmation");
415
421
  var _responsibility = require("./responsibility");
416
422
  var _section = require("./section");
423
+ var _sevenDayPassExperimentConfirmation = require("./seven-day-pass-experiment-confirmation");
417
424
  var _state = require("./state");
418
425
  var _submit = require("./submit");
419
426
  var _trialBanner = require("./trial-banner");
@@ -10,7 +10,8 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
10
10
  function PackageChange(_ref) {
11
11
  var changePackageUrl = _ref.changePackageUrl,
12
12
  currentPackage = _ref.currentPackage,
13
- packageDescription = _ref.packageDescription;
13
+ packageDescription = _ref.packageDescription,
14
+ is7DayPassExperiment = _ref.is7DayPassExperiment;
14
15
  return /*#__PURE__*/_react["default"].createElement("div", {
15
16
  className: "ncf__package-change"
16
17
  }, /*#__PURE__*/_react["default"].createElement("div", {
@@ -21,7 +22,7 @@ function PackageChange(_ref) {
21
22
  className: "ncf__strong"
22
23
  }, currentPackage)), packageDescription && /*#__PURE__*/_react["default"].createElement("p", {
23
24
  className: "ncf__package-change__content__description"
24
- }, packageDescription)), /*#__PURE__*/_react["default"].createElement("div", {
25
+ }, packageDescription)), !is7DayPassExperiment && /*#__PURE__*/_react["default"].createElement("div", {
25
26
  className: "ncf__package-change__actions"
26
27
  }, /*#__PURE__*/_react["default"].createElement("a", {
27
28
  href: changePackageUrl,
@@ -32,5 +33,6 @@ function PackageChange(_ref) {
32
33
  PackageChange.propTypes = {
33
34
  changePackageUrl: _propTypes["default"].string.isRequired,
34
35
  currentPackage: _propTypes["default"].string.isRequired,
35
- packageDescription: _propTypes["default"].string
36
+ packageDescription: _propTypes["default"].string,
37
+ is7DayPassExperiment: _propTypes["default"].bool
36
38
  };
@@ -33,7 +33,9 @@ function PaymentTerm(_ref) {
33
33
  _ref$optionsInARow = _ref.optionsInARow,
34
34
  optionsInARow = _ref$optionsInARow === void 0 ? false : _ref$optionsInARow,
35
35
  _ref$billingCountry = _ref.billingCountry,
36
- billingCountry = _ref$billingCountry === void 0 ? '' : _ref$billingCountry;
36
+ billingCountry = _ref$billingCountry === void 0 ? '' : _ref$billingCountry,
37
+ _ref$is7DayPassExperi = _ref.is7DayPassExperiment,
38
+ is7DayPassExperiment = _ref$is7DayPassExperi === void 0 ? false : _ref$is7DayPassExperi;
37
39
  /**
38
40
  * Compute monthly price for given term name
39
41
  * @param {number} amount price in number format
@@ -118,10 +120,16 @@ function PaymentTerm(_ref) {
118
120
  },
119
121
  monthly: {
120
122
  title: 'Monthly',
121
- price: function price(_price3) {
123
+ price: function price(_price3, is7DayPassExperiment) {
124
+ var paymentIntervalTextToDisplay = function () {
125
+ if (is7DayPassExperiment) {
126
+ return ' one-time payment';
127
+ }
128
+ return ' per month';
129
+ }();
122
130
  return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", {
123
131
  className: "ncf__payment-term__price"
124
- }, _price3), " per month");
132
+ }, _price3), paymentIntervalTextToDisplay);
125
133
  },
126
134
  trialPrice: function trialPrice(price) {
127
135
  return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", {
@@ -130,7 +138,15 @@ function PaymentTerm(_ref) {
130
138
  },
131
139
  monthlyPrice: function monthlyPrice() {},
132
140
  renewsText: function renewsText(isFixedTermOffer) {
133
- var textToDisplay = isFixedTermOffer ? 'This subscription is for 3 months, charged monthly. You can cancel at anytime' : 'Renews monthly unless cancelled';
141
+ var textToDisplay = function () {
142
+ if (is7DayPassExperiment) {
143
+ return 'This subscription is for 7 days, charged at the outset.';
144
+ }
145
+ if (isFixedTermOffer) {
146
+ return 'This subscription is for 3 months, charged monthly. You can cancel at anytime';
147
+ }
148
+ return 'Renews monthly unless cancelled';
149
+ }();
134
150
  return /*#__PURE__*/_react["default"].createElement("p", {
135
151
  className: "ncf__payment-term__renews-text"
136
152
  }, textToDisplay);
@@ -192,7 +208,7 @@ function PaymentTerm(_ref) {
192
208
  className: "ncf__payment-term__trial-price"
193
209
  }, option.trialPrice), /*#__PURE__*/_react["default"].createElement("br", null), nameMap[option.name] && nameMap[option.name].trialPrice(option.price)) : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, nameMap[option.name] ? /*#__PURE__*/_react["default"].createElement("div", {
194
210
  className: "ncf__payment-term__description"
195
- }, nameMap[option.name].price(option.price), nameMap[option.name].monthlyPrice(option.monthlyPrice), nameMap[option.name].renewsText(isFixedTermOffer)) :
211
+ }, nameMap[option.name].price(option.price, is7DayPassExperiment), nameMap[option.name].monthlyPrice(option.monthlyPrice), nameMap[option.name].renewsText(isFixedTermOffer, is7DayPassExperiment)) :
196
212
  // this should cover the cases different than annual, quarterly and monthly
197
213
  // for those containing period on option.value, render custom template, for the rest keep legacy render
198
214
  isValidPeriod(option.value) ? /*#__PURE__*/_react["default"].createElement("div", {
@@ -205,8 +221,16 @@ function PaymentTerm(_ref) {
205
221
  };
206
222
  var getTermDisplayName = function getTermDisplayName() {
207
223
  var showTrialCopyInTitle = option.isTrial && !isPrintOrBundle && !isEpaper;
208
- var defaultTitle = option.name && nameMap[option.name] ? nameMap[option.name].title : '';
209
- var title = isFixedTermOffer ? "".concat(offerDisplayName, " - ").concat(defaultTitle) : defaultTitle;
224
+ var defaultTitle = function () {
225
+ if (is7DayPassExperiment) {
226
+ return '';
227
+ }
228
+ if (Boolean(option.name && nameMap[option.name])) {
229
+ return nameMap[option.name].title;
230
+ }
231
+ return '';
232
+ }();
233
+ var title = isFixedTermOffer ? [offerDisplayName, defaultTitle].filter(Boolean).join(' - ') : defaultTitle;
210
234
  var termDisplayName = '';
211
235
  if (showTrialCopyInTitle) {
212
236
  var termName = option.displayName ? option.displayName : 'Premium Digital';
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.SevenDayPassExperimentConfirmation = SevenDayPassExperimentConfirmation;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _propTypes = _interopRequireDefault(require("prop-types"));
10
+ var DetailsMobileView = function DetailsMobileView(_ref) {
11
+ var details = _ref.details;
12
+ return /*#__PURE__*/_react["default"].createElement("dl", {
13
+ className: "ncf__list ncf__lite-sub__details ncf__lite-sub-confirmation--hidden-md ncf__lite-sub-confirmation--hidden-lg"
14
+ }, details.map(function (detail, index) {
15
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, {
16
+ key: index
17
+ }, /*#__PURE__*/_react["default"].createElement("dt", {
18
+ className: "ncf__list-title"
19
+ }, detail.title), /*#__PURE__*/_react["default"].createElement("dd", {
20
+ className: "ncf__list-data"
21
+ }, detail.data));
22
+ }));
23
+ };
24
+ function SevenDayPassExperimentConfirmation(_ref2) {
25
+ var _ref2$offerName = _ref2.offerName,
26
+ offerName = _ref2$offerName === void 0 ? '' : _ref2$offerName,
27
+ _ref2$details = _ref2.details,
28
+ details = _ref2$details === void 0 ? [] : _ref2$details;
29
+ var detailElements = details && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("h2", {
30
+ className: "ncf__header2--afterline"
31
+ }, "Your billing details"), /*#__PURE__*/_react["default"].createElement("dl", {
32
+ className: "ncf__list ncf__lite-sub-confirmation--hidden-sm"
33
+ }, details.map(function (detail, index) {
34
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, {
35
+ key: index
36
+ }, /*#__PURE__*/_react["default"].createElement("dt", {
37
+ className: "ncf__list-title"
38
+ }, detail.title), /*#__PURE__*/_react["default"].createElement("dd", {
39
+ className: "ncf__list-data"
40
+ }, detail.data));
41
+ })), /*#__PURE__*/_react["default"].createElement(DetailsMobileView, {
42
+ details: details
43
+ }));
44
+ return /*#__PURE__*/_react["default"].createElement("div", {
45
+ className: "ncf ncf__wrapper"
46
+ }, /*#__PURE__*/_react["default"].createElement("div", {
47
+ className: "ncf__center"
48
+ }, /*#__PURE__*/_react["default"].createElement("div", {
49
+ className: "ncf__icon ncf__icon--tick ncf__icon--large"
50
+ }), /*#__PURE__*/_react["default"].createElement("p", {
51
+ className: "ncf__paragraph--reduced-padding ncf__paragraph--subscription-confirmation"
52
+ }, "You are now subscribed to:"), /*#__PURE__*/_react["default"].createElement("h1", {
53
+ className: "ncf__header ncf__header--confirmation"
54
+ }, 'Premium Digital')), /*#__PURE__*/_react["default"].createElement("p", {
55
+ className: "ncf__paragraph"
56
+ }, "Exciting news! You are one of the first to try a", ' ', /*#__PURE__*/_react["default"].createElement("strong", null, offerName), ". As a thank you, we are pleased to extend your subscription to one month at no additional cost."), /*#__PURE__*/_react["default"].createElement("p", {
57
+ className: "ncf__center"
58
+ }, /*#__PURE__*/_react["default"].createElement("a", {
59
+ href: "/",
60
+ className: "ncf__button ncf__button--submit ncf__button--margin ncf__lite-sub-confirmation--lite-sub-cta"
61
+ }, "Go to FT.com")), /*#__PURE__*/_react["default"].createElement("p", {
62
+ className: "ncf__paragraph"
63
+ }, "Please save or print this page for your records as your purchase confirmation."), /*#__PURE__*/_react["default"].createElement("p", {
64
+ className: "ncf__paragraph"
65
+ }, "Here's a summary of your Premium Digital subscription:"), detailElements, /*#__PURE__*/_react["default"].createElement("div", {
66
+ className: "ncf__headed-paragraph"
67
+ }, /*#__PURE__*/_react["default"].createElement("h3", {
68
+ className: "ncf__header"
69
+ }, "Something not right?"), /*#__PURE__*/_react["default"].createElement("p", {
70
+ className: "ncf__paragraph"
71
+ }, "Go to your", ' ', /*#__PURE__*/_react["default"].createElement("a", {
72
+ className: "ncf__link ncf__link--external",
73
+ href: "https://www.ft.com/myaccount/personal-details",
74
+ target: "_blank",
75
+ rel: "noopener noreferrer",
76
+ "data-trackable": "yourAccount"
77
+ }, "account settings"), ' ', "to view or edit your account. If you need to get in touch call us on", ' ', /*#__PURE__*/_react["default"].createElement("a", {
78
+ href: "tel:+442077556248",
79
+ className: "ncf__link ncf__link--external"
80
+ }, "+44 20 7755 6248"), ". Or", ' ', /*#__PURE__*/_react["default"].createElement("a", {
81
+ className: "ncf__link ncf__link--external",
82
+ href: "https://help.ft.com/contact/",
83
+ target: "_blank",
84
+ rel: "noopener noreferrer"
85
+ }, "contact us"), ' ', "for additional support.")));
86
+ }
87
+ SevenDayPassExperimentConfirmation.propTypes = {
88
+ offerName: _propTypes["default"].string.isRequired,
89
+ details: _propTypes["default"].arrayOf(_propTypes["default"].shape({
90
+ title: _propTypes["default"].string.isRequired,
91
+ data: _propTypes["default"].string.isRequired
92
+ }))
93
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-conversion-forms",
3
- "version": "0.0.0",
3
+ "version": "32.3.2",
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": {
@@ -37,9 +37,10 @@
37
37
  "@babel/preset-env": "^7.22.15",
38
38
  "@babel/preset-react": "^7.22.15",
39
39
  "@dotcom-tool-kit/babel": "^3.1.3",
40
- "@dotcom-tool-kit/component": "^3.1.8",
40
+ "@dotcom-tool-kit/component": "^4.0.4",
41
41
  "@dotcom-tool-kit/eslint": "^3.1.3",
42
42
  "@dotcom-tool-kit/frontend-app": "^3.1.9",
43
+ "@dotcom-tool-kit/husky-npm": "^4.1.0",
43
44
  "@dotcom-tool-kit/jest": "^3.2.0",
44
45
  "@dotcom-tool-kit/lint-staged": "^4.1.3",
45
46
  "@dotcom-tool-kit/logger": "^3.1.1",
@@ -28,10 +28,10 @@ const UKDeliveryOptions = {
28
28
  PV: {
29
29
  title: 'Paper vouchers',
30
30
  description:
31
- '13-week voucher pack delivered quarterly and redeemable at retailers nationwide. COVID-19 - make sure your preferred newsagent or retailer is open and/or delivering before you select this option.',
31
+ '13-week voucher pack delivered quarterly and redeemable at retailers nationwide.',
32
32
  },
33
33
  HD: {
34
- title: 'Home delivery',
34
+ title: 'Hand delivery',
35
35
  description: 'Free delivery to your home or office before 7am.',
36
36
  },
37
37
  EV: {
@@ -114,7 +114,7 @@ const deliveryOptionMessages = [
114
114
  deliveryOnPublicationDate: false,
115
115
  flightMarket: true,
116
116
  country: [printRegions.cemeaV1, printRegions.cemeaV2, printRegions.apac],
117
- title: 'Hand Delivery',
117
+ title: 'Hand delivery',
118
118
  description:
119
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
120
  },
@@ -127,7 +127,7 @@ const deliveryOptionMessages = [
127
127
  distributorType: HAND_DELIVERY,
128
128
  deliveryOnPublicationDate: true,
129
129
  flightMarket: true,
130
- title: 'Hand Delivery',
130
+ title: 'Hand delivery',
131
131
  country: [printRegions.cemeaV1, printRegions.cemeaV2, printRegions.apac],
132
132
  description:
133
133
  'Enjoy delivery of the newspaper to your home or office address. FT Weekend will be delivered on Sunday or Monday.',
@@ -142,7 +142,7 @@ const deliveryOptionMessages = [
142
142
  deliveryOnPublicationDate: true,
143
143
  flightMarket: false,
144
144
  country: [printRegions.cemeaV1, printRegions.cemeaV2, printRegions.apac],
145
- title: 'Hand Delivery',
145
+ title: 'Hand delivery',
146
146
  description:
147
147
  'Enjoy delivery of the newspaper daily to your home or office address on the day of publication.',
148
148
  },
@@ -140,7 +140,7 @@ describe('Find Custom Delivery Option', () => {
140
140
  stubOption.deliveryOnPublicationDate = false;
141
141
  stubOption.mailDelivery = false;
142
142
  const expected = {
143
- title: 'Hand Delivery',
143
+ title: 'Hand delivery',
144
144
  description:
145
145
  '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.',
146
146
  };