gatsby-core-theme 44.0.27 → 44.0.29

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 CHANGED
@@ -1,3 +1,31 @@
1
+ ## [44.0.29](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.0.28...v44.0.29) (2025-05-02)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add max-height ([e6761ec](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e6761ec824947c1a2737c8445a55994a68f5d798))
7
+ * autocomplete ([8c6e7df](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/8c6e7dff541dcb2f881d069fa47acd4af267d9b1))
8
+ * extra-filed operator filter search ([a1a5519](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/a1a55199d87ccee533c41f794651680a5bcb838d))
9
+ * game cards need extra fields ([658caab](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/658caab2e01eb4f846e5894e8ebb1f067bac7d0c))
10
+ * jest ([022231d](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/022231dafd7b6e3a8b454cedeb3b3ed02b1a4278))
11
+ * logo on operator ([5658824](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/5658824db41998591596f3b9bc304dbb21419989))
12
+ * new structure search pick ([05e9106](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/05e9106a14d02605c27106951351a116a4be4cac))
13
+ * search icons ([2ef9a3f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/2ef9a3f3462f15531158a3c82752538e44bebd05))
14
+ * search json ([54019af](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/54019af88626c6b4fb265adab402a5351b50836b))
15
+ * update stats ([17aa455](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/17aa455826d426bcd8903f543ce1679860c85b62))
16
+
17
+
18
+ * Merge branch 'search-json' into 'master' ([710a55f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/710a55f0f922b0e986666e40315c4073d3908205))
19
+ * Merge branch 'tm-5424-update-sportsbook-value' into 'master' ([21a7d4a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/21a7d4a5affe9cab7608958fb7f9088fa8e46855))
20
+
21
+ ## [44.0.28](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.0.27...v44.0.28) (2025-04-25)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * sports relation kit bug ([de7f998](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/de7f998a91f2583548026d56325ab23fc834302c))
27
+ * sports relation kit bug ([53bcd9c](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/53bcd9c324355e1f3f0f570f526df44c4601e404))
28
+
1
29
  ## [44.0.27](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.0.26...v44.0.27) (2025-04-24)
2
30
 
3
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.0.27",
3
+ "version": "44.0.29",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -7,7 +7,7 @@ import { imagePrettyUrl } from '~helpers/getters';
7
7
  import styles from './game.module.scss';
8
8
 
9
9
  const Game = ({ item = {}, width = 56, height = 56, btnText = '', icon = <FaArrowRight title="Right-pointing Arrow Icon" /> }) => {
10
- const { relation } = item;
10
+ const { logo } = item;
11
11
 
12
12
  return (
13
13
  <li className={styles.row || ''}>
@@ -15,7 +15,7 @@ const Game = ({ item = {}, width = 56, height = 56, btnText = '', icon = <FaArro
15
15
  className={styles.gameImage}
16
16
  width={width}
17
17
  height={height}
18
- src={relation?.logo?.filename ? imagePrettyUrl(relation?.logo?.filename, width, height) : '/images/default-slot.jpg'}
18
+ src={logo ? imagePrettyUrl(logo, width, height) : '/images/default-slot.jpg'}
19
19
  alt={item.title}
20
20
  />
21
21
  <h3 className={styles.gameTitle}>{item.title}</h3>
@@ -7,17 +7,17 @@ import { imagePrettyUrl } from '~helpers/getters';
7
7
  import styles from './operator.module.scss';
8
8
 
9
9
  const Operator = ({ item = {}, width = 56, height = 56, btnText = '', icon = <FaArrowRight title="Right-pointing Arrow Icon" /> }) => {
10
- const { relation } = item;
10
+ const { logo } = item;
11
11
 
12
12
  return (
13
13
  <li className={styles.row || ''}>
14
- <LazyImage
14
+ {logo && <LazyImage
15
15
  className={styles.operatorImage}
16
16
  width={width}
17
17
  height={height}
18
- src={imagePrettyUrl(relation?.logo?.filename, width, height)}
18
+ src={imagePrettyUrl(logo, width, height)}
19
19
  alt={item.title}
20
- />
20
+ />}
21
21
  <h3 className={styles.operatorTitle}>{item.title}</h3>
22
22
  <Button
23
23
  to={item?.path}
@@ -9,14 +9,20 @@
9
9
  }
10
10
 
11
11
  .formInput {
12
- width: 100%;
13
- border: 1px solid;
14
- padding: 2.4rem;
15
- padding-left: 5rem;
16
- border-radius: 4rem;
12
+ width: 100%;
13
+ border: 1px solid;
14
+ padding: 2.4rem;
15
+ border-radius: 4rem;
16
+ padding-right: 6rem;
17
+ }
18
+
19
+ .searchButton {
20
+ position: absolute;
21
+ right: 2.4rem;
22
+ top: 2.5rem;
17
23
  }
18
24
 
19
25
  .noData {
20
26
  padding: 2.4rem;
21
27
  font-weight: bold;
22
- }
28
+ }
@@ -84,7 +84,7 @@ const SearchForm = ({
84
84
  setAutoCompleteLoading(true);
85
85
 
86
86
  try {
87
- autoCompleteData.current = autoCompleteData.current || await loadSource(market)
87
+ autoCompleteData.current = autoCompleteData.current || await loadSource(market, 'data-simple.json')
88
88
 
89
89
  setFilteredData(autoCompleteData.current.filter(item =>
90
90
  item.title.toLowerCase().includes(query.toLowerCase())
@@ -204,7 +204,7 @@ const SearchForm = ({
204
204
  }
205
205
  }}
206
206
  >
207
- {useTranslate('autocomplete_see_all', 'View more')} {type}
207
+ {useTranslate('autocomplete_see_all', 'View more')} {useTranslate(type, type)}
208
208
  </button>
209
209
  )}
210
210
 
@@ -0,0 +1,81 @@
1
+ /* eslint-disable camelcase */
2
+ import React from 'react';
3
+ import { render, screen, fireEvent, waitFor } from '@testing-library/react';
4
+ import '@testing-library/jest-dom/extend-expect';
5
+ import SearchForm from '.';
6
+
7
+ // Mock loadSource
8
+ jest.mock('../../../helpers/search-source', () => ({
9
+ // __esModule: true,
10
+ default: jest.fn().mockResolvedValue([
11
+ { title: 'Game One', pageType: 'game' },
12
+ { title: 'Article One', pageType: 'article' }
13
+ ])
14
+ }));
15
+
16
+ const mockPageContext = {
17
+ page: {
18
+ market: 'test_market',
19
+ template: 'main'
20
+ }
21
+ };
22
+
23
+ describe('SearchForm Component', () => {
24
+ afterEach(() => {
25
+ jest.clearAllMocks();
26
+ });
27
+
28
+ test('renders search button and hides input initially', () => {
29
+ render(<SearchForm pageContext={mockPageContext} />);
30
+ const button = screen.getByRole('button', { name: 'Search' });
31
+ expect(button).toBeInTheDocument();
32
+ expect(screen.queryByPlaceholderText('search')).not.toBeInTheDocument();
33
+ });
34
+
35
+ test('displays search input when button is clicked', () => {
36
+ render(<SearchForm pageContext={mockPageContext} />);
37
+ const button = screen.getByRole('button', { name: 'Search' });
38
+
39
+ fireEvent.click(button);
40
+
41
+ const input = screen.getByPlaceholderText('Search...');
42
+ expect(input).toBeInTheDocument();
43
+ });
44
+
45
+ test('shows grouped autocomplete results on input', async () => {
46
+ render(<SearchForm pageContext={mockPageContext} />);
47
+ fireEvent.click(screen.getByRole('button', { name: 'Search' }));
48
+
49
+ const input = screen.getByPlaceholderText('Search...');
50
+ fireEvent.keyUp(input, { target: { value: 'Game' } });
51
+
52
+
53
+ });
54
+
55
+
56
+
57
+ test('closes form when clicking outside', async () => {
58
+ render(
59
+ <div>
60
+ <SearchForm pageContext={mockPageContext} />
61
+ <div data-testid="outside">Outside</div>
62
+ </div>
63
+ );
64
+
65
+ fireEvent.click(screen.getByRole('button', { name: 'Search' }));
66
+ const input = screen.getByPlaceholderText('Search...');
67
+ expect(input).toBeInTheDocument();
68
+
69
+ fireEvent.mouseDown(screen.getByTestId('outside'));
70
+
71
+ await waitFor(() => {
72
+ expect(screen.queryByPlaceholderText('search')).not.toBeInTheDocument();
73
+ });
74
+ });
75
+
76
+
77
+ });
78
+
79
+
80
+
81
+
@@ -67,6 +67,8 @@
67
67
  .autoCompleteContainer {
68
68
  background-color: #fff;
69
69
  margin-top: 0.8rem;
70
+ max-height: 65rem;
71
+ overflow: auto;
70
72
  border-radius: 0.8rem;
71
73
  }
72
74
 
@@ -1,24 +1,91 @@
1
1
  /* eslint-disable import/prefer-default-export */
2
- export const searchReleationPickKeys = [
3
- 'bonuses',
4
- 'logo',
5
- 'path',
6
- 'short_name',
7
- 'status',
8
- "type",
9
- "selling_points",
10
- "support_types",
11
- "ribbons",
12
- "rating",
13
- 'name',
14
- "standardised_logo_filename_object",
15
- "game_provider",
16
- "average_rating",
17
- "first_rating",
18
- "second_rating",
19
- "third_rating",
20
- "fourth_rating",
21
- "extra_fields",
22
- 'rtp',
23
- 'volatility',
24
- ];
2
+
3
+ export const searchReleationPickKeys = {
4
+ page: [""],
5
+ operator: [
6
+ "name",
7
+ "logo",
8
+ "path",
9
+ "type",
10
+ "short_name",
11
+ "links",
12
+ "market",
13
+ "bonuses",
14
+ "status",
15
+ "selling_points",
16
+ "support_types",
17
+ "ribbons",
18
+ "rating",
19
+ "average_rating",
20
+ "first_rating",
21
+ "second_rating",
22
+ "third_rating",
23
+ "fourth_rating",
24
+ "extra_fields",
25
+ 'rtp',
26
+ 'volatility',
27
+ ],
28
+ game: [
29
+ "logo",
30
+ "name",
31
+ "type",
32
+ "rating",
33
+ "path",
34
+ "average_rating",
35
+ "first_rating",
36
+ "second_rating",
37
+ "third_rating",
38
+ "fourth_rating",
39
+ "extra_fields",
40
+ "status",
41
+ "game_provider",
42
+ "thumbnail_filename_object",
43
+ "standardised_logo_filename_object",
44
+ 'rtp',
45
+ 'volatility',
46
+ ],
47
+ article: ["type",],
48
+ author: [
49
+ "name",
50
+ "logo",
51
+ "type",
52
+ "image_object",
53
+ "author_title",
54
+ "image_alt",
55
+ "pages_count",
56
+ "biography",
57
+ "facebook_profile",
58
+ "instagram_profile",
59
+ "linkedin_profile",
60
+ "twitter_profile",
61
+ "tik_tok",
62
+ "personal_website"
63
+
64
+ ],
65
+ payment_method: [
66
+ "type",
67
+ "logo",
68
+ "name",
69
+ "rating",
70
+ "status",
71
+ "selling_points",
72
+ "average_rating",
73
+ "first_rating",
74
+ "second_rating",
75
+ "third_rating",
76
+ "fourth_rating",
77
+ ],
78
+ software_provider: [
79
+ "type",
80
+ "logo",
81
+ "name",
82
+ "rating",
83
+ "status",
84
+ "standardised_logo_filename_object",
85
+ "average_rating",
86
+ "first_rating",
87
+ "second_rating",
88
+ "third_rating",
89
+ "fourth_rating",
90
+ ]
91
+ }
@@ -0,0 +1 @@
1
+ {}
@@ -52,6 +52,7 @@ let menus = null;
52
52
  let prefilledMarketModules = null;
53
53
  let prefilledMarketModulesRaw = null;
54
54
 
55
+ const searchSimpleData = {};
55
56
  const searchData = {};
56
57
 
57
58
  export function processSitemapPages(pages, markets) {
@@ -242,13 +243,13 @@ export function getReadingTime(sections) {
242
243
  );
243
244
  }
244
245
 
245
- function processSearchData(data, fs) {
246
+ function processSearchData(data, fs, filename) {
246
247
  if (!fs) {
247
248
  return;
248
249
  }
249
250
 
250
251
  fs.writeFile(
251
- `./src/data/search/data.json`,
252
+ `./src/data/search/${filename}`,
252
253
  JSON.stringify(data, null, " "),
253
254
  (error) => {
254
255
  if (error) {
@@ -364,7 +365,10 @@ export default {
364
365
 
365
366
  prefilledMarketModules = data.prefilled_market_modules || {};
366
367
  prefilledMarketModulesRaw = cloneDeep(data.prefilled_market_modules);
368
+
369
+ searchSimpleData[market] = [];
367
370
  searchData[market] = [];
371
+
368
372
  Object.keys(transformedPages[market]).forEach((pageType) => {
369
373
  transformedPages[market][pageType].forEach((page, index) => {
370
374
  const translations = translationsData
@@ -474,31 +478,45 @@ export default {
474
478
 
475
479
  pagesMappedById[page.id] = page;
476
480
 
477
-
481
+
478
482
  // add search data
479
483
  if (searchTemplatesAcitve.includes(page.template) && searchEnabled) {
480
- const { title, path, status, type, relation, author } = transformedPages[market][pageType][index];
484
+ const { title, path, status, banner, type, relation, author, extra_fields } = transformedPages[market][pageType][index];
481
485
 
482
- const filteredRelation = filterRelation(relation, searchReleationPickKeys);
486
+ const filteredRelation = filterRelation(relation, searchReleationPickKeys[type]);
483
487
 
484
488
  const allowedAuthorRelationKeys = ['image', 'name'];
485
- const filteredAuthorRelation = filterRelation(author, allowedAuthorRelationKeys);
489
+ const filteredAuthorRelation = author && filterRelation(author, allowedAuthorRelationKeys);
490
+
491
+ const operatorExtraFileds = extra_fields?.operator && filterRelation(extra_fields?.operator, searchReleationPickKeys['operator']);
486
492
 
487
493
  const minimalPage = {
488
494
  title,
489
495
  pageType,
490
496
  path,
497
+ banner,
498
+ type,
491
499
  ...(relation?.short_name && { short_name: relation.short_name }),
492
- // ...(relation?.logo && { logo: relation.logo.filename }),
500
+ ...(relation?.logo && { logo: relation.logo.filename }),
493
501
  ...(relation?.game_id && { game_id: relation.game_id }),
494
- type,
495
- ...(filteredRelation && { relation: filteredRelation }),
496
- ...(filteredAuthorRelation && { author: filteredAuthorRelation }),
497
502
  };
498
503
 
499
- status === 'active' && searchData[page.market].push(
500
- cloneDeep(minimalPage)
501
- );
504
+ if (status === 'active') {
505
+ searchSimpleData[page.market].push(
506
+ cloneDeep(minimalPage)
507
+ );
508
+ searchData[page.market].push(
509
+ cloneDeep({
510
+ ...minimalPage,
511
+ ...(filteredRelation && { relation: filteredRelation }),
512
+ ...(filteredAuthorRelation && { author: filteredAuthorRelation }),
513
+ ...operatorExtraFileds && { extra_fields: {
514
+ operator: operatorExtraFileds
515
+ } },
516
+ })
517
+ );
518
+ }
519
+
502
520
  }
503
521
 
504
522
  const sectionList = postSectionsMap[page.relation_type];
@@ -596,7 +614,8 @@ export default {
596
614
  });
597
615
 
598
616
  if (searchEnabled) {
599
- processSearchData(searchData, fs);
617
+ processSearchData(searchSimpleData, fs, "data-simple.json");
618
+ processSearchData(searchData, fs, "data.json");
600
619
  }
601
620
 
602
621
  data.pages = transformedPages;
@@ -556,6 +556,11 @@ export function processModule(
556
556
  makeCount[page.template] = (makeCount[page.template] || 0) + 1;
557
557
  return makeCount;
558
558
  }, {});
559
+
560
+ pagesByTemplate.operatorTimesBonus =
561
+ (pagesByTemplate.operator_review || 0) *
562
+ (pagesByTemplate.free_bonuses || 0);
563
+
559
564
  module.stats = pagesByTemplate;
560
565
  } else if (module.name === "carousel") {
561
566
  processCarouselModule(module, content);
@@ -187,14 +187,16 @@ export const processSportsRelations = (
187
187
 
188
188
  // Optimization 2: Convert teams and team_kits to Maps if used frequently
189
189
  const teamsMap = new Map(Object.entries(teams));
190
+
190
191
  const teamKitsMap = new Map(
191
192
  Object.entries(data.relations.sports_data.team_kits)
192
193
  );
193
194
 
194
195
  if (tournament && tournament.teams) {
195
196
  tournament.teams.forEach((teamId) => {
196
- const team = teamsMap.get(teamId);
197
- const kit = teamKitsMap.get(team?.livegoals_v2_id);
197
+
198
+ const team = teamsMap.get(teamId.toString());
199
+ const kit = team?.livegoals_v2_id ? teamKitsMap.get(team?.livegoals_v2_id.toString()) : null;
198
200
 
199
201
  if (team && kit) {
200
202
  teamKits[team.livegoals_v2_id] = kit; // Shallow copy might be enough
@@ -1,4 +1,4 @@
1
- export default async function loadSource(market) {
1
+ export default async function loadSource(market, file = 'data.json') {
2
2
  // Search data source
3
- return import('../data/search/data.json').then((data) => data[market]);
3
+ return import(`../data/search/${file}`).then((data) => data[market]);
4
4
  }
@@ -3,7 +3,7 @@ import loadSource from './search-source';
3
3
 
4
4
  describe('Scroll test', () => {
5
5
  test('loadSource()', () => {
6
- const data = loadSource('id', ['title']);
6
+ const data = loadSource('id');
7
7
  expect(data).toBeInstanceOf(Promise);
8
8
  });
9
9
 
@@ -84,7 +84,7 @@ export async function getAPIData(page, url, headers, preview) {
84
84
  return { props: {} };
85
85
  }
86
86
 
87
- const results = await loadSource(page.market);
87
+ const results = await loadSource(page.market, "data.json");
88
88
  if (page.path.endsWith("/s") || page.path === "s") {
89
89
  let urlParams = null;
90
90
  if (url && url.split("?").length === 2) {