@financial-times/n-conversion-forms 28.10.0 → 29.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.
- package/components/accept-terms-business.jsx +121 -0
- package/components/accept-terms-business.spec.jsx +47 -0
- package/components/accept-terms-business.stories.js +32 -0
- package/components/accept-terms-privacy-policy.jsx +93 -0
- package/components/accept-terms-privacy-policy.spec.js +37 -0
- package/components/accept-terms-privacy-policy.stories.js +24 -0
- package/components/accept-terms-subscription.jsx +215 -0
- package/components/accept-terms-subscription.spec.js +94 -0
- package/components/accept-terms-subscription.stories.js +51 -0
- package/components/index.jsx +3 -0
- package/dist/accept-terms-business.js +74 -0
- package/dist/accept-terms-business.spec.js +40 -0
- package/dist/accept-terms-privacy-policy.js +71 -0
- package/dist/accept-terms-subscription.js +124 -0
- package/dist/index.js +21 -0
- package/package.json +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
|
|
5
|
+
export function AcceptTermsBusiness({
|
|
6
|
+
hasError = false,
|
|
7
|
+
isB2b = false,
|
|
8
|
+
isEmbedded = false,
|
|
9
|
+
isTrial = false,
|
|
10
|
+
}) {
|
|
11
|
+
const divProps = {
|
|
12
|
+
id: 'acceptTermsField',
|
|
13
|
+
className: 'o-forms-field o-layout-typography ncf__validation-error',
|
|
14
|
+
'data-validate': 'required,checked',
|
|
15
|
+
};
|
|
16
|
+
const labelClassName = classNames([
|
|
17
|
+
'o-forms-input',
|
|
18
|
+
'o-forms-input--checkbox',
|
|
19
|
+
{
|
|
20
|
+
'o-forms-input--invalid': hasError,
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
const inputProps = {
|
|
25
|
+
id: 'termsAcceptance',
|
|
26
|
+
type: 'checkbox',
|
|
27
|
+
name: 'termsAcceptance',
|
|
28
|
+
value: 'true',
|
|
29
|
+
'data-trackable': 'field-terms',
|
|
30
|
+
'aria-required': 'true',
|
|
31
|
+
required: true,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const b2bTerms = isB2b ? (
|
|
35
|
+
<li>
|
|
36
|
+
<span className="terms-b2b">
|
|
37
|
+
By submitting this form, you indicate your consent to also being
|
|
38
|
+
contacted by Financial Times by email, post, or phone about our other
|
|
39
|
+
products, services or special offers unless you untick this box.
|
|
40
|
+
</span>
|
|
41
|
+
</li>
|
|
42
|
+
) : (
|
|
43
|
+
<li>
|
|
44
|
+
<span className="terms-default">
|
|
45
|
+
I confirm I am 16 years or older and have read and agree to the{' '}
|
|
46
|
+
<a
|
|
47
|
+
className="ncf__link--external"
|
|
48
|
+
href="http://help.ft.com/help/legal-privacy/terms-conditions/"
|
|
49
|
+
target={isEmbedded ? '_top' : '_blank'}
|
|
50
|
+
rel="noopener noreferrer"
|
|
51
|
+
data-trackable="terms-and-conditions"
|
|
52
|
+
>
|
|
53
|
+
Terms & Conditions
|
|
54
|
+
</a>
|
|
55
|
+
.
|
|
56
|
+
</span>
|
|
57
|
+
</li>
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const corpSignupTerms = (
|
|
61
|
+
<>
|
|
62
|
+
<li>
|
|
63
|
+
<span className="terms-corp-signup">
|
|
64
|
+
Your organisation’s administrator(s) may view basic usage and profile
|
|
65
|
+
data about your account and have the ability to set up myFT topic
|
|
66
|
+
follows on your behalf.
|
|
67
|
+
</span>
|
|
68
|
+
</li>
|
|
69
|
+
<li>
|
|
70
|
+
<span className="terms-corp-signup">
|
|
71
|
+
Basic usage and profile data about your account can include; for
|
|
72
|
+
example, your job title and profile information, the date you last
|
|
73
|
+
visited, volume of content consumed, etc.
|
|
74
|
+
</span>
|
|
75
|
+
</li>
|
|
76
|
+
<li>
|
|
77
|
+
<span className="terms-corp-signup">
|
|
78
|
+
myFT topics may be selected on your behalf by your company
|
|
79
|
+
administrator or FT representative for you to follow. You can unfollow
|
|
80
|
+
these topics or unsubscribe from the myFT digest through the Contact
|
|
81
|
+
preferences section on myFT.
|
|
82
|
+
</span>
|
|
83
|
+
</li>
|
|
84
|
+
{isTrial && (
|
|
85
|
+
<li>
|
|
86
|
+
<span className="terms-corp-signup">
|
|
87
|
+
This trial is to demonstrate the value of a group subscription and
|
|
88
|
+
we’ll contact you during your trial.
|
|
89
|
+
</span>
|
|
90
|
+
</li>
|
|
91
|
+
)}
|
|
92
|
+
</>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div {...divProps}>
|
|
97
|
+
<ul className="o-typography-list ncf__accept-terms-list">
|
|
98
|
+
{b2bTerms}
|
|
99
|
+
{corpSignupTerms}
|
|
100
|
+
</ul>
|
|
101
|
+
|
|
102
|
+
<label className={labelClassName} htmlFor="termsAcceptance">
|
|
103
|
+
<input {...inputProps} />
|
|
104
|
+
<span className="o-forms-input__label">
|
|
105
|
+
I agree to the above terms & conditions.
|
|
106
|
+
</span>
|
|
107
|
+
<p className="o-forms-input__error">
|
|
108
|
+
Please accept our terms & conditions
|
|
109
|
+
</p>
|
|
110
|
+
</label>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
AcceptTermsBusiness.propTypes = {
|
|
116
|
+
hasError: PropTypes.bool,
|
|
117
|
+
isChecked: PropTypes.bool,
|
|
118
|
+
isB2b: PropTypes.bool,
|
|
119
|
+
isEmbedded: PropTypes.bool,
|
|
120
|
+
isTrial: PropTypes.bool,
|
|
121
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
import { AcceptTermsBusiness } from './index';
|
|
4
|
+
|
|
5
|
+
describe('AcceptTermsPrivacyPolicy', () => {
|
|
6
|
+
it('renders with "o-forms-input--invalid" class when hasError prop is true', () => {
|
|
7
|
+
const props = { hasError: true };
|
|
8
|
+
|
|
9
|
+
const component = mount(<AcceptTermsBusiness {...props} />);
|
|
10
|
+
|
|
11
|
+
const labelElement = component.find('label');
|
|
12
|
+
expect(labelElement.hasClass('o-forms-input--invalid')).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders the B2B terms when isB2b prop is true', () => {
|
|
16
|
+
const props = {
|
|
17
|
+
isB2b: true,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const component = mount(<AcceptTermsBusiness {...props} />);
|
|
21
|
+
|
|
22
|
+
const b2bTerms = component.find('.terms-b2b');
|
|
23
|
+
expect(b2bTerms.exists()).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('renders the external link with target="_blank" when isEmbedded prop is false', () => {
|
|
27
|
+
const props = {
|
|
28
|
+
isEmbedded: false,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const component = mount(<AcceptTermsBusiness {...props} />);
|
|
32
|
+
|
|
33
|
+
const externalLink = component.find('.ncf__link--external');
|
|
34
|
+
expect(externalLink.prop('target')).toBe('_blank');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('renders the trial terms when isTrial prop is true', () => {
|
|
38
|
+
const props = {
|
|
39
|
+
isTrial: true,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const component = mount(<AcceptTermsBusiness {...props} />);
|
|
43
|
+
|
|
44
|
+
const trialTerms = component.find('.terms-corp-signup');
|
|
45
|
+
expect(trialTerms.exists()).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AcceptTermsBusiness } from './accept-terms-business';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Accept Terms Business',
|
|
6
|
+
component: AcceptTermsBusiness,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Basic = (args) => <AcceptTermsBusiness {...args} />;
|
|
10
|
+
Basic.args = {};
|
|
11
|
+
|
|
12
|
+
export const AcceptTermsBusinessB2b = (args) => (
|
|
13
|
+
<AcceptTermsBusiness {...args} />
|
|
14
|
+
);
|
|
15
|
+
AcceptTermsBusinessB2b.args = {
|
|
16
|
+
isB2b: true,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const AcceptTermsBusinessTrial = (args) => (
|
|
20
|
+
<AcceptTermsBusiness {...args} />
|
|
21
|
+
);
|
|
22
|
+
AcceptTermsBusinessTrial.args = {
|
|
23
|
+
isTrial: true,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const AcceptTermsBusinessTrialAndB2b = (args) => (
|
|
27
|
+
<AcceptTermsBusiness {...args} />
|
|
28
|
+
);
|
|
29
|
+
AcceptTermsBusinessTrialAndB2b.args = {
|
|
30
|
+
isTrial: true,
|
|
31
|
+
isB2b: true,
|
|
32
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
|
|
5
|
+
export function AcceptTermsPrivacyPolicy({
|
|
6
|
+
hasError = false,
|
|
7
|
+
isEmbedded = false,
|
|
8
|
+
children,
|
|
9
|
+
}) {
|
|
10
|
+
const divProps = {
|
|
11
|
+
id: 'acceptTermsField',
|
|
12
|
+
className: 'o-forms-field o-layout-typography ncf__validation-error',
|
|
13
|
+
'data-validate': 'required,checked',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const labelClassName = classNames([
|
|
17
|
+
'o-forms-input',
|
|
18
|
+
'o-forms-input--checkbox',
|
|
19
|
+
{
|
|
20
|
+
'o-forms-input--invalid': hasError,
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
const inputProps = {
|
|
24
|
+
id: 'termsAcceptance',
|
|
25
|
+
type: 'checkbox',
|
|
26
|
+
name: 'termsAcceptance',
|
|
27
|
+
value: 'true',
|
|
28
|
+
'data-trackable': 'field-terms',
|
|
29
|
+
'aria-required': 'true',
|
|
30
|
+
required: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div {...divProps}>
|
|
35
|
+
<div className="privacy-policy-terms">
|
|
36
|
+
<label className={labelClassName} htmlFor="termsAcceptance">
|
|
37
|
+
<input {...inputProps} />
|
|
38
|
+
<span className="o-forms-input__label">
|
|
39
|
+
I confirm that I am 16 years or older and agree to the full{' '}
|
|
40
|
+
<a
|
|
41
|
+
className="ncf__link--external"
|
|
42
|
+
href="http://help.ft.com/help/legal-privacy/terms-conditions/"
|
|
43
|
+
target={isEmbedded ? '_top' : '_blank'}
|
|
44
|
+
rel="noopener noreferrer"
|
|
45
|
+
data-trackable="terms-and-conditions"
|
|
46
|
+
>
|
|
47
|
+
Terms & Conditions
|
|
48
|
+
</a>
|
|
49
|
+
.
|
|
50
|
+
</span>
|
|
51
|
+
<p className="o-forms-input__error">
|
|
52
|
+
Please accept our terms & conditions
|
|
53
|
+
</p>
|
|
54
|
+
</label>
|
|
55
|
+
|
|
56
|
+
{children && <div className="children-container">{children}</div>}
|
|
57
|
+
|
|
58
|
+
<span className={`consent-text--bottom`}>
|
|
59
|
+
For more information about how we use your data, please refer to our{' '}
|
|
60
|
+
<a
|
|
61
|
+
className="ncf__link--external"
|
|
62
|
+
href="https://help.ft.com/legal-privacy/privacy-policy/"
|
|
63
|
+
target="_blank"
|
|
64
|
+
rel="noopener noreferrer"
|
|
65
|
+
data-trackable="privacy-policy-info"
|
|
66
|
+
>
|
|
67
|
+
privacy
|
|
68
|
+
</a>{' '}
|
|
69
|
+
and
|
|
70
|
+
<a
|
|
71
|
+
className="ncf__link--external"
|
|
72
|
+
href="https://help.ft.com/legal-privacy/cookies/"
|
|
73
|
+
target="_blank"
|
|
74
|
+
rel="noopener noreferrer"
|
|
75
|
+
data-trackable="cookies-info"
|
|
76
|
+
>
|
|
77
|
+
cookie
|
|
78
|
+
</a>{' '}
|
|
79
|
+
policies.
|
|
80
|
+
</span>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
AcceptTermsPrivacyPolicy.propTypes = {
|
|
87
|
+
hasError: PropTypes.bool,
|
|
88
|
+
isEmbedded: PropTypes.bool,
|
|
89
|
+
children: PropTypes.oneOfType([
|
|
90
|
+
PropTypes.arrayOf(PropTypes.node),
|
|
91
|
+
PropTypes.node,
|
|
92
|
+
]),
|
|
93
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
import { AcceptTermsPrivacyPolicy } from './index';
|
|
4
|
+
|
|
5
|
+
describe('AcceptTermsPrivacyPolicy', () => {
|
|
6
|
+
it('renders with "o-forms-input--invalid" class when hasError prop is true', () => {
|
|
7
|
+
const props = { hasError: true };
|
|
8
|
+
|
|
9
|
+
const component = mount(<AcceptTermsPrivacyPolicy {...props} />);
|
|
10
|
+
|
|
11
|
+
const labelElement = component.find('label');
|
|
12
|
+
expect(labelElement.hasClass('o-forms-input--invalid')).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders the external link with target="_top" when isEmbedded prop is true', () => {
|
|
16
|
+
const props = {
|
|
17
|
+
isEmbedded: true,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const component = mount(<AcceptTermsPrivacyPolicy {...props} />);
|
|
21
|
+
|
|
22
|
+
const externalLink = component.find('.ncf__link--external').first();
|
|
23
|
+
expect(externalLink.prop('target')).toBe('_top');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('renders children when children prop is provided', () => {
|
|
27
|
+
const props = {
|
|
28
|
+
children: <div className="child-component">Child Component</div>,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const component = mount(<AcceptTermsPrivacyPolicy {...props} />);
|
|
32
|
+
|
|
33
|
+
const childElement = component.find('.child-component');
|
|
34
|
+
expect(childElement.exists()).toBe(true);
|
|
35
|
+
expect(childElement.text()).toBe('Child Component');
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AcceptTermsPrivacyPolicy } from './accept-terms-privacy-policy';
|
|
3
|
+
import { Submit } from './submit';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Accept Terms Privacy Policy',
|
|
7
|
+
component: AcceptTermsPrivacyPolicy,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const Basic = (args) => <AcceptTermsPrivacyPolicy {...args} />;
|
|
11
|
+
Basic.args = {};
|
|
12
|
+
|
|
13
|
+
export const AcceptTermsError = (args) => (
|
|
14
|
+
<AcceptTermsPrivacyPolicy {...args} />
|
|
15
|
+
);
|
|
16
|
+
AcceptTermsError.args = {
|
|
17
|
+
hasError: true,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const AcceptTermsWithChildren = (args) => (
|
|
21
|
+
<AcceptTermsPrivacyPolicy {...args}>
|
|
22
|
+
<Submit />
|
|
23
|
+
</AcceptTermsPrivacyPolicy>
|
|
24
|
+
);
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
|
|
5
|
+
export function AcceptTermsSubscription({
|
|
6
|
+
hasError = false,
|
|
7
|
+
isSignup = false,
|
|
8
|
+
isEmbedded = false,
|
|
9
|
+
isTrial = false,
|
|
10
|
+
isPrintProduct = false,
|
|
11
|
+
isSingleTerm = false,
|
|
12
|
+
isTransition = false,
|
|
13
|
+
transitionType = null,
|
|
14
|
+
isDeferredBilling = false,
|
|
15
|
+
}) {
|
|
16
|
+
const divProps = {
|
|
17
|
+
id: 'acceptTermsField',
|
|
18
|
+
className: 'o-forms-field o-layout-typography ncf__validation-error',
|
|
19
|
+
'data-validate': 'required,checked',
|
|
20
|
+
...(isSignup && { 'data-trackable': 'sign-up-terms' }),
|
|
21
|
+
};
|
|
22
|
+
const labelClassName = classNames([
|
|
23
|
+
'o-forms-input',
|
|
24
|
+
'o-forms-input--checkbox',
|
|
25
|
+
{
|
|
26
|
+
'o-forms-input--invalid': hasError,
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
const inputProps = {
|
|
31
|
+
id: 'termsAcceptance',
|
|
32
|
+
type: 'checkbox',
|
|
33
|
+
name: 'termsAcceptance',
|
|
34
|
+
value: 'true',
|
|
35
|
+
'data-trackable': 'field-terms',
|
|
36
|
+
'aria-required': 'true',
|
|
37
|
+
required: true,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const transitionTerms = isTransition && (
|
|
41
|
+
<>
|
|
42
|
+
{!isSingleTerm && (
|
|
43
|
+
<li>
|
|
44
|
+
<span className="terms-transition">
|
|
45
|
+
I give consent for my chosen payment method to be charged
|
|
46
|
+
automatically at the end of each subscription term until I cancel it
|
|
47
|
+
by contacting{' '}
|
|
48
|
+
<a
|
|
49
|
+
className="ncf__link--external"
|
|
50
|
+
href="https://help.ft.com/help/contact-us/"
|
|
51
|
+
target="_blank"
|
|
52
|
+
rel="noopener noreferrer"
|
|
53
|
+
>
|
|
54
|
+
customer care through chat, phone or email
|
|
55
|
+
</a>
|
|
56
|
+
.
|
|
57
|
+
</span>
|
|
58
|
+
</li>
|
|
59
|
+
)}
|
|
60
|
+
{transitionType === 'immediate' ? (
|
|
61
|
+
<li>
|
|
62
|
+
<span className="terms-transition terms-transition--immediate">
|
|
63
|
+
By placing my order, my subscription will start immediately and I am
|
|
64
|
+
aware and agree that I will therefore lose my statutory right to
|
|
65
|
+
cancel my subscription within 14 days of acceptance of my order. Any
|
|
66
|
+
notice of cancellation that I provide will only take effect at the
|
|
67
|
+
end of my subscription period and previously paid amounts are
|
|
68
|
+
non-refundable, except in the event that there is a fault in the
|
|
69
|
+
provision of the services.
|
|
70
|
+
</span>
|
|
71
|
+
</li>
|
|
72
|
+
) : (
|
|
73
|
+
<li>
|
|
74
|
+
<span className="terms-transition terms-transition--other">
|
|
75
|
+
By placing my order, I acknowledge that my subscription will start
|
|
76
|
+
{isSingleTerm
|
|
77
|
+
? ' and the chosen payment method will be charged '
|
|
78
|
+
: ' '}
|
|
79
|
+
on the date given above. Any cancellation notice received after that
|
|
80
|
+
date will take effect at the end of my subscription term and
|
|
81
|
+
previously paid amounts are non-refundable.
|
|
82
|
+
</span>
|
|
83
|
+
</li>
|
|
84
|
+
)}
|
|
85
|
+
<li>
|
|
86
|
+
<span className="terms-transition">
|
|
87
|
+
Find out more about our cancellation policy in our{' '}
|
|
88
|
+
<a
|
|
89
|
+
className="ncf__link--external"
|
|
90
|
+
href="http://help.ft.com/help/legal-privacy/terms-conditions/"
|
|
91
|
+
target="_blank"
|
|
92
|
+
rel="noopener noreferrer"
|
|
93
|
+
>
|
|
94
|
+
Terms & Conditions
|
|
95
|
+
</a>
|
|
96
|
+
.
|
|
97
|
+
</span>
|
|
98
|
+
</li>
|
|
99
|
+
</>
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const deferredBillingTerms = isDeferredBilling && (
|
|
103
|
+
<li>
|
|
104
|
+
<span className="terms-deferred">
|
|
105
|
+
Please note if you fail to make payment for your deferred billing plan
|
|
106
|
+
within due date your subscription will be automatically cancelled.
|
|
107
|
+
</span>
|
|
108
|
+
</li>
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const printSignupTermText = isTrial
|
|
112
|
+
? 'Credits for delivery suspension or delivery failure are not available during introductory offer periods.'
|
|
113
|
+
: 'Credit for delivery suspensions is only available for hand-delivered subscriptions and is limited to a maximum of 24 issues per yearly subscription terms (4 issues per yearly FT Weekend subscription term).';
|
|
114
|
+
|
|
115
|
+
const printTerms = (
|
|
116
|
+
<>
|
|
117
|
+
<li>
|
|
118
|
+
<span className="terms-print">{printSignupTermText}</span>
|
|
119
|
+
</li>
|
|
120
|
+
<li>
|
|
121
|
+
<span className="terms-print">
|
|
122
|
+
Find out more about your delivery start date in our{' '}
|
|
123
|
+
<a
|
|
124
|
+
className="ncf__link--external"
|
|
125
|
+
href="http://help.ft.com/help/legal-privacy/terms-conditions/"
|
|
126
|
+
target={isEmbedded ? '_top' : '_blank'}
|
|
127
|
+
rel="noopener noreferrer"
|
|
128
|
+
>
|
|
129
|
+
Terms & Conditions
|
|
130
|
+
</a>
|
|
131
|
+
.
|
|
132
|
+
</span>
|
|
133
|
+
</li>
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const nonPrintTerms = (
|
|
138
|
+
<>
|
|
139
|
+
<li>
|
|
140
|
+
<span className="terms-signup">
|
|
141
|
+
I give consent for my chosen payment method to be charged
|
|
142
|
+
automatically at the end of each subscription term until I cancel it
|
|
143
|
+
by contacting{' '}
|
|
144
|
+
<a
|
|
145
|
+
className="ncf__link--external"
|
|
146
|
+
href="https://help.ft.com/help/contact-us/"
|
|
147
|
+
target={isEmbedded ? '_top' : '_blank'}
|
|
148
|
+
rel="noopener noreferrer"
|
|
149
|
+
>
|
|
150
|
+
customer care through chat, phone or email
|
|
151
|
+
</a>
|
|
152
|
+
.
|
|
153
|
+
</span>
|
|
154
|
+
</li>
|
|
155
|
+
<li>
|
|
156
|
+
<span className="terms-signup">
|
|
157
|
+
By placing my order, my subscription will start immediately and I am
|
|
158
|
+
aware and agree that I will therefore lose my statutory right to
|
|
159
|
+
cancel my subscription within 14 days of acceptance of my order. Any
|
|
160
|
+
notice of cancellation that I provide will only take effect at the end
|
|
161
|
+
of my subscription period and previously paid amounts are
|
|
162
|
+
non-refundable, except in the event that there is a fault in the
|
|
163
|
+
provision of the services.
|
|
164
|
+
</span>
|
|
165
|
+
</li>
|
|
166
|
+
<li>
|
|
167
|
+
<span className="terms-signup">
|
|
168
|
+
Find out more about our cancellation policy in our{' '}
|
|
169
|
+
<a
|
|
170
|
+
className="ncf__link--external"
|
|
171
|
+
href="https://help.ft.com/legal-privacy/terms-and-conditions/"
|
|
172
|
+
target={isEmbedded ? '_top' : '_blank'}
|
|
173
|
+
rel="noopener noreferrer"
|
|
174
|
+
>
|
|
175
|
+
Terms & Conditions
|
|
176
|
+
</a>
|
|
177
|
+
.
|
|
178
|
+
</span>
|
|
179
|
+
</li>
|
|
180
|
+
</>
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const signupTerms = <>{isPrintProduct ? printTerms : nonPrintTerms}</>;
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<div {...divProps}>
|
|
187
|
+
<ul className="o-typography-list ncf__accept-terms-list">
|
|
188
|
+
{transitionTerms}
|
|
189
|
+
{signupTerms}
|
|
190
|
+
{deferredBillingTerms}
|
|
191
|
+
</ul>
|
|
192
|
+
<label className={labelClassName} htmlFor="termsAcceptance">
|
|
193
|
+
<input {...inputProps} />
|
|
194
|
+
<span className="o-forms-input__label">
|
|
195
|
+
I agree to the above terms & conditions.
|
|
196
|
+
</span>
|
|
197
|
+
<p className="o-forms-input__error">
|
|
198
|
+
Please accept our terms & conditions
|
|
199
|
+
</p>
|
|
200
|
+
</label>
|
|
201
|
+
</div>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
AcceptTermsSubscription.propTypes = {
|
|
206
|
+
hasError: PropTypes.bool,
|
|
207
|
+
isSignup: PropTypes.bool,
|
|
208
|
+
isEmbedded: PropTypes.bool,
|
|
209
|
+
isTrial: PropTypes.bool,
|
|
210
|
+
isPrintProduct: PropTypes.bool,
|
|
211
|
+
isSingleTerm: PropTypes.bool,
|
|
212
|
+
isTransition: PropTypes.bool,
|
|
213
|
+
transitionType: PropTypes.string,
|
|
214
|
+
isDeferredBilling: PropTypes.bool,
|
|
215
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
import { AcceptTermsSubscription } from './index';
|
|
4
|
+
|
|
5
|
+
describe('AcceptTermsSubscription', () => {
|
|
6
|
+
it('renders with "o-forms-input--invalid" class when hasError prop is true', () => {
|
|
7
|
+
const props = { hasError: true };
|
|
8
|
+
|
|
9
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
10
|
+
|
|
11
|
+
const labelElement = component.find('label');
|
|
12
|
+
expect(labelElement.hasClass('o-forms-input--invalid')).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('renders without data-trackable attribute when isSignup prop is false', () => {
|
|
16
|
+
const props = {
|
|
17
|
+
isSignup: false,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
21
|
+
|
|
22
|
+
const labelElement = component.find(
|
|
23
|
+
'label[data-trackable="sign-up-terms"]'
|
|
24
|
+
);
|
|
25
|
+
expect(labelElement.exists()).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('renders the external link with target="_top" when isEmbedded prop is true', () => {
|
|
29
|
+
const props = {
|
|
30
|
+
isEmbedded: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
34
|
+
|
|
35
|
+
const externalLink = component.find('.ncf__link--external').first();
|
|
36
|
+
expect(externalLink.prop('target')).toBe('_top');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('does not render the trial-specific terms when isTrial prop is false', () => {
|
|
40
|
+
const props = {
|
|
41
|
+
isTrial: false,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
45
|
+
|
|
46
|
+
const trialTerms = component.find('.terms-print');
|
|
47
|
+
expect(trialTerms.exists()).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('renders the print-specific terms when isPrintProduct prop is true', () => {
|
|
51
|
+
const props = {
|
|
52
|
+
isPrintProduct: true,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
56
|
+
|
|
57
|
+
const printTerms = component.find('.terms-print');
|
|
58
|
+
expect(printTerms.exists()).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('renders the transition terms when isSingleTerm prop is true and isTransition prop is true', () => {
|
|
62
|
+
const props = {
|
|
63
|
+
isSingleTerm: true,
|
|
64
|
+
isTransition: true,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
68
|
+
|
|
69
|
+
const transitionTerms = component.find('.terms-transition');
|
|
70
|
+
expect(transitionTerms.exists()).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('does not render the transition terms when transitionType prop is null', () => {
|
|
74
|
+
const props = {
|
|
75
|
+
transitionType: null,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
79
|
+
|
|
80
|
+
const transitionTerms = component.find('.terms-transition');
|
|
81
|
+
expect(transitionTerms.exists()).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('renders the deferred billing terms when isDeferredBilling prop is true', () => {
|
|
85
|
+
const props = {
|
|
86
|
+
isDeferredBilling: true,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const component = mount(<AcceptTermsSubscription {...props} />);
|
|
90
|
+
|
|
91
|
+
const deferredBillingTerms = component.find('.terms-deferred');
|
|
92
|
+
expect(deferredBillingTerms.exists()).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AcceptTermsSubscription } from './accept-terms-subscription';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Accept Terms Subscription',
|
|
6
|
+
component: AcceptTermsSubscription,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Basic = (args) => <AcceptTermsSubscription {...args} />;
|
|
10
|
+
Basic.args = {};
|
|
11
|
+
|
|
12
|
+
export const PrintProduct = (args) => <AcceptTermsSubscription {...args} />;
|
|
13
|
+
|
|
14
|
+
PrintProduct.args = {
|
|
15
|
+
isPrintProduct: true,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const PrintProductTrial = (args) => (
|
|
19
|
+
<AcceptTermsSubscription {...args} />
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
PrintProductTrial.args = {
|
|
23
|
+
isPrintProduct: true,
|
|
24
|
+
isTrial: true,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const isSingleTerm = (args) => <AcceptTermsSubscription {...args} />;
|
|
28
|
+
|
|
29
|
+
isSingleTerm.args = {
|
|
30
|
+
isSingleTerm: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const isTransition = (args) => <AcceptTermsSubscription {...args} />;
|
|
34
|
+
|
|
35
|
+
isTransition.args = {
|
|
36
|
+
isTransition: true,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const transitionType = (args) => <AcceptTermsSubscription {...args} />;
|
|
40
|
+
|
|
41
|
+
transitionType.args = {
|
|
42
|
+
transitionType: true,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const isDeferredBilling = (args) => (
|
|
46
|
+
<AcceptTermsSubscription {...args} />
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
isDeferredBilling.args = {
|
|
50
|
+
isDeferredBilling: true,
|
|
51
|
+
};
|
package/components/index.jsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { AcceptTerms } from './accept-terms';
|
|
2
|
+
export { AcceptTermsPrivacyPolicy } from './accept-terms-privacy-policy';
|
|
3
|
+
export { AcceptTermsSubscription } from './accept-terms-subscription';
|
|
4
|
+
export { AcceptTermsBusiness } from './accept-terms-business';
|
|
2
5
|
export { AppBanner } from './app-banner';
|
|
3
6
|
export { BillingCity } from './billing-city';
|
|
4
7
|
export { BillingCountry } from './billing-country';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.AcceptTermsBusiness = AcceptTermsBusiness;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
|
+
function AcceptTermsBusiness(_ref) {
|
|
12
|
+
var _ref$hasError = _ref.hasError,
|
|
13
|
+
hasError = _ref$hasError === void 0 ? false : _ref$hasError,
|
|
14
|
+
_ref$isB2b = _ref.isB2b,
|
|
15
|
+
isB2b = _ref$isB2b === void 0 ? false : _ref$isB2b,
|
|
16
|
+
_ref$isEmbedded = _ref.isEmbedded,
|
|
17
|
+
isEmbedded = _ref$isEmbedded === void 0 ? false : _ref$isEmbedded,
|
|
18
|
+
_ref$isTrial = _ref.isTrial,
|
|
19
|
+
isTrial = _ref$isTrial === void 0 ? false : _ref$isTrial;
|
|
20
|
+
var divProps = {
|
|
21
|
+
id: 'acceptTermsField',
|
|
22
|
+
className: 'o-forms-field o-layout-typography ncf__validation-error',
|
|
23
|
+
'data-validate': 'required,checked'
|
|
24
|
+
};
|
|
25
|
+
var labelClassName = (0, _classnames["default"])(['o-forms-input', 'o-forms-input--checkbox', {
|
|
26
|
+
'o-forms-input--invalid': hasError
|
|
27
|
+
}]);
|
|
28
|
+
var inputProps = {
|
|
29
|
+
id: 'termsAcceptance',
|
|
30
|
+
type: 'checkbox',
|
|
31
|
+
name: 'termsAcceptance',
|
|
32
|
+
value: 'true',
|
|
33
|
+
'data-trackable': 'field-terms',
|
|
34
|
+
'aria-required': 'true',
|
|
35
|
+
required: true
|
|
36
|
+
};
|
|
37
|
+
var b2bTerms = isB2b ? /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
38
|
+
className: "terms-b2b"
|
|
39
|
+
}, "By submitting this form, you indicate your consent to also being contacted by Financial Times by email, post, or phone about our other products, services or special offers unless you untick this box.")) : /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
40
|
+
className: "terms-default"
|
|
41
|
+
}, "I confirm I am 16 years or older and have read and agree to the", ' ', /*#__PURE__*/_react["default"].createElement("a", {
|
|
42
|
+
className: "ncf__link--external",
|
|
43
|
+
href: "http://help.ft.com/help/legal-privacy/terms-conditions/",
|
|
44
|
+
target: isEmbedded ? '_top' : '_blank',
|
|
45
|
+
rel: "noopener noreferrer",
|
|
46
|
+
"data-trackable": "terms-and-conditions"
|
|
47
|
+
}, "Terms & Conditions"), "."));
|
|
48
|
+
var corpSignupTerms = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
49
|
+
className: "terms-corp-signup"
|
|
50
|
+
}, "Your organisation\u2019s administrator(s) may view basic usage and profile data about your account and have the ability to set up myFT topic follows on your behalf.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
51
|
+
className: "terms-corp-signup"
|
|
52
|
+
}, "Basic usage and profile data about your account can include; for example, your job title and profile information, the date you last visited, volume of content consumed, etc.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
53
|
+
className: "terms-corp-signup"
|
|
54
|
+
}, "myFT topics may be selected on your behalf by your company administrator or FT representative for you to follow. You can unfollow these topics or unsubscribe from the myFT digest through the Contact preferences section on myFT.")), isTrial && /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
55
|
+
className: "terms-corp-signup"
|
|
56
|
+
}, "This trial is to demonstrate the value of a group subscription and we\u2019ll contact you during your trial.")));
|
|
57
|
+
return /*#__PURE__*/_react["default"].createElement("div", divProps, /*#__PURE__*/_react["default"].createElement("ul", {
|
|
58
|
+
className: "o-typography-list ncf__accept-terms-list"
|
|
59
|
+
}, b2bTerms, corpSignupTerms), /*#__PURE__*/_react["default"].createElement("label", {
|
|
60
|
+
className: labelClassName,
|
|
61
|
+
htmlFor: "termsAcceptance"
|
|
62
|
+
}, /*#__PURE__*/_react["default"].createElement("input", inputProps), /*#__PURE__*/_react["default"].createElement("span", {
|
|
63
|
+
className: "o-forms-input__label"
|
|
64
|
+
}, "I agree to the above terms & conditions."), /*#__PURE__*/_react["default"].createElement("p", {
|
|
65
|
+
className: "o-forms-input__error"
|
|
66
|
+
}, "Please accept our terms & conditions")));
|
|
67
|
+
}
|
|
68
|
+
AcceptTermsBusiness.propTypes = {
|
|
69
|
+
hasError: _propTypes["default"].bool,
|
|
70
|
+
isChecked: _propTypes["default"].bool,
|
|
71
|
+
isB2b: _propTypes["default"].bool,
|
|
72
|
+
isEmbedded: _propTypes["default"].bool,
|
|
73
|
+
isTrial: _propTypes["default"].bool
|
|
74
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _react = _interopRequireDefault(require("react"));
|
|
5
|
+
var _enzyme = require("enzyme");
|
|
6
|
+
var _index = require("./index");
|
|
7
|
+
describe('AcceptTermsPrivacyPolicy', function () {
|
|
8
|
+
it('renders with "o-forms-input--invalid" class when hasError prop is true', function () {
|
|
9
|
+
var props = {
|
|
10
|
+
hasError: true
|
|
11
|
+
};
|
|
12
|
+
var component = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_index.AcceptTermsBusiness, props));
|
|
13
|
+
var labelElement = component.find('label');
|
|
14
|
+
expect(labelElement.hasClass('o-forms-input--invalid')).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it('renders the B2B terms when isB2b prop is true', function () {
|
|
17
|
+
var props = {
|
|
18
|
+
isB2b: true
|
|
19
|
+
};
|
|
20
|
+
var component = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_index.AcceptTermsBusiness, props));
|
|
21
|
+
var b2bTerms = component.find('.terms-b2b');
|
|
22
|
+
expect(b2bTerms.exists()).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
it('renders the external link with target="_blank" when isEmbedded prop is false', function () {
|
|
25
|
+
var props = {
|
|
26
|
+
isEmbedded: false
|
|
27
|
+
};
|
|
28
|
+
var component = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_index.AcceptTermsBusiness, props));
|
|
29
|
+
var externalLink = component.find('.ncf__link--external');
|
|
30
|
+
expect(externalLink.prop('target')).toBe('_blank');
|
|
31
|
+
});
|
|
32
|
+
it('renders the trial terms when isTrial prop is true', function () {
|
|
33
|
+
var props = {
|
|
34
|
+
isTrial: true
|
|
35
|
+
};
|
|
36
|
+
var component = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_index.AcceptTermsBusiness, props));
|
|
37
|
+
var trialTerms = component.find('.terms-corp-signup');
|
|
38
|
+
expect(trialTerms.exists()).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.AcceptTermsPrivacyPolicy = AcceptTermsPrivacyPolicy;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
|
+
function AcceptTermsPrivacyPolicy(_ref) {
|
|
12
|
+
var _ref$hasError = _ref.hasError,
|
|
13
|
+
hasError = _ref$hasError === void 0 ? false : _ref$hasError,
|
|
14
|
+
_ref$isEmbedded = _ref.isEmbedded,
|
|
15
|
+
isEmbedded = _ref$isEmbedded === void 0 ? false : _ref$isEmbedded,
|
|
16
|
+
children = _ref.children;
|
|
17
|
+
var divProps = {
|
|
18
|
+
id: 'acceptTermsField',
|
|
19
|
+
className: 'o-forms-field o-layout-typography ncf__validation-error',
|
|
20
|
+
'data-validate': 'required,checked'
|
|
21
|
+
};
|
|
22
|
+
var labelClassName = (0, _classnames["default"])(['o-forms-input', 'o-forms-input--checkbox', {
|
|
23
|
+
'o-forms-input--invalid': hasError
|
|
24
|
+
}]);
|
|
25
|
+
var inputProps = {
|
|
26
|
+
id: 'termsAcceptance',
|
|
27
|
+
type: 'checkbox',
|
|
28
|
+
name: 'termsAcceptance',
|
|
29
|
+
value: 'true',
|
|
30
|
+
'data-trackable': 'field-terms',
|
|
31
|
+
'aria-required': 'true',
|
|
32
|
+
required: true
|
|
33
|
+
};
|
|
34
|
+
return /*#__PURE__*/_react["default"].createElement("div", divProps, /*#__PURE__*/_react["default"].createElement("div", {
|
|
35
|
+
className: "privacy-policy-terms"
|
|
36
|
+
}, /*#__PURE__*/_react["default"].createElement("label", {
|
|
37
|
+
className: labelClassName,
|
|
38
|
+
htmlFor: "termsAcceptance"
|
|
39
|
+
}, /*#__PURE__*/_react["default"].createElement("input", inputProps), /*#__PURE__*/_react["default"].createElement("span", {
|
|
40
|
+
className: "o-forms-input__label"
|
|
41
|
+
}, "I confirm that I am 16 years or older and agree to the full", ' ', /*#__PURE__*/_react["default"].createElement("a", {
|
|
42
|
+
className: "ncf__link--external",
|
|
43
|
+
href: "http://help.ft.com/help/legal-privacy/terms-conditions/",
|
|
44
|
+
target: isEmbedded ? '_top' : '_blank',
|
|
45
|
+
rel: "noopener noreferrer",
|
|
46
|
+
"data-trackable": "terms-and-conditions"
|
|
47
|
+
}, "Terms & Conditions"), "."), /*#__PURE__*/_react["default"].createElement("p", {
|
|
48
|
+
className: "o-forms-input__error"
|
|
49
|
+
}, "Please accept our terms & conditions")), children && /*#__PURE__*/_react["default"].createElement("div", {
|
|
50
|
+
className: "children-container"
|
|
51
|
+
}, children), /*#__PURE__*/_react["default"].createElement("span", {
|
|
52
|
+
className: "consent-text--bottom"
|
|
53
|
+
}, "For more information about how we use your data, please refer to our", ' ', /*#__PURE__*/_react["default"].createElement("a", {
|
|
54
|
+
className: "ncf__link--external",
|
|
55
|
+
href: "https://help.ft.com/legal-privacy/privacy-policy/",
|
|
56
|
+
target: "_blank",
|
|
57
|
+
rel: "noopener noreferrer",
|
|
58
|
+
"data-trackable": "privacy-policy-info"
|
|
59
|
+
}, "privacy"), ' ', "and\xA0", /*#__PURE__*/_react["default"].createElement("a", {
|
|
60
|
+
className: "ncf__link--external",
|
|
61
|
+
href: "https://help.ft.com/legal-privacy/cookies/",
|
|
62
|
+
target: "_blank",
|
|
63
|
+
rel: "noopener noreferrer",
|
|
64
|
+
"data-trackable": "cookies-info"
|
|
65
|
+
}, "cookie"), ' ', "policies.")));
|
|
66
|
+
}
|
|
67
|
+
AcceptTermsPrivacyPolicy.propTypes = {
|
|
68
|
+
hasError: _propTypes["default"].bool,
|
|
69
|
+
isEmbedded: _propTypes["default"].bool,
|
|
70
|
+
children: _propTypes["default"].oneOfType([_propTypes["default"].arrayOf(_propTypes["default"].node), _propTypes["default"].node])
|
|
71
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.AcceptTermsSubscription = AcceptTermsSubscription;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _react = _interopRequireDefault(require("react"));
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
12
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
13
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
14
|
+
function AcceptTermsSubscription(_ref) {
|
|
15
|
+
var _ref$hasError = _ref.hasError,
|
|
16
|
+
hasError = _ref$hasError === void 0 ? false : _ref$hasError,
|
|
17
|
+
_ref$isSignup = _ref.isSignup,
|
|
18
|
+
isSignup = _ref$isSignup === void 0 ? false : _ref$isSignup,
|
|
19
|
+
_ref$isEmbedded = _ref.isEmbedded,
|
|
20
|
+
isEmbedded = _ref$isEmbedded === void 0 ? false : _ref$isEmbedded,
|
|
21
|
+
_ref$isTrial = _ref.isTrial,
|
|
22
|
+
isTrial = _ref$isTrial === void 0 ? false : _ref$isTrial,
|
|
23
|
+
_ref$isPrintProduct = _ref.isPrintProduct,
|
|
24
|
+
isPrintProduct = _ref$isPrintProduct === void 0 ? false : _ref$isPrintProduct,
|
|
25
|
+
_ref$isSingleTerm = _ref.isSingleTerm,
|
|
26
|
+
isSingleTerm = _ref$isSingleTerm === void 0 ? false : _ref$isSingleTerm,
|
|
27
|
+
_ref$isTransition = _ref.isTransition,
|
|
28
|
+
isTransition = _ref$isTransition === void 0 ? false : _ref$isTransition,
|
|
29
|
+
_ref$transitionType = _ref.transitionType,
|
|
30
|
+
transitionType = _ref$transitionType === void 0 ? null : _ref$transitionType,
|
|
31
|
+
_ref$isDeferredBillin = _ref.isDeferredBilling,
|
|
32
|
+
isDeferredBilling = _ref$isDeferredBillin === void 0 ? false : _ref$isDeferredBillin;
|
|
33
|
+
var divProps = _objectSpread({
|
|
34
|
+
id: 'acceptTermsField',
|
|
35
|
+
className: 'o-forms-field o-layout-typography ncf__validation-error',
|
|
36
|
+
'data-validate': 'required,checked'
|
|
37
|
+
}, isSignup && {
|
|
38
|
+
'data-trackable': 'sign-up-terms'
|
|
39
|
+
});
|
|
40
|
+
var labelClassName = (0, _classnames["default"])(['o-forms-input', 'o-forms-input--checkbox', {
|
|
41
|
+
'o-forms-input--invalid': hasError
|
|
42
|
+
}]);
|
|
43
|
+
var inputProps = {
|
|
44
|
+
id: 'termsAcceptance',
|
|
45
|
+
type: 'checkbox',
|
|
46
|
+
name: 'termsAcceptance',
|
|
47
|
+
value: 'true',
|
|
48
|
+
'data-trackable': 'field-terms',
|
|
49
|
+
'aria-required': 'true',
|
|
50
|
+
required: true
|
|
51
|
+
};
|
|
52
|
+
var transitionTerms = isTransition && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, !isSingleTerm && /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
53
|
+
className: "terms-transition"
|
|
54
|
+
}, "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", {
|
|
55
|
+
className: "ncf__link--external",
|
|
56
|
+
href: "https://help.ft.com/help/contact-us/",
|
|
57
|
+
target: "_blank",
|
|
58
|
+
rel: "noopener noreferrer"
|
|
59
|
+
}, "customer care through chat, phone or email"), ".")), transitionType === 'immediate' ? /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
60
|
+
className: "terms-transition terms-transition--immediate"
|
|
61
|
+
}, "By placing my order, my subscription will start immediately and I am aware and agree that I will therefore lose my statutory right to cancel my subscription within 14 days of acceptance of my order. Any notice of cancellation that I provide will only take effect at the end of my subscription period and previously paid amounts are non-refundable, except in the event that there is a fault in the provision of the services.")) : /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
62
|
+
className: "terms-transition terms-transition--other"
|
|
63
|
+
}, "By placing my order, I acknowledge that my subscription will start", isSingleTerm ? ' and the chosen payment method will be charged ' : ' ', "on the date given above. Any cancellation notice received after that date will take effect at the end of my subscription term and previously paid amounts are non-refundable.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
64
|
+
className: "terms-transition"
|
|
65
|
+
}, "Find out more about our cancellation policy in our", ' ', /*#__PURE__*/_react["default"].createElement("a", {
|
|
66
|
+
className: "ncf__link--external",
|
|
67
|
+
href: "http://help.ft.com/help/legal-privacy/terms-conditions/",
|
|
68
|
+
target: "_blank",
|
|
69
|
+
rel: "noopener noreferrer"
|
|
70
|
+
}, "Terms & Conditions"), ".")));
|
|
71
|
+
var deferredBillingTerms = isDeferredBilling && /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
72
|
+
className: "terms-deferred"
|
|
73
|
+
}, "Please note if you fail to make payment for your deferred billing plan within due date your subscription will be automatically cancelled."));
|
|
74
|
+
var printSignupTermText = isTrial ? 'Credits for delivery suspension or delivery failure are not available during introductory offer periods.' : 'Credit for delivery suspensions is only available for hand-delivered subscriptions and is limited to a maximum of 24 issues per yearly subscription terms (4 issues per yearly FT Weekend subscription term).';
|
|
75
|
+
var printTerms = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
76
|
+
className: "terms-print"
|
|
77
|
+
}, printSignupTermText)), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
78
|
+
className: "terms-print"
|
|
79
|
+
}, "Find out more about your delivery start date in our", ' ', /*#__PURE__*/_react["default"].createElement("a", {
|
|
80
|
+
className: "ncf__link--external",
|
|
81
|
+
href: "http://help.ft.com/help/legal-privacy/terms-conditions/",
|
|
82
|
+
target: isEmbedded ? '_top' : '_blank',
|
|
83
|
+
rel: "noopener noreferrer"
|
|
84
|
+
}, "Terms & Conditions"), ".")));
|
|
85
|
+
var nonPrintTerms = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
86
|
+
className: "terms-signup"
|
|
87
|
+
}, "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", {
|
|
88
|
+
className: "ncf__link--external",
|
|
89
|
+
href: "https://help.ft.com/help/contact-us/",
|
|
90
|
+
target: isEmbedded ? '_top' : '_blank',
|
|
91
|
+
rel: "noopener noreferrer"
|
|
92
|
+
}, "customer care through chat, phone or email"), ".")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
93
|
+
className: "terms-signup"
|
|
94
|
+
}, "By placing my order, my subscription will start immediately and I am aware and agree that I will therefore lose my statutory right to cancel my subscription within 14 days of acceptance of my order. Any notice of cancellation that I provide will only take effect at the end of my subscription period and previously paid amounts are non-refundable, except in the event that there is a fault in the provision of the services.")), /*#__PURE__*/_react["default"].createElement("li", null, /*#__PURE__*/_react["default"].createElement("span", {
|
|
95
|
+
className: "terms-signup"
|
|
96
|
+
}, "Find out more about our cancellation policy in our", ' ', /*#__PURE__*/_react["default"].createElement("a", {
|
|
97
|
+
className: "ncf__link--external",
|
|
98
|
+
href: "https://help.ft.com/legal-privacy/terms-and-conditions/",
|
|
99
|
+
target: isEmbedded ? '_top' : '_blank',
|
|
100
|
+
rel: "noopener noreferrer"
|
|
101
|
+
}, "Terms & Conditions"), ".")));
|
|
102
|
+
var signupTerms = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, isPrintProduct ? printTerms : nonPrintTerms);
|
|
103
|
+
return /*#__PURE__*/_react["default"].createElement("div", divProps, /*#__PURE__*/_react["default"].createElement("ul", {
|
|
104
|
+
className: "o-typography-list ncf__accept-terms-list"
|
|
105
|
+
}, transitionTerms, signupTerms, deferredBillingTerms), /*#__PURE__*/_react["default"].createElement("label", {
|
|
106
|
+
className: labelClassName,
|
|
107
|
+
htmlFor: "termsAcceptance"
|
|
108
|
+
}, /*#__PURE__*/_react["default"].createElement("input", inputProps), /*#__PURE__*/_react["default"].createElement("span", {
|
|
109
|
+
className: "o-forms-input__label"
|
|
110
|
+
}, "I agree to the above terms & conditions."), /*#__PURE__*/_react["default"].createElement("p", {
|
|
111
|
+
className: "o-forms-input__error"
|
|
112
|
+
}, "Please accept our terms & conditions")));
|
|
113
|
+
}
|
|
114
|
+
AcceptTermsSubscription.propTypes = {
|
|
115
|
+
hasError: _propTypes["default"].bool,
|
|
116
|
+
isSignup: _propTypes["default"].bool,
|
|
117
|
+
isEmbedded: _propTypes["default"].bool,
|
|
118
|
+
isTrial: _propTypes["default"].bool,
|
|
119
|
+
isPrintProduct: _propTypes["default"].bool,
|
|
120
|
+
isSingleTerm: _propTypes["default"].bool,
|
|
121
|
+
isTransition: _propTypes["default"].bool,
|
|
122
|
+
transitionType: _propTypes["default"].string,
|
|
123
|
+
isDeferredBilling: _propTypes["default"].bool
|
|
124
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,24 @@ Object.defineProperty(exports, "AcceptTerms", {
|
|
|
9
9
|
return _acceptTerms.AcceptTerms;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "AcceptTermsBusiness", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _acceptTermsBusiness.AcceptTermsBusiness;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "AcceptTermsPrivacyPolicy", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _acceptTermsPrivacyPolicy.AcceptTermsPrivacyPolicy;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "AcceptTermsSubscription", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function get() {
|
|
27
|
+
return _acceptTermsSubscription.AcceptTermsSubscription;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
12
30
|
Object.defineProperty(exports, "AppBanner", {
|
|
13
31
|
enumerable: true,
|
|
14
32
|
get: function get() {
|
|
@@ -346,6 +364,9 @@ Object.defineProperty(exports, "TrialBanner", {
|
|
|
346
364
|
}
|
|
347
365
|
});
|
|
348
366
|
var _acceptTerms = require("./accept-terms");
|
|
367
|
+
var _acceptTermsPrivacyPolicy = require("./accept-terms-privacy-policy");
|
|
368
|
+
var _acceptTermsSubscription = require("./accept-terms-subscription");
|
|
369
|
+
var _acceptTermsBusiness = require("./accept-terms-business");
|
|
349
370
|
var _appBanner = require("./app-banner");
|
|
350
371
|
var _billingCity = require("./billing-city");
|
|
351
372
|
var _billingCountry = require("./billing-country");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@financial-times/n-conversion-forms",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "29.0.0",
|
|
4
4
|
"description": "Containing jsx components and styles for forms included on Accounts and Acqusition apps (next-signup, next-profile, next-retention, etc).",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|