@financial-times/n-conversion-forms 41.1.0 → 41.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.toolkitstate/ci.json +3 -3
- package/components/__snapshots__/payment-type.spec.js.snap +150 -0
- package/components/index.js +2 -0
- package/components/payment-type.jsx +8 -0
- package/components/payment-type.stories.js +1 -0
- package/components/proceed-with-payment-link.jsx +47 -0
- package/components/proceed-with-payment-link.stories.js +31 -0
- package/components/subscription-confirmation-with-payment-link.jsx +60 -0
- package/components/subscription-confirmation-with-payment-link.stories.js +65 -0
- package/dist/index.js +15 -1
- package/dist/payment-type.jsx +11 -3
- package/dist/proceed-with-payment-link.jsx +51 -0
- package/dist/subscription-confirmation-with-payment-link.jsx +51 -0
- package/main.scss +2 -0
- package/package.json +1 -1
- package/styles/proceed-with-payment-link.scss +69 -0
- package/styles/subscription-confirmation-with-payment-link.scss +86 -0
- package/utils/payment-type.js +4 -0
- package/utils/submit.js +14 -0
- package/utils/subscription-confirmation-with-payment-link.js +78 -0
- package/utils/subscription-confirmation-with-payment-link.spec.js +117 -0
package/.toolkitstate/ci.json
CHANGED
|
@@ -82,6 +82,21 @@ exports[`PaymentType can initialise with the loader visible 1`] = `
|
|
|
82
82
|
</span>
|
|
83
83
|
</label>
|
|
84
84
|
</div>
|
|
85
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
86
|
+
<label for="zuorapaymentlink">
|
|
87
|
+
<input type="radio"
|
|
88
|
+
name="paymentType"
|
|
89
|
+
value="zuorapaymentlink"
|
|
90
|
+
id="zuorapaymentlink"
|
|
91
|
+
aria-label="Zuora Payment"
|
|
92
|
+
>
|
|
93
|
+
<span class="o-forms-input__label"
|
|
94
|
+
aria-hidden="true"
|
|
95
|
+
>
|
|
96
|
+
Zuora Payment
|
|
97
|
+
</span>
|
|
98
|
+
</label>
|
|
99
|
+
</div>
|
|
85
100
|
</div>
|
|
86
101
|
<div class="o-forms-input__error">
|
|
87
102
|
Please enter a valid payment type
|
|
@@ -173,6 +188,21 @@ exports[`PaymentType render with default props 1`] = `
|
|
|
173
188
|
</span>
|
|
174
189
|
</label>
|
|
175
190
|
</div>
|
|
191
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
192
|
+
<label for="zuorapaymentlink">
|
|
193
|
+
<input type="radio"
|
|
194
|
+
name="paymentType"
|
|
195
|
+
value="zuorapaymentlink"
|
|
196
|
+
id="zuorapaymentlink"
|
|
197
|
+
aria-label="Zuora Payment"
|
|
198
|
+
>
|
|
199
|
+
<span class="o-forms-input__label"
|
|
200
|
+
aria-hidden="true"
|
|
201
|
+
>
|
|
202
|
+
Zuora Payment
|
|
203
|
+
</span>
|
|
204
|
+
</label>
|
|
205
|
+
</div>
|
|
176
206
|
</div>
|
|
177
207
|
<div class="o-forms-input__error">
|
|
178
208
|
Please enter a valid payment type
|
|
@@ -264,6 +294,21 @@ exports[`PaymentType render with enableApplepay 1`] = `
|
|
|
264
294
|
</span>
|
|
265
295
|
</label>
|
|
266
296
|
</div>
|
|
297
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
298
|
+
<label for="zuorapaymentlink">
|
|
299
|
+
<input type="radio"
|
|
300
|
+
name="paymentType"
|
|
301
|
+
value="zuorapaymentlink"
|
|
302
|
+
id="zuorapaymentlink"
|
|
303
|
+
aria-label="Zuora Payment"
|
|
304
|
+
>
|
|
305
|
+
<span class="o-forms-input__label"
|
|
306
|
+
aria-hidden="true"
|
|
307
|
+
>
|
|
308
|
+
Zuora Payment
|
|
309
|
+
</span>
|
|
310
|
+
</label>
|
|
311
|
+
</div>
|
|
267
312
|
</div>
|
|
268
313
|
<div class="o-forms-input__error">
|
|
269
314
|
Please enter a valid payment type
|
|
@@ -355,6 +400,21 @@ exports[`PaymentType render with enableBankTransfer 1`] = `
|
|
|
355
400
|
</span>
|
|
356
401
|
</label>
|
|
357
402
|
</div>
|
|
403
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
404
|
+
<label for="zuorapaymentlink">
|
|
405
|
+
<input type="radio"
|
|
406
|
+
name="paymentType"
|
|
407
|
+
value="zuorapaymentlink"
|
|
408
|
+
id="zuorapaymentlink"
|
|
409
|
+
aria-label="Zuora Payment"
|
|
410
|
+
>
|
|
411
|
+
<span class="o-forms-input__label"
|
|
412
|
+
aria-hidden="true"
|
|
413
|
+
>
|
|
414
|
+
Zuora Payment
|
|
415
|
+
</span>
|
|
416
|
+
</label>
|
|
417
|
+
</div>
|
|
358
418
|
</div>
|
|
359
419
|
<div class="o-forms-input__error">
|
|
360
420
|
Please enter a valid payment type
|
|
@@ -446,6 +506,21 @@ exports[`PaymentType render with enableCreditcard 1`] = `
|
|
|
446
506
|
</span>
|
|
447
507
|
</label>
|
|
448
508
|
</div>
|
|
509
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
510
|
+
<label for="zuorapaymentlink">
|
|
511
|
+
<input type="radio"
|
|
512
|
+
name="paymentType"
|
|
513
|
+
value="zuorapaymentlink"
|
|
514
|
+
id="zuorapaymentlink"
|
|
515
|
+
aria-label="Zuora Payment"
|
|
516
|
+
>
|
|
517
|
+
<span class="o-forms-input__label"
|
|
518
|
+
aria-hidden="true"
|
|
519
|
+
>
|
|
520
|
+
Zuora Payment
|
|
521
|
+
</span>
|
|
522
|
+
</label>
|
|
523
|
+
</div>
|
|
449
524
|
</div>
|
|
450
525
|
<div class="o-forms-input__error">
|
|
451
526
|
Please enter a valid payment type
|
|
@@ -556,6 +631,21 @@ exports[`PaymentType render with enableDirectdebit 1`] = `
|
|
|
556
631
|
</span>
|
|
557
632
|
</label>
|
|
558
633
|
</div>
|
|
634
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
635
|
+
<label for="zuorapaymentlink">
|
|
636
|
+
<input type="radio"
|
|
637
|
+
name="paymentType"
|
|
638
|
+
value="zuorapaymentlink"
|
|
639
|
+
id="zuorapaymentlink"
|
|
640
|
+
aria-label="Zuora Payment"
|
|
641
|
+
>
|
|
642
|
+
<span class="o-forms-input__label"
|
|
643
|
+
aria-hidden="true"
|
|
644
|
+
>
|
|
645
|
+
Zuora Payment
|
|
646
|
+
</span>
|
|
647
|
+
</label>
|
|
648
|
+
</div>
|
|
559
649
|
</div>
|
|
560
650
|
<div class="o-forms-input__error">
|
|
561
651
|
Please enter a valid payment type
|
|
@@ -705,6 +795,21 @@ exports[`PaymentType render with enablePaypal 1`] = `
|
|
|
705
795
|
</span>
|
|
706
796
|
</label>
|
|
707
797
|
</div>
|
|
798
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
799
|
+
<label for="zuorapaymentlink">
|
|
800
|
+
<input type="radio"
|
|
801
|
+
name="paymentType"
|
|
802
|
+
value="zuorapaymentlink"
|
|
803
|
+
id="zuorapaymentlink"
|
|
804
|
+
aria-label="Zuora Payment"
|
|
805
|
+
>
|
|
806
|
+
<span class="o-forms-input__label"
|
|
807
|
+
aria-hidden="true"
|
|
808
|
+
>
|
|
809
|
+
Zuora Payment
|
|
810
|
+
</span>
|
|
811
|
+
</label>
|
|
812
|
+
</div>
|
|
708
813
|
</div>
|
|
709
814
|
<div class="o-forms-input__error">
|
|
710
815
|
Please enter a valid payment type
|
|
@@ -796,6 +901,21 @@ exports[`PaymentType render with isSingleTerm 1`] = `
|
|
|
796
901
|
</span>
|
|
797
902
|
</label>
|
|
798
903
|
</div>
|
|
904
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
905
|
+
<label for="zuorapaymentlink">
|
|
906
|
+
<input type="radio"
|
|
907
|
+
name="paymentType"
|
|
908
|
+
value="zuorapaymentlink"
|
|
909
|
+
id="zuorapaymentlink"
|
|
910
|
+
aria-label="Zuora Payment"
|
|
911
|
+
>
|
|
912
|
+
<span class="o-forms-input__label"
|
|
913
|
+
aria-hidden="true"
|
|
914
|
+
>
|
|
915
|
+
Zuora Payment
|
|
916
|
+
</span>
|
|
917
|
+
</label>
|
|
918
|
+
</div>
|
|
799
919
|
</div>
|
|
800
920
|
<div class="o-forms-input__error">
|
|
801
921
|
Please enter a valid payment type
|
|
@@ -900,6 +1020,21 @@ exports[`PaymentType render with isSingleTermChecked 1`] = `
|
|
|
900
1020
|
</span>
|
|
901
1021
|
</label>
|
|
902
1022
|
</div>
|
|
1023
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
1024
|
+
<label for="zuorapaymentlink">
|
|
1025
|
+
<input type="radio"
|
|
1026
|
+
name="paymentType"
|
|
1027
|
+
value="zuorapaymentlink"
|
|
1028
|
+
id="zuorapaymentlink"
|
|
1029
|
+
aria-label="Zuora Payment"
|
|
1030
|
+
>
|
|
1031
|
+
<span class="o-forms-input__label"
|
|
1032
|
+
aria-hidden="true"
|
|
1033
|
+
>
|
|
1034
|
+
Zuora Payment
|
|
1035
|
+
</span>
|
|
1036
|
+
</label>
|
|
1037
|
+
</div>
|
|
903
1038
|
</div>
|
|
904
1039
|
<div class="o-forms-input__error">
|
|
905
1040
|
Please enter a valid payment type
|
|
@@ -1005,6 +1140,21 @@ exports[`PaymentType render with value 1`] = `
|
|
|
1005
1140
|
</span>
|
|
1006
1141
|
</label>
|
|
1007
1142
|
</div>
|
|
1143
|
+
<div class="o-forms-input--radio-box__container ncf__payment-type ncf__payment-type--zuorapaymentlink ncf__hidden">
|
|
1144
|
+
<label for="zuorapaymentlink">
|
|
1145
|
+
<input type="radio"
|
|
1146
|
+
name="paymentType"
|
|
1147
|
+
value="zuorapaymentlink"
|
|
1148
|
+
id="zuorapaymentlink"
|
|
1149
|
+
aria-label="Zuora Payment"
|
|
1150
|
+
>
|
|
1151
|
+
<span class="o-forms-input__label"
|
|
1152
|
+
aria-hidden="true"
|
|
1153
|
+
>
|
|
1154
|
+
Zuora Payment
|
|
1155
|
+
</span>
|
|
1156
|
+
</label>
|
|
1157
|
+
</div>
|
|
1008
1158
|
</div>
|
|
1009
1159
|
<div class="o-forms-input__error">
|
|
1010
1160
|
Please enter a valid payment type
|
package/components/index.js
CHANGED
|
@@ -58,3 +58,5 @@ export { GoogleSignIn } from './google-sign-in';
|
|
|
58
58
|
export { TextInput } from './text-input';
|
|
59
59
|
export { DeferredBillingTerms } from './deferred-billing-terms';
|
|
60
60
|
export { YearOfBirth } from './year-of-birth';
|
|
61
|
+
export { ProceedWithPaymentLink } from './proceed-with-payment-link';
|
|
62
|
+
export { SubscriptionConfirmationWithPaymentLink } from './subscription-confirmation-with-payment-link';
|
|
@@ -42,6 +42,7 @@ export function PaymentType({
|
|
|
42
42
|
value,
|
|
43
43
|
isSingleTerm = false,
|
|
44
44
|
isSingleTermChecked = false,
|
|
45
|
+
enableZuoraPaymentLink = false,
|
|
45
46
|
}) {
|
|
46
47
|
const createSecuritySeal = () => {
|
|
47
48
|
return (
|
|
@@ -95,6 +96,11 @@ export function PaymentType({
|
|
|
95
96
|
hide: !enableBankTransfer,
|
|
96
97
|
};
|
|
97
98
|
|
|
99
|
+
const zuoraPaymentLink = {
|
|
100
|
+
id: 'zuorapaymentlink',
|
|
101
|
+
label: 'Zuora Payment',
|
|
102
|
+
hide: !enableZuoraPaymentLink,
|
|
103
|
+
};
|
|
98
104
|
const createPaymentTypes = () => {
|
|
99
105
|
const paymentTypes = [
|
|
100
106
|
paymentTypeCreditCard,
|
|
@@ -102,6 +108,7 @@ export function PaymentType({
|
|
|
102
108
|
paymentTypeDirectDebit,
|
|
103
109
|
paymentTypeApplePay,
|
|
104
110
|
paymentTypeBankTransfer,
|
|
111
|
+
zuoraPaymentLink,
|
|
105
112
|
].filter(Boolean);
|
|
106
113
|
|
|
107
114
|
return paymentTypes.map((type) => {
|
|
@@ -284,4 +291,5 @@ PaymentType.propTypes = {
|
|
|
284
291
|
value: PropTypes.string,
|
|
285
292
|
isSingleTerm: PropTypes.bool,
|
|
286
293
|
isSingleTermChecked: PropTypes.bool,
|
|
294
|
+
enableZuoraPaymentLink: PropTypes.bool,
|
|
287
295
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
export function ProceedWithPaymentLink({
|
|
5
|
+
id = 'proceedWithPaymentLink',
|
|
6
|
+
title = `By proceeding now, you're:`,
|
|
7
|
+
description,
|
|
8
|
+
listItems = [],
|
|
9
|
+
children = (
|
|
10
|
+
<button className="proceed-with-payment-link__button">Proceed</button>
|
|
11
|
+
),
|
|
12
|
+
}) {
|
|
13
|
+
return (
|
|
14
|
+
<div id={id} className="proceed-with-payment-link o-forms-field">
|
|
15
|
+
{title && <h2 className="proceed-with-payment-link__heading">{title}</h2>}
|
|
16
|
+
{description && (
|
|
17
|
+
<p className="proceed-with-payment-link__description">{description}</p>
|
|
18
|
+
)}
|
|
19
|
+
{listItems.length > 0 && (
|
|
20
|
+
<ul className="proceed-with-payment-link__list">
|
|
21
|
+
{listItems.map((item, index) => (
|
|
22
|
+
<li key={index} className="proceed-with-payment-link__list-item">
|
|
23
|
+
<span
|
|
24
|
+
className="proceed-with-payment-link__icon"
|
|
25
|
+
aria-hidden="true"
|
|
26
|
+
></span>
|
|
27
|
+
<span className="proceed-with-payment-link__list-item-text">
|
|
28
|
+
{item}
|
|
29
|
+
</span>
|
|
30
|
+
</li>
|
|
31
|
+
))}
|
|
32
|
+
</ul>
|
|
33
|
+
)}
|
|
34
|
+
{children && (
|
|
35
|
+
<div className="proceed-with-payment-link__actions">{children}</div>
|
|
36
|
+
)}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ProceedWithPaymentLink.propTypes = {
|
|
42
|
+
id: PropTypes.string,
|
|
43
|
+
title: PropTypes.string,
|
|
44
|
+
description: PropTypes.string,
|
|
45
|
+
listItems: PropTypes.arrayOf(PropTypes.string),
|
|
46
|
+
children: PropTypes.node,
|
|
47
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ProceedWithPaymentLink } from './proceed-with-payment-link';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Proceed With Payment Link',
|
|
6
|
+
component: ProceedWithPaymentLink,
|
|
7
|
+
argTypes: {
|
|
8
|
+
id: { control: 'text' },
|
|
9
|
+
title: { control: 'text' },
|
|
10
|
+
description: { control: 'text' },
|
|
11
|
+
listItems: { control: 'array' },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const Basic = (args) => (
|
|
16
|
+
<ProceedWithPaymentLink {...args}>
|
|
17
|
+
<button className="proceed-with-payment-link__button">
|
|
18
|
+
{args.buttonText}
|
|
19
|
+
</button>
|
|
20
|
+
</ProceedWithPaymentLink>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
Basic.args = {
|
|
24
|
+
id: 'payment-section',
|
|
25
|
+
title: `By proceeding now, you're:`,
|
|
26
|
+
listItems: [
|
|
27
|
+
'Activating the customer’s subscription',
|
|
28
|
+
'Creating a payment link for the customer to complete their payment on Zuora, which they must do within 24 hours',
|
|
29
|
+
],
|
|
30
|
+
buttonText: 'Proceed now',
|
|
31
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
export function SubscriptionConfirmationWithPaymentLink({
|
|
5
|
+
id = 'subscriptionConfirmationWithPaymentLink',
|
|
6
|
+
header = 'The subscription is now active',
|
|
7
|
+
body,
|
|
8
|
+
paymentLink,
|
|
9
|
+
}) {
|
|
10
|
+
return (
|
|
11
|
+
<div id={id} className="subscription-active-with-payment-link">
|
|
12
|
+
{/* Header */}
|
|
13
|
+
{header && (
|
|
14
|
+
<div className="subscription-active-with-payment-link__header">
|
|
15
|
+
<div className="subscription-active-with-payment-link__icon-container">
|
|
16
|
+
<span className="subscription-active-with-payment-link__icon"></span>
|
|
17
|
+
</div>
|
|
18
|
+
<h3 className="subscription-active-with-payment-link__title">
|
|
19
|
+
{header}
|
|
20
|
+
</h3>
|
|
21
|
+
</div>
|
|
22
|
+
)}
|
|
23
|
+
|
|
24
|
+
{/* Body */}
|
|
25
|
+
{body && (
|
|
26
|
+
<p
|
|
27
|
+
className="subscription-active-with-payment-link__description"
|
|
28
|
+
dangerouslySetInnerHTML={{ __html: body }}
|
|
29
|
+
/>
|
|
30
|
+
)}
|
|
31
|
+
|
|
32
|
+
{/* Payment Link Section */}
|
|
33
|
+
{paymentLink && (
|
|
34
|
+
<>
|
|
35
|
+
<label className="subscription-active-with-payment-link__label">
|
|
36
|
+
Zuora Payment Link
|
|
37
|
+
</label>
|
|
38
|
+
<div className="subscription-active-with-payment-link__payment-box">
|
|
39
|
+
<input
|
|
40
|
+
type="text"
|
|
41
|
+
value={paymentLink}
|
|
42
|
+
readOnly
|
|
43
|
+
className="subscription-active-with-payment-link__input"
|
|
44
|
+
/>
|
|
45
|
+
<button className="subscription-active-with-payment-link__button">
|
|
46
|
+
Copy
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
</>
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
SubscriptionConfirmationWithPaymentLink.propTypes = {
|
|
56
|
+
id: PropTypes.string,
|
|
57
|
+
header: PropTypes.string,
|
|
58
|
+
body: PropTypes.string,
|
|
59
|
+
paymentLink: PropTypes.string,
|
|
60
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { action } from '@storybook/addon-actions';
|
|
3
|
+
import { SubscriptionConfirmationWithPaymentLink } from './subscription-confirmation-with-payment-link';
|
|
4
|
+
import SubscriptionConfirmationWithPaymentLinkUtil from '../utils/subscription-confirmation-with-payment-link';
|
|
5
|
+
|
|
6
|
+
// Initialize the utility after story renders
|
|
7
|
+
const initializeUtil = () => {
|
|
8
|
+
const subscriptionConfirmation =
|
|
9
|
+
new SubscriptionConfirmationWithPaymentLinkUtil(document);
|
|
10
|
+
subscriptionConfirmation.handleCopyPaymentLink();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
title: 'Subscription Confirmation With Payment Link',
|
|
15
|
+
component: SubscriptionConfirmationWithPaymentLink,
|
|
16
|
+
argTypes: {
|
|
17
|
+
body: { control: 'text' }, // Allows input of raw HTML in Storybook UI
|
|
18
|
+
},
|
|
19
|
+
parameters: {
|
|
20
|
+
docs: {
|
|
21
|
+
description: {
|
|
22
|
+
component:
|
|
23
|
+
'A component that displays subscription confirmation with a copyable payment link.',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function handleButtonClick(event) {
|
|
30
|
+
const button = event.target.closest('button');
|
|
31
|
+
if (button) {
|
|
32
|
+
navigator.clipboard
|
|
33
|
+
.readText()
|
|
34
|
+
.then((copiedText) => action('copied')(copiedText));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// HOC to add utility initialization for stories with payment link
|
|
39
|
+
const withUtilInit = (Story, args) => {
|
|
40
|
+
if (args.paymentLink) {
|
|
41
|
+
setTimeout(initializeUtil, 0);
|
|
42
|
+
}
|
|
43
|
+
return (
|
|
44
|
+
<div className="ncf" onClick={handleButtonClick}>
|
|
45
|
+
<Story {...args} />
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const WithPaymentLink = (args) =>
|
|
51
|
+
withUtilInit(SubscriptionConfirmationWithPaymentLink, args);
|
|
52
|
+
|
|
53
|
+
WithPaymentLink.args = {
|
|
54
|
+
header: 'The subscription is now active',
|
|
55
|
+
body: 'To remain active, the customer must pay using the Zuora Payment link below <strong>within the next 24 hours</strong>.',
|
|
56
|
+
paymentLink: 'https://knowledgecenter.zuora.com/Zuora_Payments/Process',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const WithoutPaymentLink = (args) =>
|
|
60
|
+
withUtilInit(SubscriptionConfirmationWithPaymentLink, args);
|
|
61
|
+
|
|
62
|
+
WithoutPaymentLink.args = {
|
|
63
|
+
header: 'The subscription is now active',
|
|
64
|
+
body: 'Your subscription has been activated successfully.',
|
|
65
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -309,6 +309,12 @@ Object.defineProperty(exports, "Position", {
|
|
|
309
309
|
return _position.Position;
|
|
310
310
|
}
|
|
311
311
|
});
|
|
312
|
+
Object.defineProperty(exports, "ProceedWithPaymentLink", {
|
|
313
|
+
enumerable: true,
|
|
314
|
+
get: function get() {
|
|
315
|
+
return _proceedWithPaymentLink.ProceedWithPaymentLink;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
312
318
|
Object.defineProperty(exports, "ProgressIndicator", {
|
|
313
319
|
enumerable: true,
|
|
314
320
|
get: function get() {
|
|
@@ -345,6 +351,12 @@ Object.defineProperty(exports, "Submit", {
|
|
|
345
351
|
return _submit.Submit;
|
|
346
352
|
}
|
|
347
353
|
});
|
|
354
|
+
Object.defineProperty(exports, "SubscriptionConfirmationWithPaymentLink", {
|
|
355
|
+
enumerable: true,
|
|
356
|
+
get: function get() {
|
|
357
|
+
return _subscriptionConfirmationWithPaymentLink.SubscriptionConfirmationWithPaymentLink;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
348
360
|
Object.defineProperty(exports, "TextInput", {
|
|
349
361
|
enumerable: true,
|
|
350
362
|
get: function get() {
|
|
@@ -422,4 +434,6 @@ var _graduationDate = require("./graduation-date");
|
|
|
422
434
|
var _googleSignIn = require("./google-sign-in");
|
|
423
435
|
var _textInput = require("./text-input");
|
|
424
436
|
var _deferredBillingTerms = require("./deferred-billing-terms");
|
|
425
|
-
var _yearOfBirth = require("./year-of-birth");
|
|
437
|
+
var _yearOfBirth = require("./year-of-birth");
|
|
438
|
+
var _proceedWithPaymentLink = require("./proceed-with-payment-link");
|
|
439
|
+
var _subscriptionConfirmationWithPaymentLink = require("./subscription-confirmation-with-payment-link");
|
package/dist/payment-type.jsx
CHANGED
|
@@ -52,7 +52,9 @@ function PaymentType(_ref) {
|
|
|
52
52
|
_ref$isSingleTerm = _ref.isSingleTerm,
|
|
53
53
|
isSingleTerm = _ref$isSingleTerm === void 0 ? false : _ref$isSingleTerm,
|
|
54
54
|
_ref$isSingleTermChec = _ref.isSingleTermChecked,
|
|
55
|
-
isSingleTermChecked = _ref$isSingleTermChec === void 0 ? false : _ref$isSingleTermChec
|
|
55
|
+
isSingleTermChecked = _ref$isSingleTermChec === void 0 ? false : _ref$isSingleTermChec,
|
|
56
|
+
_ref$enableZuoraPayme = _ref.enableZuoraPaymentLink,
|
|
57
|
+
enableZuoraPaymentLink = _ref$enableZuoraPayme === void 0 ? false : _ref$enableZuoraPayme;
|
|
56
58
|
var createSecuritySeal = function createSecuritySeal() {
|
|
57
59
|
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
58
60
|
className: "ncf__security-seal",
|
|
@@ -90,8 +92,13 @@ function PaymentType(_ref) {
|
|
|
90
92
|
label: 'Bank Transfer',
|
|
91
93
|
hide: !enableBankTransfer
|
|
92
94
|
};
|
|
95
|
+
var zuoraPaymentLink = {
|
|
96
|
+
id: 'zuorapaymentlink',
|
|
97
|
+
label: 'Zuora Payment',
|
|
98
|
+
hide: !enableZuoraPaymentLink
|
|
99
|
+
};
|
|
93
100
|
var createPaymentTypes = function createPaymentTypes() {
|
|
94
|
-
var paymentTypes = [paymentTypeCreditCard, paymentTypePaypal(), paymentTypeDirectDebit, paymentTypeApplePay, paymentTypeBankTransfer].filter(Boolean);
|
|
101
|
+
var paymentTypes = [paymentTypeCreditCard, paymentTypePaypal(), paymentTypeDirectDebit, paymentTypeApplePay, paymentTypeBankTransfer, zuoraPaymentLink].filter(Boolean);
|
|
95
102
|
return paymentTypes.map(function (type) {
|
|
96
103
|
if (type.id === undefined) {
|
|
97
104
|
return type;
|
|
@@ -207,5 +214,6 @@ PaymentType.propTypes = {
|
|
|
207
214
|
inputId: _propTypes["default"].string,
|
|
208
215
|
value: _propTypes["default"].string,
|
|
209
216
|
isSingleTerm: _propTypes["default"].bool,
|
|
210
|
-
isSingleTermChecked: _propTypes["default"].bool
|
|
217
|
+
isSingleTermChecked: _propTypes["default"].bool,
|
|
218
|
+
enableZuoraPaymentLink: _propTypes["default"].bool
|
|
211
219
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.ProceedWithPaymentLink = ProceedWithPaymentLink;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
+
function ProceedWithPaymentLink(_ref) {
|
|
11
|
+
var _ref$id = _ref.id,
|
|
12
|
+
id = _ref$id === void 0 ? 'proceedWithPaymentLink' : _ref$id,
|
|
13
|
+
_ref$title = _ref.title,
|
|
14
|
+
title = _ref$title === void 0 ? "By proceeding now, you're:" : _ref$title,
|
|
15
|
+
description = _ref.description,
|
|
16
|
+
_ref$listItems = _ref.listItems,
|
|
17
|
+
listItems = _ref$listItems === void 0 ? [] : _ref$listItems,
|
|
18
|
+
_ref$children = _ref.children,
|
|
19
|
+
children = _ref$children === void 0 ? /*#__PURE__*/_react["default"].createElement("button", {
|
|
20
|
+
className: "proceed-with-payment-link__button"
|
|
21
|
+
}, "Proceed") : _ref$children;
|
|
22
|
+
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
23
|
+
id: id,
|
|
24
|
+
className: "proceed-with-payment-link o-forms-field"
|
|
25
|
+
}, title && /*#__PURE__*/_react["default"].createElement("h2", {
|
|
26
|
+
className: "proceed-with-payment-link__heading"
|
|
27
|
+
}, title), description && /*#__PURE__*/_react["default"].createElement("p", {
|
|
28
|
+
className: "proceed-with-payment-link__description"
|
|
29
|
+
}, description), listItems.length > 0 && /*#__PURE__*/_react["default"].createElement("ul", {
|
|
30
|
+
className: "proceed-with-payment-link__list"
|
|
31
|
+
}, listItems.map(function (item, index) {
|
|
32
|
+
return /*#__PURE__*/_react["default"].createElement("li", {
|
|
33
|
+
key: index,
|
|
34
|
+
className: "proceed-with-payment-link__list-item"
|
|
35
|
+
}, /*#__PURE__*/_react["default"].createElement("span", {
|
|
36
|
+
className: "proceed-with-payment-link__icon",
|
|
37
|
+
"aria-hidden": "true"
|
|
38
|
+
}), /*#__PURE__*/_react["default"].createElement("span", {
|
|
39
|
+
className: "proceed-with-payment-link__list-item-text"
|
|
40
|
+
}, item));
|
|
41
|
+
})), children && /*#__PURE__*/_react["default"].createElement("div", {
|
|
42
|
+
className: "proceed-with-payment-link__actions"
|
|
43
|
+
}, children));
|
|
44
|
+
}
|
|
45
|
+
ProceedWithPaymentLink.propTypes = {
|
|
46
|
+
id: _propTypes["default"].string,
|
|
47
|
+
title: _propTypes["default"].string,
|
|
48
|
+
description: _propTypes["default"].string,
|
|
49
|
+
listItems: _propTypes["default"].arrayOf(_propTypes["default"].string),
|
|
50
|
+
children: _propTypes["default"].node
|
|
51
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.SubscriptionConfirmationWithPaymentLink = SubscriptionConfirmationWithPaymentLink;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
+
function SubscriptionConfirmationWithPaymentLink(_ref) {
|
|
11
|
+
var _ref$id = _ref.id,
|
|
12
|
+
id = _ref$id === void 0 ? 'subscriptionConfirmationWithPaymentLink' : _ref$id,
|
|
13
|
+
_ref$header = _ref.header,
|
|
14
|
+
header = _ref$header === void 0 ? 'The subscription is now active' : _ref$header,
|
|
15
|
+
body = _ref.body,
|
|
16
|
+
paymentLink = _ref.paymentLink;
|
|
17
|
+
return /*#__PURE__*/_react["default"].createElement("div", {
|
|
18
|
+
id: id,
|
|
19
|
+
className: "subscription-active-with-payment-link"
|
|
20
|
+
}, header && /*#__PURE__*/_react["default"].createElement("div", {
|
|
21
|
+
className: "subscription-active-with-payment-link__header"
|
|
22
|
+
}, /*#__PURE__*/_react["default"].createElement("div", {
|
|
23
|
+
className: "subscription-active-with-payment-link__icon-container"
|
|
24
|
+
}, /*#__PURE__*/_react["default"].createElement("span", {
|
|
25
|
+
className: "subscription-active-with-payment-link__icon"
|
|
26
|
+
})), /*#__PURE__*/_react["default"].createElement("h3", {
|
|
27
|
+
className: "subscription-active-with-payment-link__title"
|
|
28
|
+
}, header)), body && /*#__PURE__*/_react["default"].createElement("p", {
|
|
29
|
+
className: "subscription-active-with-payment-link__description",
|
|
30
|
+
dangerouslySetInnerHTML: {
|
|
31
|
+
__html: body
|
|
32
|
+
}
|
|
33
|
+
}), paymentLink && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("label", {
|
|
34
|
+
className: "subscription-active-with-payment-link__label"
|
|
35
|
+
}, "Zuora Payment Link"), /*#__PURE__*/_react["default"].createElement("div", {
|
|
36
|
+
className: "subscription-active-with-payment-link__payment-box"
|
|
37
|
+
}, /*#__PURE__*/_react["default"].createElement("input", {
|
|
38
|
+
type: "text",
|
|
39
|
+
value: paymentLink,
|
|
40
|
+
readOnly: true,
|
|
41
|
+
className: "subscription-active-with-payment-link__input"
|
|
42
|
+
}), /*#__PURE__*/_react["default"].createElement("button", {
|
|
43
|
+
className: "subscription-active-with-payment-link__button"
|
|
44
|
+
}, "Copy"))));
|
|
45
|
+
}
|
|
46
|
+
SubscriptionConfirmationWithPaymentLink.propTypes = {
|
|
47
|
+
id: _propTypes["default"].string,
|
|
48
|
+
header: _propTypes["default"].string,
|
|
49
|
+
body: _propTypes["default"].string,
|
|
50
|
+
paymentLink: _propTypes["default"].string
|
|
51
|
+
};
|
package/main.scss
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
@import './styles/google-sign-in';
|
|
24
24
|
@import './styles/confirmation';
|
|
25
25
|
@import './styles/ft-edit-registration-confirmation';
|
|
26
|
+
@import './styles/subscription-confirmation-with-payment-link';
|
|
27
|
+
@import './styles/proceed-with-payment-link';
|
|
26
28
|
|
|
27
29
|
@include oTypography();
|
|
28
30
|
@include oFonts();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financial-times/n-conversion-forms",
|
|
3
|
-
"version": "41.
|
|
3
|
+
"version": "41.2.0",
|
|
4
4
|
"description": "Containing jsx components and styles for forms included on Accounts and Acquisition apps (next-signup, next-profile, next-retention, etc).",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
@import '@financial-times/o-icons/main';
|
|
2
|
+
|
|
3
|
+
.proceed-with-payment-link {
|
|
4
|
+
font-family: oFontsGetFontFamilyWithFallbacks(MetricWeb);
|
|
5
|
+
font-weight: 400;
|
|
6
|
+
background: oColorsByName('ft-grey');
|
|
7
|
+
padding: 24px;
|
|
8
|
+
color: oColorsByName('white');
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
|
|
12
|
+
@include oGridRespondTo($from: M) {
|
|
13
|
+
padding: oSpacingByName('s6') oSpacingByName('s6') oSpacingByName('s8');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.proceed-with-payment-link__heading {
|
|
18
|
+
margin: 0px;
|
|
19
|
+
margin-bottom: oSpacingByName('s1');
|
|
20
|
+
font-weight: 400;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.proceed-with-payment-link__description {
|
|
24
|
+
color: oColorsByName('white');
|
|
25
|
+
margin-top: 0;
|
|
26
|
+
padding-top: 0;
|
|
27
|
+
margin-bottom: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.proceed-with-payment-link__list {
|
|
31
|
+
list-style: none;
|
|
32
|
+
padding: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.proceed-with-payment-link__list-item {
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: flex-start;
|
|
38
|
+
margin-bottom: oSpacingByName('s2');
|
|
39
|
+
flex-wrap: nowrap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.proceed-with-payment-link__icon {
|
|
43
|
+
@include oIconsContent($icon-name: 'tick', $color: oColorsByName('ft-pink'), $size: 26);
|
|
44
|
+
margin-right: oSpacingByName('s3');
|
|
45
|
+
flex-shrink: 0;
|
|
46
|
+
min-width: 26px;
|
|
47
|
+
display: flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.proceed-with-payment-link__list-item-text {
|
|
53
|
+
flex-grow: 1;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.proceed-with-payment-link__actions {
|
|
57
|
+
margin-top: oSpacingByName('s2');
|
|
58
|
+
|
|
59
|
+
button {
|
|
60
|
+
@include oButtonsContent($opts: ('type': 'primary', 'theme': ('color': 'ft-pink')));
|
|
61
|
+
color: oColorsByName('ft-grey');
|
|
62
|
+
padding: oSpacingByName('s3') oSpacingByName('s6');
|
|
63
|
+
width: 100%;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
button:hover {
|
|
67
|
+
background-color: oColorsMix('ft-pink', 'black', 80);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
@import '@financial-times/o-colors/main';
|
|
2
|
+
@import '@financial-times/o-buttons/main';
|
|
3
|
+
|
|
4
|
+
.subscription-active-with-payment-link {
|
|
5
|
+
background: oColorsByName('ft-grey');
|
|
6
|
+
padding: oSpacingByName('s6') oSpacingByName('s6') oSpacingByName('s8');
|
|
7
|
+
color: oColorsByName('white');
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.subscription-active-with-payment-link--responsive {
|
|
13
|
+
@include oGridRespondTo($from: M) {
|
|
14
|
+
padding: oSpacingByName('s6') 50px oSpacingByName('s8');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.subscription-active-with-payment-link__header {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.subscription-active-with-payment-link__icon-container {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
width: 24px;
|
|
28
|
+
height: 24px;
|
|
29
|
+
background-color: oColorsByName('ft-pink');
|
|
30
|
+
border-radius: 50%;
|
|
31
|
+
margin-right: oSpacingByName('s4');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.subscription-active-with-payment-link__icon {
|
|
35
|
+
@include oIconsContent($icon-name: 'tick', $color: oColorsByName('ft-grey'), $size: 34);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.subscription-active-with-payment-link__title {
|
|
39
|
+
margin: 0;
|
|
40
|
+
@include oTypographySans($scale: 4, $weight: 'regular');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.subscription-active-with-payment-link__description {
|
|
44
|
+
@include oTypographySans($scale: 1);
|
|
45
|
+
color: oColorsByName('white');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.subscription-active-with-payment-link__label {
|
|
49
|
+
@include oTypographySans($scale: 1);
|
|
50
|
+
color: oColorsByName('ft-pink');
|
|
51
|
+
margin-bottom: oSpacingByName('s2');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.subscription-active-with-payment-link__payment-box {
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
background: oColorsByName('ft-grey');
|
|
58
|
+
overflow: hidden;
|
|
59
|
+
gap: oSpacingByName('s2');
|
|
60
|
+
width: 100%;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.subscription-active-with-payment-link__input {
|
|
64
|
+
flex-grow: 1;
|
|
65
|
+
background: oColorsByName('white-60');
|
|
66
|
+
border: none;
|
|
67
|
+
box-sizing: border-box;
|
|
68
|
+
color: oColorsByName('black-60');
|
|
69
|
+
@include oTypographySans($scale: 1);
|
|
70
|
+
padding: 10px oSpacingByName('s4');
|
|
71
|
+
text-overflow: ellipsis;
|
|
72
|
+
height: 40px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.subscription-active-with-payment-link__button {
|
|
76
|
+
@include oTypographySans($scale: 1);
|
|
77
|
+
@include oButtonsContent($opts: ('type': 'primary', 'theme': ('color': 'ft-pink')));
|
|
78
|
+
color: oColorsByName('ft-grey');
|
|
79
|
+
transition: background 0.2s ease-in-out;
|
|
80
|
+
padding: 10px 20px;
|
|
81
|
+
height: 40px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.subscription-active-with-payment-link__button--copied {
|
|
85
|
+
background-color: oColorsMix($color: 'ft-pink', $background: 'white', $percentage: 80%);
|
|
86
|
+
}
|
package/utils/payment-type.js
CHANGED
package/utils/submit.js
CHANGED
|
@@ -58,6 +58,20 @@ class Submit {
|
|
|
58
58
|
isDisabled() {
|
|
59
59
|
return !!this.$submit.disabled;
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Hides the submit button
|
|
64
|
+
*/
|
|
65
|
+
hide() {
|
|
66
|
+
this.$submit.classList.add('ncf__hidden');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Shows the submit button
|
|
71
|
+
*/
|
|
72
|
+
show() {
|
|
73
|
+
this.$submit.classList.remove('ncf__hidden');
|
|
74
|
+
}
|
|
61
75
|
}
|
|
62
76
|
|
|
63
77
|
module.exports = Submit;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for the subscription confirmation with payment link component
|
|
3
|
+
* @example
|
|
4
|
+
* const subscriptionConfirmation = new SubscriptionConfirmationWithPaymentLink(document);
|
|
5
|
+
* subscriptionConfirmation.handleCopyPaymentLink((copiedText) => {
|
|
6
|
+
* // Handle copy event
|
|
7
|
+
* });
|
|
8
|
+
*/
|
|
9
|
+
class SubscriptionConfirmationWithPaymentLink {
|
|
10
|
+
static CONTAINER_QUERY_SELECTOR = '.subscription-active-with-payment-link';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initialize the SubscriptionConfirmationWithPaymentLink utility
|
|
14
|
+
* @param {Element} element Usually the window.document
|
|
15
|
+
* @throws If the document not passed
|
|
16
|
+
* @throws When the component element not found
|
|
17
|
+
*/
|
|
18
|
+
constructor(element) {
|
|
19
|
+
if (!element) {
|
|
20
|
+
throw new Error('Please supply a DOM element');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.$container = element.querySelector(
|
|
24
|
+
'.subscription-active-with-payment-link'
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (!this.$container) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
'Please include the subscription confirmation with payment link component on the page'
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.$button = this.$container.querySelector(
|
|
34
|
+
'.subscription-active-with-payment-link__button'
|
|
35
|
+
);
|
|
36
|
+
this.$input = this.$container.querySelector(
|
|
37
|
+
'.subscription-active-with-payment-link__input'
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get the payment link value
|
|
43
|
+
* @return {String}
|
|
44
|
+
*/
|
|
45
|
+
getValue() {
|
|
46
|
+
return this.$input ? this.$input.value : '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Handle copying the payment link
|
|
51
|
+
* @param {Function} callback Called after successful copy
|
|
52
|
+
*/
|
|
53
|
+
handleCopyPaymentLink(callback) {
|
|
54
|
+
if (!this.$button || !this.$input) return;
|
|
55
|
+
|
|
56
|
+
this.$button.addEventListener('click', () => {
|
|
57
|
+
navigator.clipboard.writeText(this.getValue()).then(() => {
|
|
58
|
+
this.$button.textContent = 'Copied';
|
|
59
|
+
this.$button.classList.add(
|
|
60
|
+
'subscription-active-with-payment-link__button--copied'
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
this.$button.textContent = 'Copy';
|
|
65
|
+
this.$button.classList.remove(
|
|
66
|
+
'subscription-active-with-payment-link__button--copied'
|
|
67
|
+
);
|
|
68
|
+
}, 2000);
|
|
69
|
+
|
|
70
|
+
if (callback) {
|
|
71
|
+
callback(this.getValue());
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = SubscriptionConfirmationWithPaymentLink;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const SubscriptionConfirmationWithPaymentLink = require('./subscription-confirmation-with-payment-link');
|
|
2
|
+
|
|
3
|
+
describe('SubscriptionConfirmationWithPaymentLink', () => {
|
|
4
|
+
let subscriptionConfirmation;
|
|
5
|
+
let documentStub;
|
|
6
|
+
let containerStub;
|
|
7
|
+
let buttonStub;
|
|
8
|
+
let inputStub;
|
|
9
|
+
let clipboardStub;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
buttonStub = {
|
|
13
|
+
addEventListener: jest.fn(),
|
|
14
|
+
classList: {
|
|
15
|
+
add: jest.fn(),
|
|
16
|
+
remove: jest.fn(),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
inputStub = { value: 'test-link' };
|
|
20
|
+
containerStub = {
|
|
21
|
+
querySelector: jest.fn((selector) => {
|
|
22
|
+
if (selector.includes('button')) return buttonStub;
|
|
23
|
+
if (selector.includes('input')) return inputStub;
|
|
24
|
+
return null;
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
documentStub = {
|
|
28
|
+
querySelector: jest.fn(() => containerStub),
|
|
29
|
+
};
|
|
30
|
+
clipboardStub = Promise.resolve();
|
|
31
|
+
global.navigator.clipboard = { writeText: jest.fn(() => clipboardStub) };
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
jest.clearAllMocks();
|
|
36
|
+
jest.useRealTimers();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('constructor', () => {
|
|
40
|
+
it('throws an error if nothing passed', () => {
|
|
41
|
+
expect(() => {
|
|
42
|
+
new SubscriptionConfirmationWithPaymentLink();
|
|
43
|
+
}).toThrow();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('throws an error if container not present', () => {
|
|
47
|
+
documentStub.querySelector.mockReturnValue(false);
|
|
48
|
+
expect(() => {
|
|
49
|
+
new SubscriptionConfirmationWithPaymentLink(documentStub);
|
|
50
|
+
}).toThrow();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('handleCopyPaymentLink', () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
documentStub.querySelector.mockReturnValue(containerStub);
|
|
57
|
+
subscriptionConfirmation = new SubscriptionConfirmationWithPaymentLink(
|
|
58
|
+
documentStub
|
|
59
|
+
);
|
|
60
|
+
jest.useFakeTimers();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('adds click event listener to button', () => {
|
|
64
|
+
subscriptionConfirmation.handleCopyPaymentLink();
|
|
65
|
+
expect(buttonStub.addEventListener).toHaveBeenCalledWith(
|
|
66
|
+
'click',
|
|
67
|
+
expect.any(Function)
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('copies input value to clipboard on click', async () => {
|
|
72
|
+
const callback = jest.fn();
|
|
73
|
+
subscriptionConfirmation.handleCopyPaymentLink(callback);
|
|
74
|
+
|
|
75
|
+
const clickHandler = buttonStub.addEventListener.mock.calls[0][1];
|
|
76
|
+
await clickHandler();
|
|
77
|
+
|
|
78
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith('test-link');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('updates button text and style after copy', async () => {
|
|
82
|
+
subscriptionConfirmation.handleCopyPaymentLink();
|
|
83
|
+
|
|
84
|
+
const clickHandler = buttonStub.addEventListener.mock.calls[0][1];
|
|
85
|
+
await clickHandler();
|
|
86
|
+
|
|
87
|
+
expect(buttonStub.textContent).toBe('Copied');
|
|
88
|
+
expect(buttonStub.classList.add).toHaveBeenCalledWith(
|
|
89
|
+
'subscription-active-with-payment-link__button--copied'
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('resets button after timeout', async () => {
|
|
94
|
+
subscriptionConfirmation.handleCopyPaymentLink();
|
|
95
|
+
|
|
96
|
+
const clickHandler = buttonStub.addEventListener.mock.calls[0][1];
|
|
97
|
+
await clickHandler();
|
|
98
|
+
|
|
99
|
+
jest.advanceTimersByTime(2000);
|
|
100
|
+
|
|
101
|
+
expect(buttonStub.textContent).toBe('Copy');
|
|
102
|
+
expect(buttonStub.classList.remove).toHaveBeenCalledWith(
|
|
103
|
+
'subscription-active-with-payment-link__button--copied'
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('calls callback with copied value', async () => {
|
|
108
|
+
const callback = jest.fn();
|
|
109
|
+
subscriptionConfirmation.handleCopyPaymentLink(callback);
|
|
110
|
+
|
|
111
|
+
const clickHandler = buttonStub.addEventListener.mock.calls[0][1];
|
|
112
|
+
await clickHandler();
|
|
113
|
+
|
|
114
|
+
expect(callback).toHaveBeenCalledWith('test-link');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|