gatsby-core-theme 1.3.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.js +2 -3
- package/.storybook/preview.js +1 -4
- package/CHANGELOG.md +94 -0
- package/gatsby-node.esm.js +59 -19
- package/jest.config.js +1 -0
- package/package.json +1 -1
- package/src/components/app.js +12 -7
- package/src/components/atoms/archive/items/index.js +1 -1
- package/src/components/atoms/author/index.js +3 -2
- package/src/components/atoms/author-box/author-box.test.js +1 -5
- package/src/components/atoms/author-box/index.js +42 -13
- package/src/components/atoms/breadcrumbs/index.js +8 -4
- package/src/components/atoms/button/button.test.js +7 -0
- package/src/components/atoms/button/index.js +10 -3
- package/src/components/atoms/carousel/arrow/index.js +3 -2
- package/src/components/atoms/carousel/pagination-item/index.js +3 -2
- package/src/components/atoms/collapse/index.js +3 -1
- package/src/components/atoms/custom-select/index.js +2 -1
- package/src/components/atoms/logo/index.js +2 -2
- package/src/components/atoms/menu/items/index.js +6 -0
- package/src/components/atoms/menu/items/item/index.js +5 -4
- package/src/components/atoms/menu/menu-icon/index.js +4 -4
- package/src/components/atoms/module-title/index.js +2 -1
- package/src/components/atoms/not-found/index.js +14 -0
- package/src/components/atoms/not-found/not-found.module.scss +16 -0
- package/src/components/atoms/open-graph/index.js +5 -5
- package/src/components/atoms/operator-cta/index.js +15 -5
- package/src/components/atoms/operator-cta/{operator-cta.test.disabled.js → operator-cta.test.js} +12 -1
- package/src/components/atoms/operator-info-block/index.js +8 -1
- package/src/components/atoms/search/autocomplete/operator.js +1 -1
- package/src/components/atoms/spotlights/index.js +15 -4
- package/src/components/molecules/carousel/default-slide/index.js +4 -0
- package/src/components/molecules/counter/index.js +2 -2
- package/src/components/molecules/footer/index.js +6 -2
- package/src/components/molecules/header/header.test.js +0 -1
- package/src/components/molecules/link-list/index.js +9 -1
- package/src/components/molecules/main/index.js +3 -1
- package/src/components/molecules/menu/index.js +5 -1
- package/src/components/molecules/operator-banner/index.js +17 -7
- package/src/components/molecules/operator-banner/operator-banner.test.js +1 -1
- package/src/components/molecules/pagination/index.js +16 -5
- package/src/components/molecules/pagination/pagination.test.js +3 -3
- package/src/components/molecules/pagination/with-midpoints.js +41 -17
- package/src/components/molecules/pagination/with-midpoints.test.js +7 -8
- package/src/components/molecules/search/index.js +14 -3
- package/src/components/molecules/slider/index.js +27 -3
- package/src/components/molecules/toplist/default-row/index.js +27 -4
- package/src/components/organisms/accordion/accordion.test.js +3 -3
- package/src/components/organisms/accordion/index.js +1 -1
- package/src/components/organisms/anchor/index.js +2 -1
- package/src/components/organisms/archive/archive.test.js +8 -1
- package/src/components/organisms/archive/index.js +12 -12
- package/src/components/organisms/cards/cards.stories.js +1 -0
- package/src/components/organisms/cards/index.js +1 -1
- package/src/components/organisms/carousel/index.js +16 -17
- package/src/components/organisms/cookie-consent/cookie-consent.stories.js +6 -1
- package/src/components/organisms/cookie-consent/index.js +2 -0
- package/src/components/organisms/form/index.js +1 -0
- package/src/components/organisms/navigation/index.js +4 -4
- package/src/components/organisms/search/index.js +1 -1
- package/src/components/organisms/toplist/index.js +15 -19
- package/src/components/organisms/toplist/list/index.js +22 -29
- package/src/components/pages/body/index.js +9 -5
- package/src/components/pages/search/index.js +36 -1
- package/src/components/pages/tracker/index.js +8 -4
- package/src/constants/pick-keys.js +2 -0
- package/src/context/TranslationsProvider.js +9 -0
- package/src/helpers/processor/index.js +20 -3
- package/src/helpers/processor/processor.test.js +14 -0
- package/src/hooks/lazy-image/lazy-image.stories.js +1 -0
- package/src/hooks/link/index.js +2 -0
- package/src/hooks/link/link.test.js +9 -0
- package/src/hooks/modal/modal-content.js +7 -3
- package/src/hooks/modal/modal.test.js +3 -2
- package/src/hooks/tabs/index.js +4 -1
- package/src/hooks/tabs/tab/tab-list.js +4 -1
- package/src/hooks/tabs/tab/tab.js +11 -2
- package/src/pages/sitemap/index.js +77 -0
- package/src/pages/sitemap/sitemap.module.scss +21 -0
- package/tests/factories/relations/operator.factory.js +33 -0
|
@@ -30,7 +30,7 @@ const CustomSelect = ({
|
|
|
30
30
|
<div className={styles.customSelectContainer}>
|
|
31
31
|
<button
|
|
32
32
|
ref={defBtn}
|
|
33
|
-
className={styles.select}
|
|
33
|
+
className={`${styles.select} custom-select-gtm btn-cta`}
|
|
34
34
|
type="button"
|
|
35
35
|
onClick={showDropdown}
|
|
36
36
|
data-id="select-button"
|
|
@@ -56,6 +56,7 @@ const CustomSelect = ({
|
|
|
56
56
|
>
|
|
57
57
|
<button
|
|
58
58
|
type="button"
|
|
59
|
+
className="custom-select-gtm btn-cta"
|
|
59
60
|
onClick={() => {
|
|
60
61
|
onClick(currentItem[itemsValue], currentItem[itemsLabel], currentItem.type);
|
|
61
62
|
setSelectedOption(currentItem);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { prettyTracker,imagePrettyUrl } from '~helpers/getters';
|
|
3
|
+
import { prettyTracker, imagePrettyUrl } from '~helpers/getters';
|
|
4
4
|
import LazyImage from '~hooks/lazy-image';
|
|
5
5
|
|
|
6
6
|
import styles from './logo.module.scss';
|
|
@@ -11,7 +11,7 @@ const Logo = ({ item = {} }) => {
|
|
|
11
11
|
return (
|
|
12
12
|
<div>
|
|
13
13
|
<a
|
|
14
|
-
className={styles.operatorLogo}
|
|
14
|
+
className={`${styles.operatorLogo} logo-cta`}
|
|
15
15
|
href={prettyLink}
|
|
16
16
|
title={item.name}
|
|
17
17
|
target="_blank"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable arrow-body-style */
|
|
1
2
|
import React, { useRef } from 'react';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import Item from './item';
|
|
@@ -14,6 +15,7 @@ const Items = ({
|
|
|
14
15
|
subMenuDropDownButton: true,
|
|
15
16
|
},
|
|
16
17
|
},
|
|
18
|
+
gtmClass = '',
|
|
17
19
|
}) => {
|
|
18
20
|
let link;
|
|
19
21
|
let menu;
|
|
@@ -46,6 +48,7 @@ const Items = ({
|
|
|
46
48
|
hasChildren
|
|
47
49
|
item={item}
|
|
48
50
|
showSubMenuHandler={showSubMenu}
|
|
51
|
+
gtmClass={gtmClass}
|
|
49
52
|
options={{
|
|
50
53
|
mobile: {
|
|
51
54
|
subMenuDropDownButton: options.mobile.subMenuDropDownButton,
|
|
@@ -61,6 +64,7 @@ const Items = ({
|
|
|
61
64
|
key={keygen()}
|
|
62
65
|
item={child}
|
|
63
66
|
menuListRef={menuListRef}
|
|
67
|
+
gtmClass={gtmClass}
|
|
64
68
|
options={{
|
|
65
69
|
mobile: {
|
|
66
70
|
canOpenAllSubMenus: options.mobile.canOpenAllSubMenus,
|
|
@@ -77,6 +81,7 @@ const Items = ({
|
|
|
77
81
|
<Item
|
|
78
82
|
hasChildren={false}
|
|
79
83
|
item={item}
|
|
84
|
+
gtmClass={gtmClass}
|
|
80
85
|
options={{ mobile: { subMenuDropDownButton: options.mobile.subMenuDropDownButton } }}
|
|
81
86
|
/>
|
|
82
87
|
);
|
|
@@ -108,6 +113,7 @@ Items.propTypes = {
|
|
|
108
113
|
subMenuDropDownButton: PropTypes.bool,
|
|
109
114
|
}),
|
|
110
115
|
}),
|
|
116
|
+
gtmClass: PropTypes.string,
|
|
111
117
|
};
|
|
112
118
|
|
|
113
119
|
export default Items;
|
|
@@ -6,8 +6,6 @@ import ConditionalWrapper from '~atoms/conditional-wrapper';
|
|
|
6
6
|
|
|
7
7
|
import styles from './item.module.scss';
|
|
8
8
|
|
|
9
|
-
/* eslint-disable react/jsx-no-target-blank */
|
|
10
|
-
|
|
11
9
|
export default function Item({
|
|
12
10
|
item,
|
|
13
11
|
hasChildren,
|
|
@@ -17,6 +15,7 @@ export default function Item({
|
|
|
17
15
|
subMenuDropDownButton: true,
|
|
18
16
|
},
|
|
19
17
|
},
|
|
18
|
+
gtmClass = '',
|
|
20
19
|
}) {
|
|
21
20
|
const [active, setActive] = useState('');
|
|
22
21
|
useEffect(() => {
|
|
@@ -51,7 +50,7 @@ export default function Item({
|
|
|
51
50
|
title={item.title}
|
|
52
51
|
rel={`noreferrer ${item.nofollow && 'nofollow'}`}
|
|
53
52
|
target="_blank"
|
|
54
|
-
className={`${styles.item} ${active} ${
|
|
53
|
+
className={`${gtmClass} ${styles.item} ${active} ${
|
|
55
54
|
!options.mobile.subMenuDropDownButton && isMobile && hasChildren
|
|
56
55
|
? styles.inactiveLink
|
|
57
56
|
: ''
|
|
@@ -63,7 +62,7 @@ export default function Item({
|
|
|
63
62
|
</a>
|
|
64
63
|
) : (
|
|
65
64
|
<Link
|
|
66
|
-
className={`${styles.item} ${active} ${
|
|
65
|
+
className={`${gtmClass} ${styles.item} ${active} ${
|
|
67
66
|
!options.mobile.subMenuDropDownButton && isMobile && hasChildren
|
|
68
67
|
? styles.inactiveLink
|
|
69
68
|
: ''
|
|
@@ -80,6 +79,7 @@ export default function Item({
|
|
|
80
79
|
{options.mobile.subMenuDropDownButton && isMobile && hasChildren && (
|
|
81
80
|
<button
|
|
82
81
|
type="button"
|
|
82
|
+
className={`${gtmClass} btn-cta`}
|
|
83
83
|
onClick={(e) => {
|
|
84
84
|
showSubMenuHandler(styles);
|
|
85
85
|
toggleDropDown(e);
|
|
@@ -111,4 +111,5 @@ Item.propTypes = {
|
|
|
111
111
|
subMenuDropDownButton: PropTypes.bool,
|
|
112
112
|
}),
|
|
113
113
|
}),
|
|
114
|
+
gtmClass: PropTypes.string,
|
|
114
115
|
};
|
|
@@ -3,13 +3,12 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { NavigationContext } from '~organisms/navigation/navigationContext';
|
|
4
4
|
import styles from './menu-icon.module.scss';
|
|
5
5
|
|
|
6
|
-
const MenuIcon = ({ onClick }) => {
|
|
7
|
-
|
|
6
|
+
const MenuIcon = ({ onClick, gtmClass }) => {
|
|
8
7
|
const { showMenu } = useContext(NavigationContext);
|
|
9
8
|
|
|
10
9
|
return (
|
|
11
10
|
<div
|
|
12
|
-
className={styles.menuIconContainer}
|
|
11
|
+
className={`${styles.menuIconContainer} ${gtmClass}`}
|
|
13
12
|
onKeyDown={() => onClick()}
|
|
14
13
|
onClick={() => onClick()}
|
|
15
14
|
role="button"
|
|
@@ -24,7 +23,8 @@ const MenuIcon = ({ onClick }) => {
|
|
|
24
23
|
};
|
|
25
24
|
|
|
26
25
|
MenuIcon.propTypes = {
|
|
27
|
-
onClick: PropTypes.func.isRequired
|
|
26
|
+
onClick: PropTypes.func.isRequired,
|
|
27
|
+
gtmClass: PropTypes.string,
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export default MenuIcon;
|
|
@@ -36,7 +36,7 @@ const ModuleTitle = ({ module, viewMoreIcon = <FaAngleRight />, pageContext = nu
|
|
|
36
36
|
>
|
|
37
37
|
{module.module_title && getTitle(module)}
|
|
38
38
|
{module.link_label && (
|
|
39
|
-
<Link to={module.link_value} className={styles.viewMore}>
|
|
39
|
+
<Link to={module.link_value} className={`${styles.viewMore} module-title-gtm`}>
|
|
40
40
|
{module.link_label}
|
|
41
41
|
{viewMoreIcon}
|
|
42
42
|
</Link>
|
|
@@ -57,6 +57,7 @@ ModuleTitle.propTypes = {
|
|
|
57
57
|
style: PropTypes.string,
|
|
58
58
|
}),
|
|
59
59
|
viewMoreIcon: PropTypes.element,
|
|
60
|
+
pageContext: PropTypes.shape({}),
|
|
60
61
|
};
|
|
61
62
|
|
|
62
63
|
export default ModuleTitle;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* eslint-disable react/no-unescaped-entities */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import styles from './not-found.module.scss';
|
|
4
|
+
|
|
5
|
+
const NotFound = () => (
|
|
6
|
+
<div className={styles.wrapper}>
|
|
7
|
+
<div className={styles.textBlock}>
|
|
8
|
+
<p>Oops! We can't seem to find that page anymore.</p>
|
|
9
|
+
<p>While you're here though, why not check out these top South African Casinos:</p>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export default NotFound;
|
|
@@ -28,7 +28,7 @@ const OpenGraph = ({ page, text = 'Share: ' }) => {
|
|
|
28
28
|
rel="noreferrer"
|
|
29
29
|
href={fbURL}
|
|
30
30
|
role="button"
|
|
31
|
-
className={styles.btn}
|
|
31
|
+
className={`${styles.btn} open-graph-gtm`}
|
|
32
32
|
onClick={(e) => share(e, 555, 602)}
|
|
33
33
|
>
|
|
34
34
|
<FaFacebookF />
|
|
@@ -38,7 +38,7 @@ const OpenGraph = ({ page, text = 'Share: ' }) => {
|
|
|
38
38
|
rel="noreferrer"
|
|
39
39
|
href={twitterURL}
|
|
40
40
|
role="button"
|
|
41
|
-
className={styles.btn}
|
|
41
|
+
className={`${styles.btn} open-graph-gtm`}
|
|
42
42
|
onClick={(e) => share(e, 555, 255)}
|
|
43
43
|
>
|
|
44
44
|
<FaTwitter />
|
|
@@ -50,9 +50,9 @@ const OpenGraph = ({ page, text = 'Share: ' }) => {
|
|
|
50
50
|
OpenGraph.propTypes = {
|
|
51
51
|
page: PropTypes.shape({
|
|
52
52
|
title: PropTypes.string,
|
|
53
|
-
path: PropTypes.string
|
|
53
|
+
path: PropTypes.string,
|
|
54
54
|
}).isRequired,
|
|
55
|
-
text: PropTypes.string
|
|
56
|
-
}
|
|
55
|
+
text: PropTypes.string,
|
|
56
|
+
};
|
|
57
57
|
|
|
58
58
|
export default OpenGraph;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useContext } from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
|
|
5
5
|
import Button from '~atoms/button';
|
|
6
6
|
import { prettyTracker, translate } from '~helpers/getters';
|
|
7
|
+
import { Context } from '~context/TranslationsProvider';
|
|
7
8
|
import styles from './operator-cta.module.scss';
|
|
8
9
|
|
|
9
10
|
export default function OperatorCta({
|
|
@@ -12,8 +13,9 @@ export default function OperatorCta({
|
|
|
12
13
|
closedCasinoText = 'This Casino has closed',
|
|
13
14
|
playText = 'Visit',
|
|
14
15
|
tracker = 'main',
|
|
15
|
-
|
|
16
|
+
gtmClass = '',
|
|
16
17
|
}) {
|
|
18
|
+
const { translations } = useContext(Context) || {};
|
|
17
19
|
const status = operator?.status;
|
|
18
20
|
const isPlaceHolder = status === 'coming_soon';
|
|
19
21
|
const isClosed = status === 'inactive';
|
|
@@ -23,7 +25,7 @@ export default function OperatorCta({
|
|
|
23
25
|
<a
|
|
24
26
|
title={placeholderText}
|
|
25
27
|
aria-label={placeholderText}
|
|
26
|
-
className={styles.operatorCtaPlaceholder}
|
|
28
|
+
className={`${styles.operatorCtaPlaceholder} ${gtmClass} operator-cta-gtm`}
|
|
27
29
|
>
|
|
28
30
|
{placeholderText}
|
|
29
31
|
</a>
|
|
@@ -35,7 +37,7 @@ export default function OperatorCta({
|
|
|
35
37
|
<a
|
|
36
38
|
title={closedCasinoText}
|
|
37
39
|
aria-label={closedCasinoText}
|
|
38
|
-
className={styles.operatorCtaClosed}
|
|
40
|
+
className={`${styles.operatorCtaClosed} ${gtmClass} operator-cta-gtm`}
|
|
39
41
|
>
|
|
40
42
|
{closedCasinoText}
|
|
41
43
|
</a>
|
|
@@ -45,7 +47,14 @@ export default function OperatorCta({
|
|
|
45
47
|
const trackerType = tracker.toLowerCase().replace(' ', '_');
|
|
46
48
|
const prettyLink = prettyTracker(operator, trackerType);
|
|
47
49
|
const translateBtn = translate(translations, 'play_now', playText);
|
|
48
|
-
return
|
|
50
|
+
return (
|
|
51
|
+
<Button
|
|
52
|
+
to={prettyLink}
|
|
53
|
+
btnText={translateBtn}
|
|
54
|
+
isInternalLink={false}
|
|
55
|
+
gtmClass={`${gtmClass} operator-cta-gtm btn-cta`}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
49
58
|
};
|
|
50
59
|
|
|
51
60
|
return renderCta();
|
|
@@ -59,4 +68,5 @@ OperatorCta.propTypes = {
|
|
|
59
68
|
placeholderText: PropTypes.string,
|
|
60
69
|
playText: PropTypes.string,
|
|
61
70
|
closedCasinoText: PropTypes.string,
|
|
71
|
+
gtmClass: PropTypes.string,
|
|
62
72
|
};
|
package/src/components/atoms/operator-cta/{operator-cta.test.disabled.js → operator-cta.test.js}
RENAMED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, cleanup } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
|
+
import getPageData from '~tests/factories/pages/default.factory';
|
|
4
5
|
|
|
5
6
|
import OperatorCta from '.';
|
|
6
7
|
|
|
7
8
|
describe('OperatorCta Component', () => {
|
|
8
|
-
// Commented until we get the operator status data done on hercules
|
|
9
|
+
// Commented until we get the operator status data done on hercules
|
|
9
10
|
// test('test placeholder', () => {
|
|
10
11
|
// const { getByText } = render(<OperatorCta placeholderText="test" />);
|
|
11
12
|
// expect(getByText('test')).toBeTruthy();
|
|
@@ -22,6 +23,16 @@ describe('OperatorCta Component', () => {
|
|
|
22
23
|
// const { container } = render(<OperatorCta playText={'test3'} />);
|
|
23
24
|
// expect(getByText('test3')).toBeTruthy();
|
|
24
25
|
// });
|
|
26
|
+
|
|
27
|
+
test('test GTM class', () => {
|
|
28
|
+
const data = getPageData();
|
|
29
|
+
const { getByText } = render(
|
|
30
|
+
<OperatorCta playText="test3" gtmClass="operator-cta-gtm btn-cta" operator={data} />
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
expect(getByText('test3').closest('a').classList.contains('operator-cta-gtm')).toBe(true);
|
|
34
|
+
expect(getByText('test3').closest('a').classList.contains('btn-cta')).toBe(true);
|
|
35
|
+
});
|
|
25
36
|
});
|
|
26
37
|
afterEach(() => {
|
|
27
38
|
cleanup();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable arrow-body-style */
|
|
1
2
|
/* eslint-disable no-nested-ternary */
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import PropTypes from 'prop-types';
|
|
@@ -28,7 +29,12 @@ const OperatorInfoBlock = ({ page }) => {
|
|
|
28
29
|
<p className={styles.label}>{item.field_label}</p>
|
|
29
30
|
<div className={styles.value}>
|
|
30
31
|
{item.field_name === 'url' ? (
|
|
31
|
-
<a
|
|
32
|
+
<a
|
|
33
|
+
href={prettyLink}
|
|
34
|
+
target="_blank"
|
|
35
|
+
className="operator-info-block-gtm"
|
|
36
|
+
rel="noindex nofollow noreferrer"
|
|
37
|
+
>
|
|
32
38
|
{relation[item.field_name]}
|
|
33
39
|
</a>
|
|
34
40
|
) : item.field_name === 'support_types' ? (
|
|
@@ -60,6 +66,7 @@ const OperatorInfoBlock = ({ page }) => {
|
|
|
60
66
|
};
|
|
61
67
|
|
|
62
68
|
OperatorInfoBlock.propTypes = {
|
|
69
|
+
// eslint-disable-next-line react/no-unused-prop-types
|
|
63
70
|
activeOperator: PropTypes.bool,
|
|
64
71
|
page: PropTypes.shape({
|
|
65
72
|
relation: PropTypes.shape({
|
|
@@ -10,7 +10,7 @@ const Operator = ({ item = {} }) => (
|
|
|
10
10
|
<div className={styles.row}>
|
|
11
11
|
<LazyImage src={imagePrettyUrl(item.relation.logo_url, null, 20)} />
|
|
12
12
|
<h3>{item.title}</h3>
|
|
13
|
-
<Button to="/#" primaryColor isInternalLink={false} />
|
|
13
|
+
<Button to="/#" primaryColor isInternalLink={false} gtmClass="operator-gtm btn-cta" />
|
|
14
14
|
</div>
|
|
15
15
|
);
|
|
16
16
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable react/no-danger */
|
|
1
2
|
/* eslint-disable camelcase */
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import PropTypes from 'prop-types';
|
|
@@ -36,11 +37,17 @@ const Spotlights = ({ module }) => {
|
|
|
36
37
|
{items.map((item) => (
|
|
37
38
|
<li key={keygen()} className={styles.spotlightItem}>
|
|
38
39
|
{item.link.type === 'external' ? (
|
|
39
|
-
<a
|
|
40
|
+
<a
|
|
41
|
+
href={item.link.value}
|
|
42
|
+
className="spotlights-gtm"
|
|
43
|
+
title={item.label}
|
|
44
|
+
target="_blank"
|
|
45
|
+
rel="noreferrer"
|
|
46
|
+
>
|
|
40
47
|
{content(item)}
|
|
41
48
|
</a>
|
|
42
49
|
) : (
|
|
43
|
-
<Link to={item.link.value} title={item.label}>
|
|
50
|
+
<Link to={item.link.value} title={item.label} className="spotlights-gtm">
|
|
44
51
|
{content(item)}
|
|
45
52
|
</Link>
|
|
46
53
|
)}
|
|
@@ -54,7 +61,7 @@ const Spotlights = ({ module }) => {
|
|
|
54
61
|
title={item.label}
|
|
55
62
|
target="_blank"
|
|
56
63
|
rel="noreferrer"
|
|
57
|
-
className={styles.readMore}
|
|
64
|
+
className={`${styles.readMore} spotlights-gtm`}
|
|
58
65
|
>
|
|
59
66
|
{item.link_text ? item.link_text : 'Read More'}
|
|
60
67
|
<GrFormNextLink />
|
|
@@ -62,7 +69,11 @@ const Spotlights = ({ module }) => {
|
|
|
62
69
|
) : (
|
|
63
70
|
<>
|
|
64
71
|
{item.link.value && (
|
|
65
|
-
<Link
|
|
72
|
+
<Link
|
|
73
|
+
to={item.link.value}
|
|
74
|
+
title={item.label}
|
|
75
|
+
className={`${styles.readMore} spotlights-gtm`}
|
|
76
|
+
>
|
|
66
77
|
{item.link_text ? item.link_text : 'Read More'}
|
|
67
78
|
<GrFormNextLink />
|
|
68
79
|
</Link>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable react/forbid-prop-types */
|
|
2
|
+
/* eslint-disable arrow-body-style */
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import PropTypes from 'prop-types';
|
|
3
5
|
|
|
@@ -30,6 +32,7 @@ const Slide = ({
|
|
|
30
32
|
btnText={primaryBtnText}
|
|
31
33
|
isInternalLink={false}
|
|
32
34
|
primaryColor
|
|
35
|
+
gtmClass="carousel-gtm btn-cta"
|
|
33
36
|
/>
|
|
34
37
|
)}
|
|
35
38
|
{item.secondary_action && (
|
|
@@ -39,6 +42,7 @@ const Slide = ({
|
|
|
39
42
|
btnText={secondaryBtnText}
|
|
40
43
|
isInternalLink={false}
|
|
41
44
|
primaryColor={false}
|
|
45
|
+
gtmClass="carousel-gtm btn-cta"
|
|
42
46
|
/>
|
|
43
47
|
)}
|
|
44
48
|
{item.label && <span className={styles.label}>{item.label}</span>}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/* eslint-disable react/no-danger */
|
|
2
|
+
/* eslint-disable arrow-body-style */
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import PropTypes from 'prop-types';
|
|
3
5
|
|
|
@@ -5,8 +7,6 @@ import CounterItem from './counter-item';
|
|
|
5
7
|
import styles from './counter.module.scss';
|
|
6
8
|
import keygen from '~helpers/keygen';
|
|
7
9
|
|
|
8
|
-
/* eslint-disable react/no-danger */
|
|
9
|
-
|
|
10
10
|
const Counter = ({ module }) => {
|
|
11
11
|
return (
|
|
12
12
|
<>
|
|
@@ -24,7 +24,10 @@ const Footer = ({
|
|
|
24
24
|
<div className={styles.topPart}>
|
|
25
25
|
<div className={styles.links}>
|
|
26
26
|
{footerMenu && showLinks && (
|
|
27
|
-
<LinkList
|
|
27
|
+
<LinkList
|
|
28
|
+
lists={getExtraField(section.extra_fields, footerMenu)}
|
|
29
|
+
gtmClass="mobile-menu-gtm"
|
|
30
|
+
/>
|
|
28
31
|
)}
|
|
29
32
|
</div>
|
|
30
33
|
|
|
@@ -34,7 +37,7 @@ const Footer = ({
|
|
|
34
37
|
<div className={styles.bottomPart}>
|
|
35
38
|
{footerBottomCustom && <BottomSection section={section} />}
|
|
36
39
|
<div className={styles.copyrightDisclaimer}>
|
|
37
|
-
{copyrightDisclaimer && getExtraField(section.extra_fields, copyrightDisclaimer) &&(
|
|
40
|
+
{copyrightDisclaimer && getExtraField(section.extra_fields, copyrightDisclaimer) && (
|
|
38
41
|
<p
|
|
39
42
|
dangerouslySetInnerHTML={{
|
|
40
43
|
__html: getExtraField(section.extra_fields, copyrightDisclaimer).replace(
|
|
@@ -53,6 +56,7 @@ const Footer = ({
|
|
|
53
56
|
imageOnly
|
|
54
57
|
singleList
|
|
55
58
|
lists={getExtraField(section.extra_fields, footerLogos)}
|
|
59
|
+
gtmClass="mobile-menu-gtm logo-cta"
|
|
56
60
|
/>
|
|
57
61
|
)}
|
|
58
62
|
</div>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, cleanup } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
|
-
|
|
5
4
|
import getHeaderSection from '~tests/factories/sections/header.factory';
|
|
6
5
|
import '~tests/helpers/match-media.mock';
|
|
7
6
|
import Header from '.';
|
|
@@ -21,6 +21,7 @@ const LinkList = ({
|
|
|
21
21
|
once = false,
|
|
22
22
|
height,
|
|
23
23
|
width,
|
|
24
|
+
gtmClass = '',
|
|
24
25
|
}) => {
|
|
25
26
|
function renderLinkContent(item, index) {
|
|
26
27
|
const icon = listIcon[index];
|
|
@@ -64,11 +65,17 @@ const LinkList = ({
|
|
|
64
65
|
title={item.title}
|
|
65
66
|
rel={`noreferrer ${item.nofollow && 'nofollow'}`}
|
|
66
67
|
target="_blank"
|
|
68
|
+
className={gtmClass}
|
|
67
69
|
>
|
|
68
70
|
{renderLinkContent(item, index)}
|
|
69
71
|
</a>
|
|
70
72
|
) : (
|
|
71
|
-
<Link
|
|
73
|
+
<Link
|
|
74
|
+
to={item.value}
|
|
75
|
+
title={item.title}
|
|
76
|
+
className={gtmClass}
|
|
77
|
+
rel={item.nofollow && 'nofollow'}
|
|
78
|
+
>
|
|
72
79
|
{renderLinkContent(item, index)}
|
|
73
80
|
</Link>
|
|
74
81
|
)
|
|
@@ -126,6 +133,7 @@ LinkList.propTypes = {
|
|
|
126
133
|
once: PropTypes.bool,
|
|
127
134
|
width: PropTypes.number,
|
|
128
135
|
height: PropTypes.number,
|
|
136
|
+
gtmClass: PropTypes.string,
|
|
129
137
|
};
|
|
130
138
|
|
|
131
139
|
export default LinkList;
|
|
@@ -8,14 +8,16 @@ import keygen from '~helpers/keygen';
|
|
|
8
8
|
const Main = ({ section = {}, page = {}, pageContext = {} }) => {
|
|
9
9
|
const SearchPage = page.path === 's' ? loadable(() => import(`~pages/search`)) : null;
|
|
10
10
|
const AuthorBox = page.author ? loadable(() => import(`~atoms/author-box`)) : null;
|
|
11
|
+
const NotFound = page?.path?.includes('404') ? loadable(() => import(`~atoms/not-found`)) : null;
|
|
11
12
|
|
|
12
13
|
return (
|
|
13
14
|
<main className={styles.modulePage}>
|
|
15
|
+
{NotFound && <NotFound />}
|
|
14
16
|
{section.modules &&
|
|
15
17
|
section.modules.map((module) => (
|
|
16
18
|
<Module key={keygen()} module={module} page={page} pageContext={pageContext} />
|
|
17
19
|
))}
|
|
18
|
-
{AuthorBox && <AuthorBox author={page.author}
|
|
20
|
+
{AuthorBox && <AuthorBox author={page.author} />}
|
|
19
21
|
{SearchPage && <SearchPage page={page} />}
|
|
20
22
|
</main>
|
|
21
23
|
);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable arrow-body-style */
|
|
1
2
|
import React, { useContext, useRef } from 'react';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
|
|
@@ -25,6 +26,7 @@ const Menu = ({
|
|
|
25
26
|
orientation: 'horizontal',
|
|
26
27
|
},
|
|
27
28
|
},
|
|
29
|
+
gtmClass = '',
|
|
28
30
|
}) => {
|
|
29
31
|
let menuObject;
|
|
30
32
|
|
|
@@ -59,13 +61,14 @@ const Menu = ({
|
|
|
59
61
|
|
|
60
62
|
return (
|
|
61
63
|
<div className={styles.menuContainer}>
|
|
62
|
-
<MenuIcon onClick={handleMenuIconClick} />
|
|
64
|
+
<MenuIcon onClick={handleMenuIconClick} gtmClass="main-menu-gtm" />
|
|
63
65
|
<ul ref={menuListRef} className={`${menuListClasses} ${showMenu && styles.show}`}>
|
|
64
66
|
{menuObject &&
|
|
65
67
|
menuObject.children.map((child) => {
|
|
66
68
|
return (
|
|
67
69
|
<Items
|
|
68
70
|
menuListRef={menuListRef}
|
|
71
|
+
gtmClass={gtmClass}
|
|
69
72
|
key={keygen()}
|
|
70
73
|
item={child}
|
|
71
74
|
options={{
|
|
@@ -109,6 +112,7 @@ Menu.propTypes = {
|
|
|
109
112
|
),
|
|
110
113
|
}).isRequired,
|
|
111
114
|
menu: PropTypes.string.isRequired,
|
|
115
|
+
gtmClass: PropTypes.string,
|
|
112
116
|
};
|
|
113
117
|
|
|
114
118
|
export default Menu;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
|
-
import { prettyTracker } from '~helpers/getters';
|
|
4
|
+
import { prettyTracker, imagePrettyUrl } from '~helpers/getters';
|
|
5
5
|
import LazyImage from '~hooks/lazy-image';
|
|
6
|
-
import { imagePrettyUrl } from '~helpers/getters';
|
|
7
6
|
import Bonus from '~atoms/bonus';
|
|
8
7
|
import StarRating from '~molecules/star-rating';
|
|
9
8
|
import OperatorCta from '~atoms/operator-cta';
|
|
@@ -28,7 +27,6 @@ export default function OperatorBanner({
|
|
|
28
27
|
const clickHandler = () => {
|
|
29
28
|
setShow(false);
|
|
30
29
|
};
|
|
31
|
-
|
|
32
30
|
|
|
33
31
|
return (
|
|
34
32
|
show && (
|
|
@@ -45,7 +43,7 @@ export default function OperatorBanner({
|
|
|
45
43
|
{logo ? (
|
|
46
44
|
<a
|
|
47
45
|
href={prettyLink}
|
|
48
|
-
className={styles.logo}
|
|
46
|
+
className={`${styles.logo} operator-banner-gtm logo-cta`}
|
|
49
47
|
title={operator?.name}
|
|
50
48
|
target="_blank"
|
|
51
49
|
rel="noreferrer"
|
|
@@ -55,7 +53,13 @@ export default function OperatorBanner({
|
|
|
55
53
|
) : (
|
|
56
54
|
<div>
|
|
57
55
|
<h3>
|
|
58
|
-
<a
|
|
56
|
+
<a
|
|
57
|
+
href={prettyLink}
|
|
58
|
+
title={operator?.name}
|
|
59
|
+
className="operator-banner-gtm name-cta"
|
|
60
|
+
target="_blank"
|
|
61
|
+
rel="noreferrer"
|
|
62
|
+
>
|
|
59
63
|
{operator?.name}
|
|
60
64
|
</a>
|
|
61
65
|
</h3>
|
|
@@ -63,7 +67,13 @@ export default function OperatorBanner({
|
|
|
63
67
|
<StarRating numOfStars={5} rating={operator.rating} />
|
|
64
68
|
)}
|
|
65
69
|
{isPlaceholder && hasLink && (
|
|
66
|
-
<a
|
|
70
|
+
<a
|
|
71
|
+
href={operator.url}
|
|
72
|
+
title={operator?.name}
|
|
73
|
+
className="operator-banner-gtm"
|
|
74
|
+
target="_blank"
|
|
75
|
+
rel="noreferrer"
|
|
76
|
+
>
|
|
67
77
|
{operator?.url?.replace(/^(?:https?:\/\/)?(?:www\.)?/i, '')}
|
|
68
78
|
</a>
|
|
69
79
|
)}
|
|
@@ -86,7 +96,7 @@ export default function OperatorBanner({
|
|
|
86
96
|
</div>
|
|
87
97
|
{sticky && (
|
|
88
98
|
<button
|
|
89
|
-
className={styles.closeBtn}
|
|
99
|
+
className={`${styles.closeBtn} operator-banner-gtm btn-cta`}
|
|
90
100
|
onClick={clickHandler}
|
|
91
101
|
aria-label="close"
|
|
92
102
|
type="button"
|
|
@@ -17,7 +17,7 @@ describe('OperatorBanner Component', () => {
|
|
|
17
17
|
expect(getByText('Visit')).toBeTruthy();
|
|
18
18
|
});
|
|
19
19
|
test('render component placeholder', () => {
|
|
20
|
-
|
|
20
|
+
const data = getPageData();
|
|
21
21
|
data.status = 'coming_soon';
|
|
22
22
|
const { container, getByText } = render(<OperatorBanner hasLink operator={data} />);
|
|
23
23
|
expect(container).toBeTruthy();
|