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
|
@@ -6,23 +6,21 @@ import Slide from '~molecules/carousel/default-slide';
|
|
|
6
6
|
import keygen from '~helpers/keygen';
|
|
7
7
|
import styles from './carousel.module.scss';
|
|
8
8
|
|
|
9
|
-
const Carousel = ({ module = {}, settings = {}, CustomSlideComponent }) =>
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
);
|
|
25
|
-
};
|
|
9
|
+
const Carousel = ({ module = {}, settings = {}, CustomSlideComponent, gtmClass = '' }) => (
|
|
10
|
+
<div className={styles.carouselContainer}>
|
|
11
|
+
<Slider {...settings} gtmClass={gtmClass}>
|
|
12
|
+
{module.items.map((item) => (
|
|
13
|
+
<div key={keygen()} className={styles.carouselItem}>
|
|
14
|
+
{CustomSlideComponent !== undefined ? (
|
|
15
|
+
<CustomSlideComponent item={item} gtmClass={gtmClass} />
|
|
16
|
+
) : (
|
|
17
|
+
<Slide item={item} gtmClass={gtmClass} />
|
|
18
|
+
)}
|
|
19
|
+
</div>
|
|
20
|
+
))}
|
|
21
|
+
</Slider>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
26
24
|
|
|
27
25
|
Carousel.propTypes = {
|
|
28
26
|
module: PropTypes.shape({
|
|
@@ -38,6 +36,7 @@ Carousel.propTypes = {
|
|
|
38
36
|
}),
|
|
39
37
|
settings: PropTypes.shape(PropTypes.object),
|
|
40
38
|
CustomSlideComponent: PropTypes.element,
|
|
39
|
+
gtmClass: PropTypes.string,
|
|
41
40
|
};
|
|
42
41
|
|
|
43
42
|
export default Carousel;
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Primary,
|
|
6
6
|
PRIMARY_STORY,
|
|
7
7
|
ArgsTable,
|
|
8
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
8
9
|
} from '@storybook/addon-docs/blocks';
|
|
9
10
|
|
|
10
11
|
import CookieConsent from '.';
|
|
@@ -96,7 +97,11 @@ const Template = (args) => (
|
|
|
96
97
|
<p>
|
|
97
98
|
We use cookies in order to optimise our site and improve your experience with us. By using
|
|
98
99
|
the site you consent to our
|
|
99
|
-
<a href="/cookies">
|
|
100
|
+
<a href="/cookies" className="cookie-consent-gtm">
|
|
101
|
+
{' '}
|
|
102
|
+
Cookie Policy
|
|
103
|
+
</a>
|
|
104
|
+
.
|
|
100
105
|
</p>
|
|
101
106
|
</CookieConsent>
|
|
102
107
|
</div>
|
|
@@ -42,6 +42,7 @@ const CookieConsent = ({
|
|
|
42
42
|
btnText={acceptText}
|
|
43
43
|
isInternalLink={false}
|
|
44
44
|
isButton
|
|
45
|
+
gtmClass="cookie-consent-gtm btn-cta"
|
|
45
46
|
/>
|
|
46
47
|
|
|
47
48
|
{declineText && (
|
|
@@ -50,6 +51,7 @@ const CookieConsent = ({
|
|
|
50
51
|
btnText={declineText}
|
|
51
52
|
isInternalLink={false}
|
|
52
53
|
isButton
|
|
54
|
+
gtmClass="cookie-consent-gtm btn-cta"
|
|
53
55
|
/>
|
|
54
56
|
)}
|
|
55
57
|
</Sticky>
|
|
@@ -37,8 +37,8 @@ const Navigation = ({
|
|
|
37
37
|
const navRef = useRef(React.createRef());
|
|
38
38
|
const showMenu = template !== 'ppc';
|
|
39
39
|
const logoPosition = showMenu ? 'space-between' : 'center';
|
|
40
|
-
|
|
41
|
-
const Search = hasSearch ? loadable(() => import('~organisms/search')) : null;
|
|
40
|
+
|
|
41
|
+
const Search = hasSearch ? loadable(() => import('~organisms/search')) : null;
|
|
42
42
|
|
|
43
43
|
if (options.mobile.stopScrollOnOpen) toggleScroll('', true);
|
|
44
44
|
|
|
@@ -62,12 +62,12 @@ const Navigation = ({
|
|
|
62
62
|
>
|
|
63
63
|
<nav className={styles.nav} style={{ justifyContent: logoPosition }} ref={navRef}>
|
|
64
64
|
<NavigationProvider>
|
|
65
|
-
<Link className={styles.logo} to="/" onClick={onClickHandler}>
|
|
65
|
+
<Link className={`${styles.logo} main-menu-gtm logo-cta`} to="/" onClick={onClickHandler}>
|
|
66
66
|
<img alt="logo" src={logo} width={logoWidth} height={logoHeight} />
|
|
67
67
|
</Link>
|
|
68
68
|
{showMenu && (
|
|
69
69
|
<>
|
|
70
|
-
<Menu section={section} menu={menu} options={options} />
|
|
70
|
+
<Menu section={section} menu={menu} options={options} gtmClass="main-menu-gtm" />
|
|
71
71
|
{hasSearch && <Search className={styles.search} searchIcon={searchIcon} />}
|
|
72
72
|
</>
|
|
73
73
|
)}
|
|
@@ -45,7 +45,7 @@ const SearchForm = ({ className, searchIcon, iconWidth = 24, iconHeight = 24 })
|
|
|
45
45
|
type="button"
|
|
46
46
|
aria-label="Search"
|
|
47
47
|
onClick={handleOnSearchIconClick}
|
|
48
|
-
className={`${styles.searchButton} ${showSearch && styles.active}`}
|
|
48
|
+
className={`${styles.searchButton} ${showSearch && styles.active} search-gtm btn-cta`}
|
|
49
49
|
>
|
|
50
50
|
{searchIcon === null ? (
|
|
51
51
|
<FaSearch />
|
|
@@ -6,25 +6,21 @@ import Tabs from '~hooks/tabs';
|
|
|
6
6
|
|
|
7
7
|
const TopList = ({ module, toplistHeading, CustomRow, page }) => {
|
|
8
8
|
const template = page?.template;
|
|
9
|
-
const translations = page?.translations;
|
|
10
9
|
return (
|
|
11
|
-
<Tabs tabsAlign="right">
|
|
12
|
-
{module.items.map((toplist) =>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
})}
|
|
10
|
+
<Tabs tabsAlign="right" gtmClass="toplist-tabs-menu-gtm">
|
|
11
|
+
{module.items.map((toplist) => (
|
|
12
|
+
<div label={toplist.title} key={keygen()}>
|
|
13
|
+
{toplistHeading}
|
|
14
|
+
<List
|
|
15
|
+
toplist={toplist}
|
|
16
|
+
CustomRow={CustomRow}
|
|
17
|
+
hasLoadMoreButton={toplist.show_load_more}
|
|
18
|
+
initItemsCount={toplist.num_items_initial_load}
|
|
19
|
+
loadItemsCount={toplist.num_items_load_more}
|
|
20
|
+
pageTemplate={template}
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
))}
|
|
28
24
|
</Tabs>
|
|
29
25
|
);
|
|
30
26
|
};
|
|
@@ -33,7 +29,7 @@ TopList.propTypes = {
|
|
|
33
29
|
module: PropTypes.shape({ items: PropTypes.arrayOf(PropTypes.object) }),
|
|
34
30
|
toplistHeading: PropTypes.element,
|
|
35
31
|
CustomRow: PropTypes.func,
|
|
36
|
-
page: PropTypes.shape({ template: PropTypes.string
|
|
32
|
+
page: PropTypes.shape({ template: PropTypes.string }),
|
|
37
33
|
};
|
|
38
34
|
|
|
39
35
|
export default TopList;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-return-assign */
|
|
1
2
|
import React, { useRef } from 'react';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import keygen from '~helpers/keygen';
|
|
@@ -13,7 +14,6 @@ export default function List({
|
|
|
13
14
|
initItemsCount,
|
|
14
15
|
loadItemsCount,
|
|
15
16
|
pageTemplate,
|
|
16
|
-
translations,
|
|
17
17
|
}) {
|
|
18
18
|
const initLoadItems = Number(initItemsCount) !== 0 ? Number(initItemsCount) : 10000;
|
|
19
19
|
const loadingItems = Number(loadItemsCount) !== 0 ? Number(loadItemsCount) : 10000;
|
|
@@ -25,17 +25,13 @@ export default function List({
|
|
|
25
25
|
const showLoadMoreButton = hasLoadMoreButton === '1' && Number(initItemsCount) !== 0;
|
|
26
26
|
|
|
27
27
|
function handleClick() {
|
|
28
|
-
const displayed = elRefs.current.filter((item) =>
|
|
29
|
-
return item.classList.contains(styles.show);
|
|
30
|
-
}).length;
|
|
28
|
+
const displayed = elRefs.current.filter((item) => item.classList.contains(styles.show)).length;
|
|
31
29
|
|
|
32
30
|
const nextItem = loadingItems + displayed;
|
|
33
31
|
const lastItem =
|
|
34
32
|
nextItem > elRefs.current.length ? elRefs.current.length + 1 : displayed + loadingItems;
|
|
35
33
|
|
|
36
|
-
elRefs.current.slice(displayed, lastItem).forEach((item) =>
|
|
37
|
-
return item.classList.toggle(styles.show);
|
|
38
|
-
});
|
|
34
|
+
elRefs.current.slice(displayed, lastItem).forEach((item) => item.classList.toggle(styles.show));
|
|
39
35
|
|
|
40
36
|
if (loadingItems + displayed > elRefs.current.length) {
|
|
41
37
|
loadMoreBtn.current.classList.toggle(styles.hide);
|
|
@@ -45,27 +41,24 @@ export default function List({
|
|
|
45
41
|
return (
|
|
46
42
|
<>
|
|
47
43
|
<ul className={styles.list} key={keygen()}>
|
|
48
|
-
{toplist.items.map((item, index) =>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</li>
|
|
67
|
-
);
|
|
68
|
-
})}
|
|
44
|
+
{toplist.items.map((item, index) => (
|
|
45
|
+
<li
|
|
46
|
+
className={index + 1 <= initLoadItems ? styles.show : ''}
|
|
47
|
+
key={keygen()}
|
|
48
|
+
ref={(el) => (elRefs.current[index] = el)}
|
|
49
|
+
>
|
|
50
|
+
{CustomRow ? (
|
|
51
|
+
<CustomRow
|
|
52
|
+
item={item}
|
|
53
|
+
tracker={toplist.tracker}
|
|
54
|
+
oneliner={toplist.one_liner}
|
|
55
|
+
isPPC={isPPCPage}
|
|
56
|
+
/>
|
|
57
|
+
) : (
|
|
58
|
+
<Row item={item} tracker={toplist.tracker} oneliner={toplist.one_liner} />
|
|
59
|
+
)}
|
|
60
|
+
</li>
|
|
61
|
+
))}
|
|
69
62
|
</ul>
|
|
70
63
|
{showLoadMoreButton && (
|
|
71
64
|
<div ref={loadMoreBtn} className={styles.loadMore}>
|
|
@@ -76,6 +69,7 @@ export default function List({
|
|
|
76
69
|
onClick={handleClick}
|
|
77
70
|
invertColors
|
|
78
71
|
primaryColor={false}
|
|
72
|
+
gtmClass="top-list-loadmore-gtm btn-cta"
|
|
79
73
|
/>
|
|
80
74
|
</div>
|
|
81
75
|
)}
|
|
@@ -98,5 +92,4 @@ List.propTypes = {
|
|
|
98
92
|
initItemsCount: PropTypes.string,
|
|
99
93
|
loadItemsCount: PropTypes.string,
|
|
100
94
|
pageTemplate: PropTypes.string,
|
|
101
|
-
translations: PropTypes.shape({}),
|
|
102
95
|
};
|
|
@@ -9,9 +9,10 @@ import Navigation from '~organisms/navigation';
|
|
|
9
9
|
import ScrollToTop from '~atoms/scroll-to-top';
|
|
10
10
|
import CookieConsent from '~organisms/cookie-consent';
|
|
11
11
|
|
|
12
|
-
function Body({ pageContext }) {
|
|
12
|
+
function Body({ pageContext, children }) {
|
|
13
13
|
const getBodySection = (name) => getSection(name, pageContext);
|
|
14
|
-
const template = pageContext.page
|
|
14
|
+
const { template } = pageContext.page;
|
|
15
|
+
const is404 = pageContext?.page?.path?.includes('404');
|
|
15
16
|
|
|
16
17
|
const main = getBodySection('main');
|
|
17
18
|
const navigation = getBodySection('navigation');
|
|
@@ -19,12 +20,12 @@ function Body({ pageContext }) {
|
|
|
19
20
|
const sidebar = getBodySection('sidebar');
|
|
20
21
|
|
|
21
22
|
const Sidebar = sidebar ? loadable(() => import(`~molecules/sidebar`)) : null;
|
|
22
|
-
|
|
23
23
|
return (
|
|
24
24
|
<>
|
|
25
25
|
{navigation && <Navigation template={template} section={navigation} />}
|
|
26
|
-
<Header section={pageContext} />
|
|
27
|
-
{main && <Main section={main} page={pageContext.page} />}
|
|
26
|
+
{!is404 && <Header section={pageContext} />}
|
|
27
|
+
{main && !children && <Main section={main} page={pageContext.page} />}
|
|
28
|
+
{children && <main>{children}</main>}
|
|
28
29
|
{Sidebar && <Sidebar section={sidebar} />}
|
|
29
30
|
<ScrollToTop />
|
|
30
31
|
<Footer template={template} section={footer} />
|
|
@@ -34,9 +35,12 @@ function Body({ pageContext }) {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
Body.propTypes = {
|
|
38
|
+
children: PropTypes.element,
|
|
37
39
|
pageContext: PropTypes.shape({
|
|
38
40
|
page: PropTypes.shape({
|
|
39
41
|
id: PropTypes.number,
|
|
42
|
+
path: PropTypes.string,
|
|
43
|
+
template: PropTypes.string,
|
|
40
44
|
}),
|
|
41
45
|
}).isRequired,
|
|
42
46
|
};
|
|
@@ -1,15 +1,37 @@
|
|
|
1
|
+
/* eslint-disable arrow-body-style */
|
|
1
2
|
import React from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
2
4
|
|
|
3
5
|
import Search from '~molecules/search';
|
|
4
6
|
import Card from '~atoms/cards/default-card';
|
|
7
|
+
import { translate } from '~helpers/getters';
|
|
5
8
|
|
|
6
|
-
const SearchContent = () => {
|
|
9
|
+
const SearchContent = ({ page }) => {
|
|
7
10
|
return (
|
|
8
11
|
<Search
|
|
9
12
|
pageSearchOptions={{
|
|
13
|
+
useArchive: true,
|
|
14
|
+
archiveOptions: {
|
|
15
|
+
titles: [
|
|
16
|
+
{ type: 'operator', title: translate(page?.translations, 'casino', 'Casino') },
|
|
17
|
+
{ type: 'article', title: translate(page?.translations, 'news', 'News') },
|
|
18
|
+
],
|
|
19
|
+
includeOptions: {
|
|
20
|
+
desktop_num_of_columns: '3',
|
|
21
|
+
mobile_num_of_columns: '1',
|
|
22
|
+
tablet_num_of_columns: '3',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
10
25
|
tabs: true,
|
|
11
26
|
tabsOptions: { showAll: 'ShowAll', tabsAlign: 'left' },
|
|
12
27
|
sort: [{ name: 'Sorting', field: 'id', type: 'number' }],
|
|
28
|
+
loadMore: {
|
|
29
|
+
label: translate(page?.translations, 'show_more', 'Show more'),
|
|
30
|
+
limit: 3,
|
|
31
|
+
increment: 6,
|
|
32
|
+
usePrimaryButton: false,
|
|
33
|
+
useInvertColors: true,
|
|
34
|
+
},
|
|
13
35
|
}}
|
|
14
36
|
>
|
|
15
37
|
{(item) => (
|
|
@@ -26,4 +48,17 @@ const SearchContent = () => {
|
|
|
26
48
|
);
|
|
27
49
|
};
|
|
28
50
|
|
|
51
|
+
SearchContent.propTypes = {
|
|
52
|
+
page: PropTypes.shape({
|
|
53
|
+
template: PropTypes.string,
|
|
54
|
+
path: PropTypes.string,
|
|
55
|
+
updated_at: PropTypes.string,
|
|
56
|
+
created_at: PropTypes.string,
|
|
57
|
+
author: PropTypes.shape({
|
|
58
|
+
name: PropTypes.string,
|
|
59
|
+
}),
|
|
60
|
+
translations: PropTypes.shape({}),
|
|
61
|
+
}),
|
|
62
|
+
};
|
|
63
|
+
|
|
29
64
|
export default SearchContent;
|
|
@@ -10,9 +10,9 @@ import styles from './tracker.module.scss';
|
|
|
10
10
|
const Tracker = ({
|
|
11
11
|
pageContext,
|
|
12
12
|
path,
|
|
13
|
-
mainText = '',
|
|
14
|
-
redirectText = '',
|
|
15
|
-
btnText = '',
|
|
13
|
+
mainText = 'One sec, while we load [operator_name] for you..',
|
|
14
|
+
redirectText = 'If the casino has not loaded within a few seconds',
|
|
15
|
+
btnText = 'Click Here!',
|
|
16
16
|
bgImage = '',
|
|
17
17
|
bgVideo = '',
|
|
18
18
|
redirectTimer = 5000,
|
|
@@ -95,7 +95,10 @@ const Tracker = ({
|
|
|
95
95
|
{background}
|
|
96
96
|
<div className={styles.content}>
|
|
97
97
|
<LazyImage alt="Site logo" src={logo} />
|
|
98
|
-
<p className={styles.mainText}>{`${mainText
|
|
98
|
+
<p className={styles.mainText}>{`${mainText.replace(
|
|
99
|
+
'[operator_name]',
|
|
100
|
+
operator.name
|
|
101
|
+
)}`}</p>
|
|
99
102
|
<div className={styles.bar} />
|
|
100
103
|
{counter ? (
|
|
101
104
|
redirectText
|
|
@@ -113,6 +116,7 @@ const Tracker = ({
|
|
|
113
116
|
to={prettyTracker(operator)}
|
|
114
117
|
targetBlank={false}
|
|
115
118
|
isInternalLink={false}
|
|
119
|
+
gtmClass="tracker-gtm btn-cta"
|
|
116
120
|
/>
|
|
117
121
|
</div>
|
|
118
122
|
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React, { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export const Context = createContext();
|
|
4
|
+
|
|
5
|
+
export default (props) => {
|
|
6
|
+
// eslint-disable-next-line react/prop-types
|
|
7
|
+
const { value, children } = props;
|
|
8
|
+
return <Context.Provider value={value}>{children}</Context.Provider>;
|
|
9
|
+
};
|
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
/* eslint-disable no-use-before-define */
|
|
4
4
|
/* eslint-disable no-shadow */
|
|
5
5
|
|
|
6
|
-
import { cloneDeep } from 'lodash';
|
|
6
|
+
import { cloneDeep, pick } from 'lodash';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import ModuleValue from '../../constants/module-value';
|
|
9
9
|
import SearchTypesEnable from '../../constants/search-types-enable';
|
|
10
|
+
import { pickHTMLSitemapPageKeys } from '../../constants/pick-keys';
|
|
10
11
|
|
|
11
12
|
// eslint-disable-next-line import/no-cycle
|
|
12
13
|
import { processModule } from './modules';
|
|
13
14
|
// eslint-disable-next-line import/no-cycle
|
|
14
|
-
import { clonePageForCards } from './common';
|
|
15
|
+
import { clonePageForCards, groupBy } from './common';
|
|
15
16
|
import { prepareSportsData, addSportsDataToPage } from './sports';
|
|
16
17
|
|
|
17
18
|
const previewMode = process.env.GATSBY_PREVIEW_MODE || false;
|
|
@@ -32,7 +33,23 @@ let prefilledMarketModules = null;
|
|
|
32
33
|
let prefilledMarketModulesRaw = null;
|
|
33
34
|
let sportsData = null;
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
export function processSitemapPages(pages, markets) {
|
|
37
|
+
const pageListByMarket = [];
|
|
38
|
+
Object.keys(markets).forEach((market) => {
|
|
39
|
+
pageListByMarket[market] = [];
|
|
40
|
+
let pageList = [];
|
|
41
|
+
Object.keys(pages[market]).forEach((pageType) => {
|
|
42
|
+
pageList = pageList.concat(
|
|
43
|
+
pages[market][pageType].map((row) => pick(row, pickHTMLSitemapPageKeys))
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
pageListByMarket[market] = groupBy(pageList, 'template_id');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return pageListByMarket;
|
|
51
|
+
}
|
|
52
|
+
|
|
36
53
|
function transform(response) {
|
|
37
54
|
const transformed = {};
|
|
38
55
|
Object.keys(response.site_markets).forEach((siteMarket) => {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { processSitemapPages } from '.';
|
|
2
|
+
import getPageDataList from '~tests/factories/pages/list.factory';
|
|
3
|
+
|
|
4
|
+
describe('processor Helper', () => {
|
|
5
|
+
test('process sitemap', () => {
|
|
6
|
+
const pageList = getPageDataList(10);
|
|
7
|
+
const market = 'ie';
|
|
8
|
+
const processedSitemap = processSitemapPages(
|
|
9
|
+
{ [market]: { type: pageList } },
|
|
10
|
+
{ [market]: [] }
|
|
11
|
+
);
|
|
12
|
+
expect(processedSitemap[market]['5']).toHaveLength(10);
|
|
13
|
+
});
|
|
14
|
+
});
|
package/src/hooks/link/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
3
|
import GatsbyLink from 'gatsby-link';
|
|
3
4
|
import { navigate } from '@reach/router';
|
|
4
5
|
import PropTypes from 'prop-types';
|
|
@@ -53,6 +54,7 @@ Link.propTypes = {
|
|
|
53
54
|
children: PropTypes.oneOfType([PropTypes.node, PropTypes.element, PropTypes.any]),
|
|
54
55
|
activeClassName: PropTypes.string,
|
|
55
56
|
partiallyActive: PropTypes.bool,
|
|
57
|
+
gtmClass: PropTypes.string,
|
|
56
58
|
};
|
|
57
59
|
|
|
58
60
|
export default Link;
|
|
@@ -23,6 +23,15 @@ describe('Link Component', () => {
|
|
|
23
23
|
);
|
|
24
24
|
expect(getByText('Test Content').closest('a')).toHaveAttribute('href', '/test/link');
|
|
25
25
|
});
|
|
26
|
+
|
|
27
|
+
test('test GTM class', () => {
|
|
28
|
+
const { getByText } = render(
|
|
29
|
+
<Link to="test/link" className="testClassName test-gtm">
|
|
30
|
+
Test Content
|
|
31
|
+
</Link>
|
|
32
|
+
);
|
|
33
|
+
expect(getByText('Test Content').closest('a').classList.contains('test-gtm')).toBe(true);
|
|
34
|
+
});
|
|
26
35
|
});
|
|
27
36
|
afterEach(() => {
|
|
28
37
|
cleanup();
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
|
2
|
+
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
|
3
|
+
|
|
1
4
|
import React, { useContext, useRef, useEffect } from 'react';
|
|
2
5
|
import PropTypes from 'prop-types';
|
|
3
6
|
import { ModalContext } from './modalContext';
|
|
@@ -7,6 +10,7 @@ const ModalContent = ({ closeIcon }) => {
|
|
|
7
10
|
const { showModal, setShowModal, modalContent, setModalContent } = useContext(ModalContext);
|
|
8
11
|
const modal = useRef(null);
|
|
9
12
|
|
|
13
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10
14
|
const close = () => {
|
|
11
15
|
setShowModal(false);
|
|
12
16
|
setModalContent('');
|
|
@@ -31,7 +35,7 @@ const ModalContent = ({ closeIcon }) => {
|
|
|
31
35
|
return () => {
|
|
32
36
|
if (typeof window !== 'undefined') window.removeEventListener('keydown', handleEsc);
|
|
33
37
|
};
|
|
34
|
-
}, []);
|
|
38
|
+
}, [close]);
|
|
35
39
|
|
|
36
40
|
// Close on outside click
|
|
37
41
|
useEffect(() => {
|
|
@@ -49,14 +53,14 @@ const ModalContent = ({ closeIcon }) => {
|
|
|
49
53
|
if (typeof window !== 'undefined')
|
|
50
54
|
window.removeEventListener('mousedown', handleOutsideClick);
|
|
51
55
|
};
|
|
52
|
-
}, []);
|
|
56
|
+
}, [close]);
|
|
53
57
|
|
|
54
58
|
return (
|
|
55
59
|
<div className={styles.modalInner} ref={modal}>
|
|
56
60
|
<div className={styles.modalOverlay} onClick={close} />
|
|
57
61
|
<div className={styles.modalContent}>
|
|
58
62
|
{closeIcon && (
|
|
59
|
-
<button className={styles.closeIcon} onClick={close}>
|
|
63
|
+
<button className={`${styles.closeIcon} modal-gtm btn-cta`} type="button" onClick={close}>
|
|
60
64
|
{closeIcon}
|
|
61
65
|
</button>
|
|
62
66
|
)}
|
|
@@ -8,9 +8,10 @@ import ModalProvider from './modalContext';
|
|
|
8
8
|
import ModalContent from './modal-content';
|
|
9
9
|
|
|
10
10
|
const setUp = () => {
|
|
11
|
+
React.useContext = ModalProvider;
|
|
11
12
|
const { container, getAllByText } = render(
|
|
12
13
|
<ModalProvider>
|
|
13
|
-
<Modal content=
|
|
14
|
+
<Modal content="Modal opened">
|
|
14
15
|
<p>Click me</p>
|
|
15
16
|
</Modal>
|
|
16
17
|
<ModalContent closeIcon={<MdClose />} overlay />
|
|
@@ -32,7 +33,7 @@ describe('Modal Component', () => {
|
|
|
32
33
|
|
|
33
34
|
// Toggle effect
|
|
34
35
|
test('toggle modal', () => {
|
|
35
|
-
const { container,getAllByText } = setUp();
|
|
36
|
+
const { container, getAllByText } = setUp();
|
|
36
37
|
const toggleBtn = container.querySelector('p');
|
|
37
38
|
|
|
38
39
|
fireEvent.click(toggleBtn);
|
package/src/hooks/tabs/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const Tabs = ({
|
|
|
10
10
|
activeTabClass = '',
|
|
11
11
|
HeaderComp,
|
|
12
12
|
headerClass = '',
|
|
13
|
+
gtmClass = '',
|
|
13
14
|
}) => {
|
|
14
15
|
const showAllTabId = `${showAll}_0`;
|
|
15
16
|
const showTabs = children.length > 1;
|
|
@@ -35,7 +36,8 @@ const Tabs = ({
|
|
|
35
36
|
activeTab={activeTab}
|
|
36
37
|
activeTabClass={activeTabClass}
|
|
37
38
|
showAll={showAll}
|
|
38
|
-
|
|
39
|
+
gtmClass={gtmClass}
|
|
40
|
+
alignRight={tabsAlign === 'right'}
|
|
39
41
|
/>
|
|
40
42
|
)}
|
|
41
43
|
{HeaderComp && <div className={styles.headerComp}>{HeaderComp}</div>}
|
|
@@ -67,6 +69,7 @@ Tabs.propTypes = {
|
|
|
67
69
|
activeTabClass: PropTypes.string,
|
|
68
70
|
HeaderComp: PropTypes.objectOf(PropTypes.any),
|
|
69
71
|
headerClass: PropTypes.string,
|
|
72
|
+
gtmClass: PropTypes.string,
|
|
70
73
|
};
|
|
71
74
|
|
|
72
75
|
export default Tabs;
|
|
@@ -16,6 +16,7 @@ const TabList = ({
|
|
|
16
16
|
activeTabClass = '',
|
|
17
17
|
showAll,
|
|
18
18
|
alignRight = false,
|
|
19
|
+
gtmClass = '',
|
|
19
20
|
}) => {
|
|
20
21
|
const [tabItems, setTabItems] = useState(items);
|
|
21
22
|
|
|
@@ -41,7 +42,7 @@ const TabList = ({
|
|
|
41
42
|
<div className={`${styles.tabList} ${alignRight && styles.right}`}>
|
|
42
43
|
<button
|
|
43
44
|
ref={filterBtn}
|
|
44
|
-
className={styles.select}
|
|
45
|
+
className={`${styles.select} ${gtmClass} btn-cta`}
|
|
45
46
|
type="button"
|
|
46
47
|
onClick={showDropdown}
|
|
47
48
|
data-id="select-button"
|
|
@@ -62,6 +63,7 @@ const TabList = ({
|
|
|
62
63
|
label={label}
|
|
63
64
|
onClick={onClick}
|
|
64
65
|
toggleDropdown={showDropdown}
|
|
66
|
+
gtmClass={gtmClass}
|
|
65
67
|
/>
|
|
66
68
|
);
|
|
67
69
|
})}
|
|
@@ -77,6 +79,7 @@ TabList.propTypes = {
|
|
|
77
79
|
activeTab: PropTypes.string,
|
|
78
80
|
activeTabClass: PropTypes.string,
|
|
79
81
|
alignRight: PropTypes.bool,
|
|
82
|
+
gtmClass: PropTypes.bool,
|
|
80
83
|
};
|
|
81
84
|
|
|
82
85
|
export default TabList;
|