gatsby-core-theme 44.22.0 → 44.22.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/CHANGELOG.md +27 -0
- package/package.json +1 -1
- package/src/components/molecules/cookie-modal/index.js +58 -62
- package/src/components/molecules/floating-area/index.js +15 -14
- package/src/components/organisms/cookie-consent/cookie-consent.test.js +3 -2
- package/src/components/organisms/cookie-consent/index.js +38 -14
- package/src/components/pages/body/body.test.js +1 -1
- package/src/constants/cookies.js +99 -0
- package/src/helpers/generators.mjs +20 -0
- package/src/helpers/generators.test.js +52 -0
- package/src/resolver/modules.mjs +55 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
## [44.22.2](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.22.1...v44.22.2) (2026-04-24)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* mapped spotlight mode sports_odds ([e8d5757](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e8d575769e213645f7b0096589b7297c93f63d24))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
* Merge branch 'EN-497-Enable-new-spotlight-mode' into 'master' ([0e1f54d](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/0e1f54d2b36cf678fbbad1199c041d7996624d73))
|
|
10
|
+
|
|
11
|
+
## [44.22.1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.22.0...v44.22.1) (2026-04-21)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* fix eslint error ([7698d62](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/7698d62217cc3133caf4b18f1a291bcaea08a3f5))
|
|
17
|
+
* fix tests for cookie consent ([60c738f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/60c738f4d5cb7b79c5fb573adecb1076c26dfa96))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Config
|
|
21
|
+
|
|
22
|
+
* change logic to config driven ([e546f1a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e546f1a06609649fe229d31c2cc5c5e3e13ae127))
|
|
23
|
+
* refactor cookie consents to use custom content ([0b611c4](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/0b611c423aa7406450b63e554df1db1b621d5a75))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
* Merge branch 'EN-475/refactor-cookie-consents' into 'master' ([11aba91](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/11aba914e3f81e33c36c3b28c2c671f124ec532f))
|
|
27
|
+
|
|
1
28
|
# [44.22.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.21.1...v44.22.0) (2026-04-14)
|
|
2
29
|
|
|
3
30
|
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
2
|
/* eslint-disable jsx-a11y/no-redundant-roles */
|
|
3
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
4
|
import React, { useState, useRef, useEffect } from "react";
|
|
4
5
|
import PropTypes from "prop-types";
|
|
5
6
|
|
|
@@ -11,6 +12,8 @@ import LazyImage from "~hooks/lazy-image";
|
|
|
11
12
|
import CategoryContainer from "./category/index";
|
|
12
13
|
import Button from "~atoms/button/button";
|
|
13
14
|
import styles from "./cookie-modal.module.scss";
|
|
15
|
+
import cookiesContent from '../../../constants/cookies';
|
|
16
|
+
import { parseCookieTextWithLinks } from '../../../helpers/generators.mjs';
|
|
14
17
|
|
|
15
18
|
const CookieModal = ({
|
|
16
19
|
handleAcceptCookies,
|
|
@@ -19,21 +22,23 @@ const CookieModal = ({
|
|
|
19
22
|
acceptButtonType = "primary",
|
|
20
23
|
buttonSize = "m",
|
|
21
24
|
closeModal,
|
|
22
|
-
cookieLink = {
|
|
23
|
-
title: "",
|
|
24
|
-
path: "",
|
|
25
|
-
},
|
|
26
25
|
logo = "/images/logo.svg",
|
|
27
26
|
templateTwo = false,
|
|
28
27
|
hide,
|
|
29
28
|
}) => {
|
|
30
29
|
const [categorySection, setCategorySection] = useState(0);
|
|
31
|
-
const [
|
|
32
|
-
const [marketing, setMarketingButton] = useState(false);
|
|
30
|
+
const [categoryStates, setCategoryStates] = useState({});
|
|
33
31
|
const [menage, setMenage] = useState(true);
|
|
34
32
|
|
|
35
33
|
const modal = useRef(null);
|
|
36
34
|
|
|
35
|
+
const modalSettings = cookiesContent.modal;
|
|
36
|
+
|
|
37
|
+
const translatedDescriptionLinks = (modalSettings?.links || []).map((link) => ({
|
|
38
|
+
...link,
|
|
39
|
+
translatedText: useTranslate(link.translationKey || "", link.text || ""),
|
|
40
|
+
}));
|
|
41
|
+
|
|
37
42
|
const handlePreference = () => {
|
|
38
43
|
if (templateTwo) {
|
|
39
44
|
setMenage(!menage);
|
|
@@ -55,40 +60,20 @@ const CookieModal = ({
|
|
|
55
60
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
56
61
|
}, []);
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
defaultText:
|
|
73
|
-
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nibh aliquam non sit morbi neque in sodales tellus. Cursus neque sed quis tincidunt sed vestibulum rhoncus dolor elementum. Imperdiet tortor dolor sit nisi, magnis cras id ut. Id dolor, vel neque lobortis. Diam commodo vitae vulputate at ultrices id odio praesent. Nisi, sit massa orci accumsan.",
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
translateKey: "marketing_cookie_title",
|
|
77
|
-
button: true,
|
|
78
|
-
altTranslation: "Marketing",
|
|
79
|
-
textKey: "marketing_cookie_text",
|
|
80
|
-
defaultText:
|
|
81
|
-
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nibh aliquam non sit morbi neque in sodales tellus. Cursus neque sed quis tincidunt sed vestibulum rhoncus dolor elementum. Imperdiet tortor dolor sit nisi, magnis cras id ut. Id dolor, vel neque lobortis. Diam commodo vitae vulputate at ultrices id odio praesent. Nisi, sit massa orci accumsan.",
|
|
82
|
-
},
|
|
83
|
-
];
|
|
84
|
-
|
|
85
|
-
const privacyText = useTranslate(
|
|
86
|
-
"privacy_preference_title",
|
|
87
|
-
"Privacy Preference Center"
|
|
88
|
-
);
|
|
89
|
-
const buttonText = useTranslate(
|
|
90
|
-
"cookie_confirm_button",
|
|
91
|
-
"Confirm my choices"
|
|
63
|
+
|
|
64
|
+
const CategoryObj = (modalSettings?.categories || []).map((item) => ({
|
|
65
|
+
translateKey: item?.title?.translationKey,
|
|
66
|
+
button: item?.hasToggle,
|
|
67
|
+
altTranslation: item?.title?.label,
|
|
68
|
+
textKey: item?.description?.translationKey,
|
|
69
|
+
defaultText: item?.description?.label,
|
|
70
|
+
alwaysEnabledLabel: item?.alwaysEnabledLabel,
|
|
71
|
+
}));
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
const privacyDescription = useTranslate(
|
|
75
|
+
modalSettings?.description?.translationKey,
|
|
76
|
+
modalSettings?.description?.label
|
|
92
77
|
);
|
|
93
78
|
|
|
94
79
|
return (
|
|
@@ -107,12 +92,15 @@ const CookieModal = ({
|
|
|
107
92
|
src={logo}
|
|
108
93
|
/>
|
|
109
94
|
) : (
|
|
110
|
-
<span>{
|
|
95
|
+
<span>{useTranslate(modalSettings?.title?.translationKey, modalSettings?.title?.label)}</span>
|
|
111
96
|
)}
|
|
112
97
|
|
|
113
98
|
<button
|
|
114
99
|
role="button"
|
|
115
|
-
aria-label={useTranslate(
|
|
100
|
+
aria-label={useTranslate(
|
|
101
|
+
modalSettings?.closeAriaLabel?.translationKey,
|
|
102
|
+
modalSettings?.closeAriaLabel?.label
|
|
103
|
+
)}
|
|
116
104
|
type="button"
|
|
117
105
|
onClick={() => closeModal()}
|
|
118
106
|
>
|
|
@@ -120,16 +108,15 @@ const CookieModal = ({
|
|
|
120
108
|
</button>
|
|
121
109
|
</div>
|
|
122
110
|
<div className={styles?.modalTextHeader || ""}>
|
|
123
|
-
{!templateTwo && <span>{
|
|
124
|
-
<p>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<Link to={cookieLink?.path} className={styles.cookieLink}>
|
|
131
|
-
{cookieLink?.title}
|
|
111
|
+
{!templateTwo && <span>{useTranslate(modalSettings?.title?.translationKey, modalSettings?.title?.label)}</span>}
|
|
112
|
+
<p>{parseCookieTextWithLinks(
|
|
113
|
+
privacyDescription,
|
|
114
|
+
translatedDescriptionLinks,
|
|
115
|
+
(link, key) => (
|
|
116
|
+
<Link key={key} to={link.url} className={styles.cookieLink}>
|
|
117
|
+
{link.translatedText}
|
|
132
118
|
</Link>
|
|
119
|
+
)
|
|
133
120
|
)}
|
|
134
121
|
</p>
|
|
135
122
|
</div>
|
|
@@ -137,8 +124,8 @@ const CookieModal = ({
|
|
|
137
124
|
<Button
|
|
138
125
|
onClick={() => handleAcceptCookies()}
|
|
139
126
|
btnText={useTranslate(
|
|
140
|
-
|
|
141
|
-
|
|
127
|
+
modalSettings?.acceptAllButton?.translationKey,
|
|
128
|
+
modalSettings?.acceptAllButton?.label
|
|
142
129
|
)}
|
|
143
130
|
isInternalLink={false}
|
|
144
131
|
buttonType={acceptButtonType}
|
|
@@ -148,8 +135,8 @@ const CookieModal = ({
|
|
|
148
135
|
<Button
|
|
149
136
|
onClick={() => handleDeclineCookies()}
|
|
150
137
|
btnText={useTranslate(
|
|
151
|
-
|
|
152
|
-
|
|
138
|
+
modalSettings?.rejectNonNecessaryButton?.translationKey,
|
|
139
|
+
modalSettings?.rejectNonNecessaryButton?.label
|
|
153
140
|
)}
|
|
154
141
|
isInternalLink={false}
|
|
155
142
|
buttonType={declineButtonType}
|
|
@@ -168,8 +155,8 @@ const CookieModal = ({
|
|
|
168
155
|
className={styles?.mainTitle || ""}
|
|
169
156
|
>
|
|
170
157
|
{useTranslate(
|
|
171
|
-
|
|
172
|
-
|
|
158
|
+
modalSettings?.manageConsentTitle?.translationKey,
|
|
159
|
+
modalSettings?.manageConsentTitle?.label
|
|
173
160
|
)}
|
|
174
161
|
{templateTwo && (
|
|
175
162
|
<svg
|
|
@@ -192,15 +179,21 @@ const CookieModal = ({
|
|
|
192
179
|
</span>
|
|
193
180
|
|
|
194
181
|
{CategoryObj.map((elm, index) => {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
182
|
+
const currentState = categoryStates[index] || false;
|
|
183
|
+
|
|
184
|
+
const updateState = (value) => {
|
|
185
|
+
setCategoryStates((prev) => ({
|
|
186
|
+
...prev,
|
|
187
|
+
[index]: value,
|
|
188
|
+
}));
|
|
189
|
+
};
|
|
198
190
|
|
|
199
191
|
return (
|
|
200
192
|
<CategoryContainer
|
|
193
|
+
key={elm.translateKey || index}
|
|
201
194
|
obj={elm}
|
|
202
195
|
index={index}
|
|
203
|
-
currentState={
|
|
196
|
+
currentState={currentState}
|
|
204
197
|
updateState={updateState}
|
|
205
198
|
setCurrentSection={setCategorySection}
|
|
206
199
|
currentSection={categorySection}
|
|
@@ -212,7 +205,10 @@ const CookieModal = ({
|
|
|
212
205
|
<div className={styles?.lastButton || ""}>
|
|
213
206
|
<Button
|
|
214
207
|
onClick={() => handleAcceptCookies()}
|
|
215
|
-
btnText={
|
|
208
|
+
btnText={useTranslate(
|
|
209
|
+
modalSettings?.confirmButton?.translationKey,
|
|
210
|
+
modalSettings?.confirmButton?.label
|
|
211
|
+
)}
|
|
216
212
|
isInternalLink={false}
|
|
217
213
|
buttonType={acceptButtonType}
|
|
218
214
|
buttonSize={buttonSize}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-case-declarations */
|
|
2
2
|
/* eslint-disable react/no-danger */
|
|
3
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
4
|
import React, { useState, lazy, Suspense } from "react";
|
|
4
5
|
import PropTypes from "prop-types";
|
|
5
6
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
@@ -11,6 +12,7 @@ import { mainSettings } from "../../../constants/site-settings/main";
|
|
|
11
12
|
import styles from "./floating-area.module.scss";
|
|
12
13
|
import { pageTypes } from "../../../constants/site-settings/navigation";
|
|
13
14
|
import { trackerLinkActive } from "~helpers/tracker.mjs";
|
|
15
|
+
import useTranslate from "~hooks/useTranslate/useTranslate";
|
|
14
16
|
|
|
15
17
|
const showOperatorBanner = (operator, pageTemplate) =>
|
|
16
18
|
mainSettings[pageTemplate]?.operator_banner &&
|
|
@@ -24,7 +26,6 @@ export default function FloatingArea({
|
|
|
24
26
|
template,
|
|
25
27
|
offsetTop = 400,
|
|
26
28
|
showCookies = true,
|
|
27
|
-
customCookieContent,
|
|
28
29
|
}) {
|
|
29
30
|
const showScroll = isSticky(offsetTop);
|
|
30
31
|
const [closedBanner, setClosedBanner] = useState(false);
|
|
@@ -82,24 +83,25 @@ export default function FloatingArea({
|
|
|
82
83
|
</Suspense>
|
|
83
84
|
)}
|
|
84
85
|
|
|
85
|
-
{
|
|
86
|
+
{showCookies && (
|
|
86
87
|
<CookieConsent
|
|
87
88
|
market={pageContext?.page?.market}
|
|
88
89
|
type={pageType}
|
|
89
90
|
template={template}
|
|
90
91
|
settingsCookie
|
|
91
92
|
isPageHomepage={isPageHomepage}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
experience with us. By using the site you consent to our
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
</
|
|
102
|
-
|
|
93
|
+
>
|
|
94
|
+
<p>
|
|
95
|
+
{useTranslate(
|
|
96
|
+
"cookie_consent_default_text",
|
|
97
|
+
"We use cookies in order to optimise our site and improve your experience with us. By using the site you consent to our"
|
|
98
|
+
)}
|
|
99
|
+
<a href="/cookies" className="cookie-consent-gtm">
|
|
100
|
+
{" "}
|
|
101
|
+
{useTranslate("cookie_policy_link", "Cookie Policy")}
|
|
102
|
+
</a>
|
|
103
|
+
.
|
|
104
|
+
</p>
|
|
103
105
|
</CookieConsent>
|
|
104
106
|
)}
|
|
105
107
|
{FooterNavigation && (
|
|
@@ -142,5 +144,4 @@ FloatingArea.propTypes = {
|
|
|
142
144
|
offsetTop: PropTypes.number,
|
|
143
145
|
template: PropTypes.string,
|
|
144
146
|
showCookies: PropTypes.bool,
|
|
145
|
-
customCookieContent: PropTypes.node,
|
|
146
147
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-syntax */
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { render, cleanup, fireEvent } from '@testing-library/react';
|
|
3
4
|
import '@testing-library/jest-dom/extend-expect';
|
|
@@ -40,11 +41,11 @@ describe('cookie consent component', () => {
|
|
|
40
41
|
});
|
|
41
42
|
test('Buttons', () => {
|
|
42
43
|
const { getByText } = renderComponent();
|
|
43
|
-
expect(getByText('Accept
|
|
44
|
+
expect(getByText('Accept')).toBeTruthy();
|
|
44
45
|
});
|
|
45
46
|
test('Hide on accept', () => {
|
|
46
47
|
const { container, getByText } = renderComponent();
|
|
47
|
-
const btn = getByText('Accept
|
|
48
|
+
const btn = getByText('Accept');
|
|
48
49
|
fireEvent.click(btn);
|
|
49
50
|
expect(container.querySelector('div.cookieConsent')).not.toHaveClass('show');
|
|
50
51
|
expect(Boolean(getCookie('CookieConsent'))).toBe(true);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/exhaustive-deps */
|
|
2
2
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
|
3
3
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
4
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
4
5
|
import React, { useState, useEffect, lazy, Suspense } from "react";
|
|
5
6
|
import PropTypes from "prop-types";
|
|
6
7
|
|
|
@@ -8,9 +9,10 @@ import useTranslate from "~hooks/useTranslate/useTranslate";
|
|
|
8
9
|
import { setCookie, getCookie } from "~helpers/cookies";
|
|
9
10
|
import styles from "./cookie-consent.module.scss";
|
|
10
11
|
|
|
12
|
+
import cookiesContent from '../../../constants/cookies';
|
|
13
|
+
import { parseCookieTextWithLinks } from '../../../helpers/generators.mjs'
|
|
14
|
+
|
|
11
15
|
const CookieConsent = ({
|
|
12
|
-
acceptText = "Accept",
|
|
13
|
-
rejectText = "Reject",
|
|
14
16
|
settingsCookie,
|
|
15
17
|
children,
|
|
16
18
|
cookieName = "CookieConsent",
|
|
@@ -24,6 +26,24 @@ const CookieConsent = ({
|
|
|
24
26
|
|
|
25
27
|
const CookieModal = lazy(() => import("../../molecules/cookie-modal"));
|
|
26
28
|
|
|
29
|
+
|
|
30
|
+
const shouldShowRejectButton =
|
|
31
|
+
typeof cookiesContent.showRejectButton === "boolean"
|
|
32
|
+
? cookiesContent.showRejectButton
|
|
33
|
+
: showRejectButton;
|
|
34
|
+
|
|
35
|
+
const shouldIgnoreComponentChildren =
|
|
36
|
+
cookiesContent?.ignoreComponentChildren === true;
|
|
37
|
+
|
|
38
|
+
const translatedLinks = (cookiesContent.links || []).map((link) => ({
|
|
39
|
+
...link,
|
|
40
|
+
translatedText: useTranslate(link.translationKey || "", link.text || ""),
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const bannerText = useTranslate(
|
|
44
|
+
cookiesContent.text?.translationKey,
|
|
45
|
+
cookiesContent.text?.label
|
|
46
|
+
);
|
|
27
47
|
// when user declines
|
|
28
48
|
const handleDecline = () => {
|
|
29
49
|
setCookie(cookieName, false, 365, "/");
|
|
@@ -58,11 +78,6 @@ const CookieConsent = ({
|
|
|
58
78
|
}
|
|
59
79
|
}, []);
|
|
60
80
|
|
|
61
|
-
const settingCookieText = useTranslate(
|
|
62
|
-
"cookie_setting_button",
|
|
63
|
-
"Cookie Setting"
|
|
64
|
-
);
|
|
65
|
-
|
|
66
81
|
return (
|
|
67
82
|
<>
|
|
68
83
|
<div
|
|
@@ -71,7 +86,15 @@ const CookieConsent = ({
|
|
|
71
86
|
}`}
|
|
72
87
|
>
|
|
73
88
|
<div className={`${styles?.consent || ""}`}>
|
|
74
|
-
<div className={styles?.content || ""}>{
|
|
89
|
+
<div className={styles?.content || ""}>{shouldIgnoreComponentChildren ? (
|
|
90
|
+
parseCookieTextWithLinks(bannerText, translatedLinks, (link, key) => (
|
|
91
|
+
<a key={key} href={link.url} className="cookie-consent-gtm">
|
|
92
|
+
{link.translatedText}
|
|
93
|
+
</a>
|
|
94
|
+
))
|
|
95
|
+
) : (
|
|
96
|
+
children
|
|
97
|
+
)}</div>
|
|
75
98
|
<div className={styles?.buttonsContainer || ""}>
|
|
76
99
|
{settingsCookie && (
|
|
77
100
|
<button
|
|
@@ -79,18 +102,21 @@ const CookieConsent = ({
|
|
|
79
102
|
className="cookie-consent-gtm btn-cta"
|
|
80
103
|
type="button"
|
|
81
104
|
>
|
|
82
|
-
{
|
|
105
|
+
{useTranslate(
|
|
106
|
+
cookiesContent.managePreferences?.translationKey,
|
|
107
|
+
cookiesContent.managePreferences?.label
|
|
108
|
+
)}
|
|
83
109
|
{icon && icon}
|
|
84
110
|
</button>
|
|
85
111
|
)}
|
|
86
|
-
{
|
|
112
|
+
{shouldShowRejectButton && (
|
|
87
113
|
<button
|
|
88
114
|
onClick={() => handleDecline()}
|
|
89
115
|
className={`${styles.rejectButton} cookie-consent-gtm btn-cta`}
|
|
90
116
|
type="button"
|
|
91
117
|
>
|
|
92
118
|
{/* eslint-disable-next-line react/jsx-no-comment-textnodes, react-hooks/rules-of-hooks */}
|
|
93
|
-
{useTranslate(
|
|
119
|
+
{useTranslate(cookiesContent.rejectButton?.translationKey, cookiesContent.rejectButton?.label)}
|
|
94
120
|
</button>
|
|
95
121
|
)}
|
|
96
122
|
<button
|
|
@@ -98,7 +124,7 @@ const CookieConsent = ({
|
|
|
98
124
|
className="cookie-consent-gtm btn-cta"
|
|
99
125
|
type="button"
|
|
100
126
|
>
|
|
101
|
-
{useTranslate(
|
|
127
|
+
{useTranslate(cookiesContent.acceptButton?.translationKey, cookiesContent.acceptButton?.label)}
|
|
102
128
|
{icon && icon}
|
|
103
129
|
</button>
|
|
104
130
|
</div>
|
|
@@ -120,8 +146,6 @@ const CookieConsent = ({
|
|
|
120
146
|
};
|
|
121
147
|
|
|
122
148
|
CookieConsent.propTypes = {
|
|
123
|
-
acceptText: PropTypes.string,
|
|
124
|
-
rejectText: PropTypes.string,
|
|
125
149
|
showRejectButton: PropTypes.bool,
|
|
126
150
|
settingsCookie: PropTypes.bool,
|
|
127
151
|
cookieName: PropTypes.string,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-syntax */
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { render, cleanup } from '@testing-library/react';
|
|
3
4
|
import '@testing-library/jest-dom/extend-expect';
|
|
@@ -29,7 +30,6 @@ describe('Body', () => {
|
|
|
29
30
|
const { container } = renderComponent();
|
|
30
31
|
// all sections have their own test, we only need to test body renders without crash
|
|
31
32
|
expect(container).toBeTruthy();
|
|
32
|
-
expect(container.querySelector('.scrollToTop')).toBeTruthy();
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
35
|
afterEach(() => {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const cookiesContent = {
|
|
2
|
+
ignoreComponentChildren: false,
|
|
3
|
+
showRejectButton: false,
|
|
4
|
+
text: {
|
|
5
|
+
label:
|
|
6
|
+
'We use cookies in order to optimise our site and improve your experience with us. By using the site you consent to our [link-0].',
|
|
7
|
+
translationKey: 'cookie_consent_default_text',
|
|
8
|
+
},
|
|
9
|
+
links: [
|
|
10
|
+
{
|
|
11
|
+
url: '/cookies',
|
|
12
|
+
text: 'Cookie Policy',
|
|
13
|
+
translationKey: 'cookie_policy_link',
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
managePreferences: {
|
|
17
|
+
label: 'Cookie Setting',
|
|
18
|
+
translationKey: 'cookie_setting_button',
|
|
19
|
+
},
|
|
20
|
+
acceptButton: {
|
|
21
|
+
label: 'Accept',
|
|
22
|
+
translationKey: 'cookie_accept_button',
|
|
23
|
+
},
|
|
24
|
+
rejectButton: {
|
|
25
|
+
label: 'Reject',
|
|
26
|
+
translationKey: 'cookie_reject_button',
|
|
27
|
+
},
|
|
28
|
+
modal: {
|
|
29
|
+
title: {
|
|
30
|
+
label: 'Privacy Preference Center',
|
|
31
|
+
translationKey: 'privacy_preference_title',
|
|
32
|
+
},
|
|
33
|
+
description: {
|
|
34
|
+
label:
|
|
35
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nibh aliquam non sit morbi neque in sodales tellus. Cursus neque sed quis tincidunt sed vestibulum rhoncus dolor elementum. Imperdiet tortor dolor sit nisi, magnis cras id ut. Id dolor, vel neque lobortis. Diam commodo vitae vulputate at ultrices id odio praesent. Nisi, sit massa orci accumsan.',
|
|
36
|
+
translationKey: 'privacy_preference_text',
|
|
37
|
+
},
|
|
38
|
+
confirmButton: {
|
|
39
|
+
label: 'Confirm my choices',
|
|
40
|
+
translationKey: 'cookie_confirm_button',
|
|
41
|
+
},
|
|
42
|
+
acceptAllButton: {
|
|
43
|
+
label: 'Accept All Cookies',
|
|
44
|
+
translationKey: 'cookie_accept_all_button',
|
|
45
|
+
},
|
|
46
|
+
rejectNonNecessaryButton: {
|
|
47
|
+
label: 'I reject Non-Necessary',
|
|
48
|
+
translationKey: 'cookie_reject_nonnecessary_button',
|
|
49
|
+
},
|
|
50
|
+
manageConsentTitle: {
|
|
51
|
+
label: 'Manage Consent Preferences',
|
|
52
|
+
translationKey: 'menage_consent_preference',
|
|
53
|
+
},
|
|
54
|
+
closeAriaLabel: {
|
|
55
|
+
label: 'close cookie',
|
|
56
|
+
translationKey: 'ariaLabel-closeCookie',
|
|
57
|
+
},
|
|
58
|
+
categories: [
|
|
59
|
+
{
|
|
60
|
+
title: {
|
|
61
|
+
label: 'Neccesary',
|
|
62
|
+
translationKey: 'neccesary_cookie_title',
|
|
63
|
+
},
|
|
64
|
+
description: {
|
|
65
|
+
label:
|
|
66
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nibh aliquam non sit morbi neque in sodales tellus. Cursus neque sed quis tincidunt sed vestibulum rhoncus dolor elementum. Imperdiet tortor dolor sit nisi, magnis cras id ut. Id dolor, vel neque lobortis. Diam commodo vitae vulputate at ultrices id odio praesent. Nisi, sit massa orci accumsan.',
|
|
67
|
+
translationKey: 'neccesary_cookie_text',
|
|
68
|
+
},
|
|
69
|
+
hasToggle: false,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: {
|
|
73
|
+
label: 'Analytical And Stadistical',
|
|
74
|
+
translationKey: 'analytical_cookie_title',
|
|
75
|
+
},
|
|
76
|
+
description: {
|
|
77
|
+
label:
|
|
78
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nibh aliquam non sit morbi neque in sodales tellus. Cursus neque sed quis tincidunt sed vestibulum rhoncus dolor elementum. Imperdiet tortor dolor sit nisi, magnis cras id ut. Id dolor, vel neque lobortis. Diam commodo vitae vulputate at ultrices id odio praesent. Nisi, sit massa orci accumsan.',
|
|
79
|
+
translationKey: 'analytical_cookie_text',
|
|
80
|
+
},
|
|
81
|
+
hasToggle: true,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: {
|
|
85
|
+
label: 'Marketing',
|
|
86
|
+
translationKey: 'marketing_cookie_title',
|
|
87
|
+
},
|
|
88
|
+
description: {
|
|
89
|
+
label:
|
|
90
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nibh aliquam non sit morbi neque in sodales tellus. Cursus neque sed quis tincidunt sed vestibulum rhoncus dolor elementum. Imperdiet tortor dolor sit nisi, magnis cras id ut. Id dolor, vel neque lobortis. Diam commodo vitae vulputate at ultrices id odio praesent. Nisi, sit massa orci accumsan.',
|
|
91
|
+
translationKey: 'marketing_cookie_text',
|
|
92
|
+
},
|
|
93
|
+
hasToggle: true,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export default cookiesContent;
|
|
@@ -68,3 +68,23 @@ export function generateArray(obj) {
|
|
|
68
68
|
? Object.keys(obj).map((key) => obj[key])
|
|
69
69
|
: [];
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
export const parseCookieTextWithLinks = (
|
|
73
|
+
text,
|
|
74
|
+
translatedLinks = [],
|
|
75
|
+
renderLink
|
|
76
|
+
) =>
|
|
77
|
+
text.split(/(\[link-\d+\])/g).map((part, i) => {
|
|
78
|
+
const match = part.match(/^\[link-(\d+)\]$/);
|
|
79
|
+
|
|
80
|
+
if (!match) return part;
|
|
81
|
+
|
|
82
|
+
const linkIndex = Number(match[1]);
|
|
83
|
+
const link = translatedLinks[linkIndex];
|
|
84
|
+
|
|
85
|
+
if (!link) return part;
|
|
86
|
+
|
|
87
|
+
return renderLink(link, i);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export default parseCookieTextWithLinks;
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
generateTrackerLink,
|
|
3
3
|
generatePlaceholderString,
|
|
4
4
|
generateArray,
|
|
5
|
+
parseCookieTextWithLinks
|
|
5
6
|
} from "./generators.mjs";
|
|
6
7
|
import { months } from "~constants/common";
|
|
7
8
|
|
|
@@ -149,3 +150,54 @@ describe("Generate Array From Object", () => {
|
|
|
149
150
|
expect(output[1]).toEqual("b");
|
|
150
151
|
});
|
|
151
152
|
});
|
|
153
|
+
|
|
154
|
+
describe("Parse Cookie Text With Links", () => {
|
|
155
|
+
test("replaces indexed link placeholders with rendered links", () => {
|
|
156
|
+
const output = parseCookieTextWithLinks(
|
|
157
|
+
"Read our [link-0] and [link-1] for more details.",
|
|
158
|
+
[
|
|
159
|
+
{
|
|
160
|
+
url: "/cookies",
|
|
161
|
+
translatedText: "Cookie Policy",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
url: "/privacy-policy",
|
|
165
|
+
translatedText: "Privacy Policy",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
(link) => `[${link.translatedText}:${link.url}]`
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
expect(output).toEqual([
|
|
172
|
+
"Read our ",
|
|
173
|
+
"[Cookie Policy:/cookies]",
|
|
174
|
+
" and ",
|
|
175
|
+
"[Privacy Policy:/privacy-policy]",
|
|
176
|
+
" for more details.",
|
|
177
|
+
]);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("leaves text unchanged when placeholder link is missing", () => {
|
|
181
|
+
const output = parseCookieTextWithLinks(
|
|
182
|
+
"Read our [link-0] for more details.",
|
|
183
|
+
[],
|
|
184
|
+
(link) => `[${link.translatedText}:${link.url}]`
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
expect(output).toEqual([
|
|
188
|
+
"Read our ",
|
|
189
|
+
"[link-0]",
|
|
190
|
+
" for more details.",
|
|
191
|
+
]);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("returns plain text when there are no link placeholders", () => {
|
|
195
|
+
const output = parseCookieTextWithLinks(
|
|
196
|
+
"No links here.",
|
|
197
|
+
[{ url: "/cookies", translatedText: "Cookie Policy" }],
|
|
198
|
+
(link) => `[${link.translatedText}:${link.url}]`
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
expect(output).toEqual(["No links here."]);
|
|
202
|
+
});
|
|
203
|
+
});
|
package/src/resolver/modules.mjs
CHANGED
|
@@ -387,7 +387,7 @@ export function processTopListModule(
|
|
|
387
387
|
const itemsCount = +listItem.num_items_initial_load;
|
|
388
388
|
const toplistItem = toplists && listItem.id
|
|
389
389
|
? toplists[listItem.id.toString()] ||
|
|
390
|
-
|
|
390
|
+
toplists[`g_${listItem.id.toString()}`]
|
|
391
391
|
: undefined;
|
|
392
392
|
if (toplistItem) {
|
|
393
393
|
listItem.market = toplistItem.market?.short_code;
|
|
@@ -413,24 +413,24 @@ export function processTopListModule(
|
|
|
413
413
|
// build top list
|
|
414
414
|
listItem.items = listItem.items
|
|
415
415
|
? listItem.items
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
416
|
+
.filter(
|
|
417
|
+
(item) =>
|
|
418
|
+
Object.values(relations.operator).find(
|
|
419
|
+
(operator) =>
|
|
420
|
+
operator.operator_id === item.operator_id &&
|
|
421
|
+
operator.market === listItem.market &&
|
|
422
|
+
type === operator.type
|
|
423
|
+
) ||
|
|
424
|
+
Object.values(relations.game).find(
|
|
425
|
+
(game) => game.game_id === item.game_id
|
|
426
|
+
)
|
|
427
|
+
)
|
|
428
|
+
.map((item) => {
|
|
429
|
+
if (item.operator_id) return processOperatorToplist(item, ctx);
|
|
430
|
+
if (item.game_id) return processGameToplist(item, ctx);
|
|
431
|
+
return null;
|
|
432
|
+
})
|
|
433
|
+
.filter(Boolean)
|
|
434
434
|
: [];
|
|
435
435
|
const latestItems = listItem.items
|
|
436
436
|
.map((toplist) => ({
|
|
@@ -456,10 +456,10 @@ export function processTopListModule(
|
|
|
456
456
|
// eslint-disable-next-line no-restricted-globals
|
|
457
457
|
latestUpdatedDate instanceof Date && !isNaN(latestUpdatedDate)
|
|
458
458
|
? new Intl.DateTimeFormat("en-US", {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
year: "numeric",
|
|
460
|
+
month: "long",
|
|
461
|
+
day: "numeric",
|
|
462
|
+
}).format(latestUpdatedDate)
|
|
463
463
|
: null;
|
|
464
464
|
|
|
465
465
|
listItem.latest_items = formattedLatestItems;
|
|
@@ -513,15 +513,22 @@ export function shouldSavePrefilled(module = {}, siteName) {
|
|
|
513
513
|
);
|
|
514
514
|
}
|
|
515
515
|
|
|
516
|
-
export function processSpotlightModule(module = {}, content, previewPageID) {
|
|
517
|
-
module.
|
|
518
|
-
item
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
)
|
|
524
|
-
|
|
516
|
+
export function processSpotlightModule(module = {}, content, relations, ribbons, previewPageID) {
|
|
517
|
+
if (module.mode === "sport_odds") {
|
|
518
|
+
module.items.forEach((item) => {
|
|
519
|
+
item.relation = relations?.[item.page.relation_id];
|
|
520
|
+
item.page.ribbons = item.page.ribbon_ids.map((id) => ribbons?.[id]);
|
|
521
|
+
});
|
|
522
|
+
} else {
|
|
523
|
+
module.items.forEach((item) => {
|
|
524
|
+
item.content = trailingSlash(
|
|
525
|
+
previewPageID ? item.content : (content && content[item.content]) || ""
|
|
526
|
+
);
|
|
527
|
+
item.text = trailingSlash(
|
|
528
|
+
previewPageID ? item.text : (content && content[item.text]) || "",
|
|
529
|
+
);
|
|
530
|
+
});
|
|
531
|
+
}
|
|
525
532
|
|
|
526
533
|
return module;
|
|
527
534
|
}
|
|
@@ -542,23 +549,23 @@ export function processFaq(module = {}, content, relationData, previewPageID) {
|
|
|
542
549
|
previewPageID
|
|
543
550
|
? generatePlaceholderString(item.question, null, relationData)
|
|
544
551
|
: (content
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
552
|
+
? generatePlaceholderString(
|
|
553
|
+
content[item.question],
|
|
554
|
+
null,
|
|
555
|
+
relationData
|
|
556
|
+
)
|
|
557
|
+
: "") || ""
|
|
551
558
|
);
|
|
552
559
|
item.answer = trailingSlash(
|
|
553
560
|
previewPageID
|
|
554
561
|
? generatePlaceholderString(item.answer, null, relationData)
|
|
555
562
|
: (content &&
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
563
|
+
generatePlaceholderString(
|
|
564
|
+
content[item.answer],
|
|
565
|
+
null,
|
|
566
|
+
relationData
|
|
567
|
+
)) ||
|
|
568
|
+
""
|
|
562
569
|
);
|
|
563
570
|
});
|
|
564
571
|
}
|
|
@@ -599,13 +606,14 @@ export function processModule(
|
|
|
599
606
|
prefilledMarketModules,
|
|
600
607
|
previewPageID
|
|
601
608
|
) {
|
|
609
|
+
|
|
602
610
|
module.module_title =
|
|
603
611
|
module.module_title &&
|
|
604
612
|
generatePlaceholderString(module.module_title, translations, relationData);
|
|
605
613
|
module.title =
|
|
606
614
|
module.title &&
|
|
607
615
|
generatePlaceholderString(module.title, translations, relationData);
|
|
608
|
-
|
|
616
|
+
|
|
609
617
|
module.anchor_slug =
|
|
610
618
|
module.anchor_slug &&
|
|
611
619
|
generatePlaceholderString(module.anchor_slug, translations, relationData);
|
|
@@ -616,7 +624,7 @@ export function processModule(
|
|
|
616
624
|
module.module_introduction,
|
|
617
625
|
translations,
|
|
618
626
|
relationData,
|
|
619
|
-
);
|
|
627
|
+
);
|
|
620
628
|
|
|
621
629
|
// See more link
|
|
622
630
|
if (
|
|
@@ -663,7 +671,7 @@ export function processModule(
|
|
|
663
671
|
} else if (module.name === "anchor") {
|
|
664
672
|
processAnchor(module, relationData, translations);
|
|
665
673
|
} else if (module.name === "spotlights") {
|
|
666
|
-
processSpotlightModule(module, content, previewPageID);
|
|
674
|
+
processSpotlightModule(module, content, relations?.operator, data?.ribbons, previewPageID);
|
|
667
675
|
} else if (module.name === "menu" && menus && menus[module.menu_id]) {
|
|
668
676
|
module = Object.assign(module, menus[module.menu_id]);
|
|
669
677
|
} else if (module.name === "statistics_counter") {
|