gatsby-core-theme 44.24.1 → 44.25.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/.ci.yml CHANGED
@@ -36,6 +36,8 @@ Theme Publish:
36
36
  - yarn config set cache-folder .yarn
37
37
  - yarn
38
38
  - cd gatsby-theme/
39
+ - rm -rf /root/.npmrc /root/.npm
40
+ - npm cache clean --force
39
41
  - npx semantic-release@22.0.0 -b $CI_COMMIT_REF_NAME
40
42
  when: manual
41
43
  only:
package/CHANGELOG.md CHANGED
@@ -1,3 +1,30 @@
1
+ # [44.25.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.24.2...v44.25.0) (2026-05-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add ribbon from hercules on spotlight module ([2c751d3](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/2c751d3c97c06668ff53ba5e7616308cde00800a))
7
+ * resolver the burger menu issue on minimized screen ([5424878](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/54248783100f950a79509505e17e466beaee6d52))
8
+ * update ci yml ([4f152ca](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/4f152cab1cad735d4d003891c49012537fb0fbc3))
9
+
10
+
11
+ * Merge branch 'update-ci' into 'master' ([99888c5](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/99888c5cc0ad79a5e7409177088131048928c1d9))
12
+ * Merge branch 'en-397-burger-menu-issue' into 'master' ([1076c0b](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/1076c0b35a165bdc624eac186d1989da3b8b6fe4))
13
+ * Merge branch 'EN-533' into 'master' ([da87f4b](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/da87f4b7eb04d717660f562bb4a2e7e070e32925))
14
+ * Merge branch 'en-505-xff-tracking' into 'master' ([1af8d32](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/1af8d32658e6d0c4bf1bd17ff77853b584980470))
15
+
16
+
17
+ ### Features
18
+
19
+ * priorite xff ip if enabled ([20b1b71](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/20b1b719e33ce41c15a773c4fba1d381fed27510))
20
+
21
+ ## [44.24.2](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.24.1...v44.24.2) (2026-05-18)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * fix preview ([4884d10](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/4884d10f47c98c99cfdf100581ce25e76a62bf0b))
27
+
1
28
  ## [44.24.1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.24.0...v44.24.1) (2026-05-15)
2
29
 
3
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.24.1",
3
+ "version": "44.25.0",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -15,7 +15,6 @@ const Items = ({ item, menuListRef, orientation = 'horizontal', gtmClass = '', l
15
15
 
16
16
  const parentMenuRef = useRef(null);
17
17
  const subMenuListRef = useRef(null);
18
-
19
18
  const closeOtherMenus = (target) => {
20
19
  const parentsWithOpenSubMenu = target.parentNode.getElementsByClassName(styles.showSubMenu)[0];
21
20
  const openSubmenus = parentsWithOpenSubMenu?.getElementsByClassName(styles.show)[0];
@@ -46,6 +45,18 @@ const Items = ({ item, menuListRef, orientation = 'horizontal', gtmClass = '', l
46
45
  target.getElementsByTagName('UL')[0]?.classList.toggle(styles.show);
47
46
  };
48
47
 
48
+ const handleClick = (e) => {
49
+ if (typeof window === "undefined") return;
50
+
51
+ const isMobileView = window.innerWidth < 1199;
52
+
53
+ if (isMobileDevice() || isMobileView) {
54
+ if (e.defaultPrevented) return;
55
+ e.preventDefault();
56
+ onClick(e);
57
+ }
58
+ };
59
+
49
60
  if (item.children) {
50
61
  link = <Item item={item} gtmClass={gtmClass} orientation={orientation} active={currentPage === item.value} />;
51
62
  menu = (
@@ -83,18 +94,10 @@ const Items = ({ item, menuListRef, orientation = 'horizontal', gtmClass = '', l
83
94
  role="menuitem"
84
95
  tabIndex="0"
85
96
  onKeyDown={(e) => {
86
- if (isMobileDevice()) {
87
- if (e.defaultPrevented) return;
88
- e.preventDefault();
89
- onClick(e);
90
- }
97
+ handleClick(e);
91
98
  }}
92
99
  onClick={(e) => {
93
- if (isMobileDevice()) {
94
- if (e.defaultPrevented) return;
95
- e.preventDefault();
96
- onClick(e);
97
- }
100
+ handleClick(e)
98
101
  }}
99
102
  >
100
103
  {link}
@@ -0,0 +1,38 @@
1
+ import React from "react";
2
+ import PropTypes from "prop-types";
3
+ import useTranslate from "~hooks/useTranslate/useTranslate";
4
+ import FunIcon from "../../../../images/icons/funIcon";
5
+
6
+ export const FUNBET_TRANSLATION_KEY = "funbet";
7
+ export const FUNBET_DEFAULT_LABEL = "Funbet";
8
+
9
+ export function getRibbonTranslationKey(item) {
10
+ const label = item?.page?.ribbons?.[0]?.label;
11
+ return typeof label === "string" ? label.trim() : "";
12
+ }
13
+
14
+ export default function RibbonHeader({ item }) {
15
+ const ribbonKey = getRibbonTranslationKey(item);
16
+ const translationKey = ribbonKey || FUNBET_TRANSLATION_KEY;
17
+ const defaultValue = ribbonKey || FUNBET_DEFAULT_LABEL;
18
+ const label = useTranslate(translationKey, defaultValue);
19
+
20
+ return (
21
+ <>
22
+ <FunIcon />
23
+ <span>{label}</span>
24
+ </>
25
+ );
26
+ }
27
+
28
+ RibbonHeader.propTypes = {
29
+ item: PropTypes.shape({
30
+ page: PropTypes.shape({
31
+ ribbons: PropTypes.arrayOf(
32
+ PropTypes.shape({
33
+ label: PropTypes.string,
34
+ })
35
+ ),
36
+ }),
37
+ }),
38
+ };
@@ -5,7 +5,7 @@ import LazyImage from "~hooks/lazy-image";
5
5
  import Button from "../../../../atoms/button/operator-cta";
6
6
  import Tnc from '../../../tnc'
7
7
  import useTranslate from "~hooks/useTranslate/useTranslate";
8
- import FunIcon from "../../../../../images/icons/funIcon";
8
+ import RibbonHeader from "../ribbon-header";
9
9
  import styles from "./template-one.module.scss";
10
10
 
11
11
  const DEFAULT_CTA_TRANSLATE = {
@@ -33,7 +33,6 @@ export default function TemplateOne({
33
33
  const items = module?.items;
34
34
  const ctaText = module?.link_text;
35
35
  const date = useTranslate('date', 'Date:');
36
- const funbetLabel = useTranslate('funbet', 'Funbet');
37
36
 
38
37
  return (
39
38
  <div className={styles.sportOdds}>
@@ -58,10 +57,9 @@ export default function TemplateOne({
58
57
  <span className={styles.operatorIcon} aria-hidden="true" />
59
58
  )}
60
59
  {operatorName && <span>{operatorName}</span>}
61
- </> : <>
62
- <FunIcon />
63
- <span>{funbetLabel}</span>
64
- </>
60
+ </> : (
61
+ <RibbonHeader item={item} />
62
+ )
65
63
  }
66
64
  </div>
67
65
 
@@ -54,4 +54,18 @@ describe('Sport Odds TemplateOne Component', () => {
54
54
  const { container } = render(<TemplateOne module={module} />);
55
55
  expect(container.querySelectorAll('div').length).toBeGreaterThan(0);
56
56
  });
57
+
58
+ test('renders translated ribbon label when page ribbon exists', () => {
59
+ const module = buildModule();
60
+ module.items[0].page = {
61
+ ribbons: [{ label: ' fun bet ' }],
62
+ };
63
+ const { getByText } = render(<TemplateOne module={module} />);
64
+ expect(getByText('fun bet')).toBeInTheDocument();
65
+ });
66
+
67
+ test('falls back to Funbet label when ribbon label is missing', () => {
68
+ const { getAllByText } = render(<TemplateOne module={buildModule()} />);
69
+ expect(getAllByText('Funbet').length).toBeGreaterThan(0);
70
+ });
57
71
  });
@@ -8,7 +8,7 @@ import Button from "../../../../atoms/button/operator-cta";
8
8
  import Tnc from "../../../tnc";
9
9
  import ScrollX from "~hooks/scroll-x";
10
10
  import useTranslate from "~hooks/useTranslate/useTranslate";
11
- import FunIcon from "../../../../../images/icons/funIcon";
11
+ import RibbonHeader from "../ribbon-header";
12
12
  import styles from "./template-two.module.scss";
13
13
 
14
14
  const DEFAULT_CTA_TRANSLATE = {
@@ -43,7 +43,6 @@ export default function TemplateTwo({
43
43
  const items = module?.items;
44
44
  const ctaText = module?.link_text;
45
45
  const date = useTranslate('date', 'Date:');
46
- const funbetLabel = useTranslate('funbet', 'Funbet');
47
46
 
48
47
  const updateButtons = (shift) => {
49
48
  setScrollEnd(
@@ -110,10 +109,9 @@ export default function TemplateTwo({
110
109
  <span className={styles.operatorIcon} aria-hidden="true" />
111
110
  )}
112
111
  {operatorName && <span>{operatorName}</span>}
113
- </> : <>
114
- <FunIcon />
115
- <span>{funbetLabel}</span>
116
- </>
112
+ </> : (
113
+ <RibbonHeader item={item} />
114
+ )
117
115
  }
118
116
  </div>
119
117
 
@@ -54,4 +54,18 @@ describe('Sport Odds TemplateTwo Component', () => {
54
54
  const { container } = render(<TemplateTwo module={module} />);
55
55
  expect(container.querySelectorAll('div').length).toBeGreaterThan(0);
56
56
  });
57
+
58
+ test('renders translated ribbon label when page ribbon exists', () => {
59
+ const module = buildModule();
60
+ module.items[0].page = {
61
+ ribbons: [{ label: ' fun bet ' }],
62
+ };
63
+ const { getByText } = render(<TemplateTwo module={module} />);
64
+ expect(getByText('fun bet')).toBeInTheDocument();
65
+ });
66
+
67
+ test('falls back to Funbet label when ribbon label is missing', () => {
68
+ const { getAllByText } = render(<TemplateTwo module={buildModule()} />);
69
+ expect(getAllByText('Funbet').length).toBeGreaterThan(0);
70
+ });
57
71
  });
@@ -56,6 +56,7 @@ export function generatePlaceholderString(
56
56
  const month = String(date.getMonth() + 1).padStart(2, "0");
57
57
  const year = date.getFullYear();
58
58
  const regex = generatorsConstant.generatorsPlaceholderRegex;
59
+ if (string == null) return string;
59
60
  string = string.replace(/&#61;/g, "=");
60
61
 
61
62
  return string?.replace(regex, (match) => {
@@ -105,7 +105,12 @@ function extractUrlParams(url) {
105
105
 
106
106
  // Helper to construct URL parameters
107
107
  function buildUrlParams(operator, trackerName, headers, cookie, extraParams) {
108
- const ip = headers?.get("x-real-ip") || headers?.get("host") || "127.0.0.1";
108
+ const ip =
109
+ (process.env.TRUST_XFF === "true" &&
110
+ headers?.get("x-forwarded-for")?.split(",")[0].trim()) ||
111
+ headers?.get("x-real-ip") ||
112
+ headers?.get("host") ||
113
+ "127.0.0.1";
109
114
  const userAgent = headers?.get("user-agent") || null;
110
115
 
111
116
  const affObject = isJsonString(cookie.affObject)
@@ -177,7 +182,9 @@ export async function getAffiliateLink(operator, path, page, headers, url) {
177
182
 
178
183
  const contentType = res.headers.get("content-type");
179
184
  if (!contentType || !contentType.includes("application/json")) {
180
- console.error(`Tracking API returned non-JSON content-type: ${contentType}`);
185
+ console.error(
186
+ `Tracking API returned non-JSON content-type: ${contentType}`
187
+ );
181
188
  return { props: { success: false } };
182
189
  }
183
190
 
@@ -186,7 +193,10 @@ export async function getAffiliateLink(operator, path, page, headers, url) {
186
193
  const data = await res.json();
187
194
  return { props: data };
188
195
  } catch (jsonError) {
189
- console.error("Failed to parse tracking API response as JSON:", jsonError);
196
+ console.error(
197
+ "Failed to parse tracking API response as JSON:",
198
+ jsonError
199
+ );
190
200
  return { props: { success: false } };
191
201
  }
192
202
  } catch (error) {