gatsby-core-theme 44.2.19 → 44.3.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/CHANGELOG.md CHANGED
@@ -1,3 +1,43 @@
1
+ # [44.3.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.2.20...v44.3.0) (2025-06-25)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * filters order ([78bae80](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/78bae801cd85a65cf30007997e7c8973d17d505a))
7
+ * notification time ([355d437](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/355d4373ae1d7636c70e3822f1be52f502143927))
8
+ * rm consoel logs ([9d02b9d](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/9d02b9d9808b904d53f4fb63ee72bb7c76bc52d6))
9
+ * rm old tests ([41d19a8](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/41d19a859a1d9a76e16aa19c374ab5e27f7f8557))
10
+ * sync with main ([dfcc323](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/dfcc323274e8578b9de12a04345ec77692c6ca6a))
11
+ * use filterOperators in processFilters ([c6745f1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/c6745f1c331746565a769bb3a77f77811f4febce))
12
+
13
+
14
+ * Merge branch 'tm-5525-toplist-filters' into 'master' ([e5b1468](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e5b1468a565a367351fe065d44592383ed1d31f0))
15
+ * Merge branch 'tm-5536-notifications-time' into 'master' ([48889f9](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/48889f94b175238fffac8fa91e88e5bf15f504f2))
16
+
17
+
18
+ ### Features
19
+
20
+ * build filters for enabled templates ([3d201c2](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/3d201c20fa5e1794b00a7522953d2ab195168bfb))
21
+ * build filters on top list ([908a65f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/908a65fbb2b6fcf6869fadce2e83d96267e2c29e))
22
+ * slice toplists on filters ([6074186](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/60741862f3bc6f9d30a107921a9c1866f9b1d7ac))
23
+ * split filter operators, remove promises ([55483bb](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/55483bbe76ed03673ce6feae7ed62bce6e8dda58))
24
+
25
+
26
+ ### Tests
27
+
28
+ * buildTopListFilter ([ab811e7](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/ab811e791e631c6fffb1cd76c05cdce36ec07987))
29
+ * process filters ([d396159](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/d396159e6789b86b63d14cd743f7838e9d6dd7e3))
30
+
31
+ ## [44.2.20](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.2.19...v44.2.20) (2025-06-24)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * typo ([68823f3](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/68823f353806c946ff9602e61f9046c77d6fcd1c))
37
+
38
+
39
+ * Merge branch 'fix-typo' into 'master' ([1cbb641](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/1cbb641c00625d0d84668bc74e6c8249cd06d5c3))
40
+
1
41
  ## [44.2.19](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.2.18...v44.2.19) (2025-06-24)
2
42
 
3
43
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.2.19",
3
+ "version": "44.3.0",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -71,7 +71,8 @@ export default function FloatingArea({
71
71
 
72
72
  return (
73
73
  <div className={`${styles.floatingArea} ${showScroll ? styles.show : ""}`}>
74
- {pageTypes?.[pageTemplate]?.showScrollToTop || pageTypes.default?.showScrollToTop && <ScrollToTop />}
74
+ {(pageTypes?.[pageTemplate]?.showScrollToTop ||
75
+ pageTypes.default?.showScrollToTop) && <ScrollToTop />}
75
76
  {OperatorBanner && (
76
77
  <Suspense fallback={<></>}>
77
78
  <OperatorBanner
@@ -87,27 +88,26 @@ export default function FloatingArea({
87
88
  </Suspense>
88
89
  )}
89
90
 
90
- {CookieConsent &&
91
- showCookies && (
92
- <CookieConsent
93
- market={pageContext?.page?.market}
94
- type={pageType}
95
- template={template}
96
- settingsCookie
97
- isPageHomepage={isPageHomepage}
98
- >
99
- {
100
- customCookieContent || <p>
101
- We use cookies in order to optimise our site and improve your
102
- experience with us. By using the site you consent to our
103
- <a href="/cookies" className="cookie-consent-gtm">
104
- Cookie Policy
105
- </a>
106
- .
107
- </p>
108
- }
109
- </CookieConsent>
110
- )}
91
+ {CookieConsent && showCookies && (
92
+ <CookieConsent
93
+ market={pageContext?.page?.market}
94
+ type={pageType}
95
+ template={template}
96
+ settingsCookie
97
+ isPageHomepage={isPageHomepage}
98
+ >
99
+ {customCookieContent || (
100
+ <p>
101
+ We use cookies in order to optimise our site and improve your
102
+ experience with us. By using the site you consent to our
103
+ <a href="/cookies" className="cookie-consent-gtm">
104
+ Cookie Policy
105
+ </a>
106
+ .
107
+ </p>
108
+ )}
109
+ </CookieConsent>
110
+ )}
111
111
  {FooterNavigation && (
112
112
  <Suspense fallback={<></>}>
113
113
  <FooterNavigation section={footerNavigationData} />
@@ -30,14 +30,14 @@ export function formatDate(date, format, separator = '/', market = 'en-GB') {
30
30
  }
31
31
 
32
32
  export const getTimeAgo = (dateString) => {
33
- const date = new Date(dateString.includes('Z') ? dateString : `${dateString.replace(" ", "T")}Z`);
34
- const now = new Date(new Date().toISOString().slice(0, 19));
33
+ const date = new Date(dateString.replace(" ", "T")); // Make it ISO-compliant
34
+ const now = new Date();
35
35
 
36
- const diffMs = now.getTime() - date.getTime();
37
- const diffMinutes = Math.floor(diffMs / (1000 * 60));
38
- const diffHours = Math.floor(diffMinutes / 60);
39
- const diffDays = Math.floor(diffHours / 24);
40
- const diffMonths = Math.floor(diffDays / 30);
36
+ const diffMs = now.getTime() - date.getTime();
37
+ const diffMinutes = Math.floor(diffMs / (1000 * 60));
38
+ const diffHours = Math.floor(diffMinutes / 60);
39
+ const diffDays = Math.floor(diffHours / 24);
40
+ const diffMonths = Math.floor(diffDays / 30);
41
41
 
42
42
  if (diffDays >= 32) {
43
43
  return { value: diffMonths, key: diffMonths === 1 ? "month_ago" : "months_ago" };
@@ -49,4 +49,4 @@ export const getTimeAgo = (dateString) => {
49
49
  return { value: diffHours, key: diffHours === 1 ? "hour_ago" : "hours_ago" };
50
50
  }
51
51
  return { value: diffMinutes, key: diffMinutes === 1 ? "minute_ago" : "minutes_ago" };
52
- };
52
+ };
@@ -10,16 +10,16 @@ describe('Date-Time Helper', () => {
10
10
 
11
11
 
12
12
  test('getTimeAgo()', () => {
13
- const nowUTC = new Date(new Date().toISOString().slice(0, 19));
13
+ const now = new Date();
14
14
 
15
- const minutesAgo = new Date(nowUTC.getTime() - 5 * 60 * 1000).toISOString().slice(0, 19); // 5 mins ago
16
- const hoursAgo = new Date(nowUTC.getTime() - 2 * 60 * 60 * 1000).toISOString().slice(0, 19); // 2 hours ago
17
- const daysAgo = new Date(nowUTC.getTime() - 10 * 24 * 60 * 60 * 1000).toISOString().slice(0, 19); // 10 days ago
18
- const monthsAgo = new Date(nowUTC.getTime() - 65 * 24 * 60 * 60 * 1000).toISOString().slice(0, 19); // ~2 months ago
15
+ const minutesAgo = new Date(now.getTime() - 5 * 60 * 1000).toISOString(); // 5 minutes ago
16
+ const hoursAgo = new Date(now.getTime() - 2 * 60 * 60 * 1000).toISOString(); // 2 hours ago
17
+ const daysAgo = new Date(now.getTime() - 10 * 24 * 60 * 60 * 1000).toISOString(); // 10 days ago
18
+ const monthsAgo = new Date(now.getTime() - 65 * 24 * 60 * 60 * 1000).toISOString(); // ~2 months ago
19
19
 
20
- expect(getTimeAgo(minutesAgo)).toMatchObject({ key: 'minutes_ago', value: 5 });
21
- expect(getTimeAgo(hoursAgo)).toMatchObject({ key: 'hours_ago', value: 2 });
22
- expect(getTimeAgo(daysAgo)).toMatchObject({ key: 'days_ago', value: 10 });
23
- expect(getTimeAgo(monthsAgo)).toMatchObject({ key: 'months_ago', value: 2 });
24
- });
20
+ expect(getTimeAgo(minutesAgo)).toMatchObject({ key: 'minutes_ago', value: 5 });
21
+ expect(getTimeAgo(hoursAgo)).toMatchObject({ key: 'hours_ago', value: 2 });
22
+ expect(getTimeAgo(daysAgo)).toMatchObject({ key: 'days_ago', value: 10 });
23
+ expect(getTimeAgo(monthsAgo)).toMatchObject({ key: 'months_ago', value: 2 });
24
+ });
25
25
  });
@@ -0,0 +1,66 @@
1
+ function buildToplistFilter(pageFilters, operator) {
2
+ const addToFilter = (category, key, operatorId) => {
3
+ if (!category[key]) category[key] = { items: [] };
4
+ category[key].items.push(operatorId);
5
+ };
6
+ const operatorId = operator.id;
7
+ const rating = Math.floor(operator.rating);
8
+
9
+ // Rating filters
10
+ if (rating >= 1 && rating <= 5) {
11
+ pageFilters.rating[rating].items.push(operatorId);
12
+
13
+ // Best online casinos (5-star ratings)
14
+ if (rating === 5) {
15
+ pageFilters.popular_filters.best_online.items.push(operatorId);
16
+ }
17
+ }
18
+
19
+ // Deposit methods
20
+ operator.deposit_methods?.forEach((method) => {
21
+ addToFilter(pageFilters.deposit_methods, method.name, operatorId);
22
+
23
+ // Crypto filter
24
+ if (method.name.toLowerCase() === "cryptocurrency") {
25
+ pageFilters.popular_filters.crypto.items.push(operatorId);
26
+ }
27
+ });
28
+
29
+ // Withdrawal methods
30
+ operator.withdrawal_method?.forEach((method) => {
31
+ addToFilter(pageFilters.withdrawal_method, method.name, operatorId);
32
+ });
33
+
34
+ // Game categories
35
+ operator.game_categories?.forEach((category) => {
36
+ addToFilter(pageFilters.game_categories, category, operatorId);
37
+ });
38
+
39
+ // Licenses
40
+ operator.license_objects?.forEach((license) => {
41
+ addToFilter(pageFilters.licenses, license.name, operatorId);
42
+ });
43
+
44
+ // Payout time
45
+ if (operator.payout_time) {
46
+ addToFilter(pageFilters.payout_time, operator.payout_time, operatorId);
47
+ }
48
+
49
+ // Payout rate
50
+ const payoutRatio = operator.extra_fields?.payoutRatio;
51
+ if (payoutRatio) {
52
+ addToFilter(pageFilters.payout_rate, payoutRatio, operatorId);
53
+ }
54
+
55
+ // Mobile optimized
56
+ if (operator.extra_fields?.mobile_optimized) {
57
+ pageFilters.popular_filters.mobile_optimized.items.push(operatorId);
58
+ }
59
+
60
+ // Best live casino
61
+ if (operator.extra_fields?.best_live_casino) {
62
+ pageFilters.popular_filters.best_live.items.push(operatorId);
63
+ }
64
+ }
65
+
66
+ export default buildToplistFilter;
@@ -0,0 +1,104 @@
1
+ import buildToplistFilter from "./build-toplist-filter.mjs";
2
+
3
+ describe("buildToplistFilter", () => {
4
+ let pageFilters;
5
+ let operator;
6
+
7
+ beforeEach(() => {
8
+ pageFilters = {
9
+ rating: {
10
+ 1: { items: [] },
11
+ 2: { items: [] },
12
+ 3: { items: [] },
13
+ 4: { items: [] },
14
+ 5: { items: [] },
15
+ },
16
+ popular_filters: {
17
+ best_online: { items: [] },
18
+ crypto: { items: [] },
19
+ mobile_optimized: { items: [] },
20
+ best_live: { items: [] },
21
+ },
22
+ deposit_methods: {},
23
+ withdrawal_method: {},
24
+ game_categories: {},
25
+ licenses: {},
26
+ payout_time: {},
27
+ payout_rate: {},
28
+ };
29
+
30
+ operator = {
31
+ id: "operator1",
32
+ rating: 5,
33
+ deposit_methods: [{ name: "Cryptocurrency" }, { name: "Credit Card" }],
34
+ withdrawal_method: [{ name: "Bank Transfer" }],
35
+ game_categories: ["Slots", "Poker"],
36
+ license_objects: [{ name: "License A" }],
37
+ payout_time: "24 hours",
38
+ extra_fields: {
39
+ payoutRatio: "95%",
40
+ mobile_optimized: true,
41
+ best_live_casino: true,
42
+ },
43
+ };
44
+ });
45
+
46
+ it("should add operator to the correct rating filter", () => {
47
+ buildToplistFilter(pageFilters, operator);
48
+ expect(pageFilters.rating[5].items).toContain("operator1");
49
+ expect(pageFilters.popular_filters.best_online.items).toContain(
50
+ "operator1"
51
+ );
52
+ });
53
+
54
+ it("should add operator to the deposit methods and crypto filter", () => {
55
+ buildToplistFilter(pageFilters, operator);
56
+ expect(pageFilters.deposit_methods.Cryptocurrency.items).toContain(
57
+ "operator1"
58
+ );
59
+ expect(pageFilters.deposit_methods["Credit Card"].items).toContain(
60
+ "operator1"
61
+ );
62
+ expect(pageFilters.popular_filters.crypto.items).toContain("operator1");
63
+ });
64
+
65
+ it("should add operator to the withdrawal methods", () => {
66
+ buildToplistFilter(pageFilters, operator);
67
+ expect(pageFilters.withdrawal_method["Bank Transfer"].items).toContain(
68
+ "operator1"
69
+ );
70
+ });
71
+
72
+ it("should add operator to the game categories", () => {
73
+ buildToplistFilter(pageFilters, operator);
74
+ expect(pageFilters.game_categories.Slots.items).toContain("operator1");
75
+ expect(pageFilters.game_categories.Poker.items).toContain("operator1");
76
+ });
77
+
78
+ it("should add operator to the licenses", () => {
79
+ buildToplistFilter(pageFilters, operator);
80
+ expect(pageFilters.licenses["License A"].items).toContain("operator1");
81
+ });
82
+
83
+ it("should add operator to the payout time filter", () => {
84
+ buildToplistFilter(pageFilters, operator);
85
+ expect(pageFilters.payout_time["24 hours"].items).toContain("operator1");
86
+ });
87
+
88
+ it("should add operator to the payout rate filter", () => {
89
+ buildToplistFilter(pageFilters, operator);
90
+ expect(pageFilters.payout_rate["95%"].items).toContain("operator1");
91
+ });
92
+
93
+ it("should add operator to the mobile optimized filter", () => {
94
+ buildToplistFilter(pageFilters, operator);
95
+ expect(pageFilters.popular_filters.mobile_optimized.items).toContain(
96
+ "operator1"
97
+ );
98
+ });
99
+
100
+ it("should add operator to the best live casino filter", () => {
101
+ buildToplistFilter(pageFilters, operator);
102
+ expect(pageFilters.popular_filters.best_live.items).toContain("operator1");
103
+ });
104
+ });
@@ -113,21 +113,20 @@ export function transform(response) {
113
113
  Object.keys(pages[market][pageType]).forEach((pageId) => {
114
114
  const page = pages[market][pageType][pageId];
115
115
  if (
116
- mainSettings[page.relation_type] && mainSettings[page.relation_type].reading_time &&
116
+ mainSettings[page.relation_type] &&
117
+ mainSettings[page.relation_type].reading_time &&
117
118
  mainSettings[page.relation_type].reading_time[
118
119
  process.env.GATSBY_SITE_NAME
119
120
  ]
120
121
  ) {
121
122
  page.reading_time = getReadingTime(page.sections, response.content);
122
123
  }
123
-
124
124
 
125
125
  if (response.site_markets[siteMarket].path_prefix && page) {
126
126
  // set page prefix for multiple markets
127
127
  page.path = `${response.site_markets[siteMarket].path_prefix}${
128
128
  page.path !== "/" ? `/${page.path}` : ""
129
129
  }`;
130
-
131
130
  transformed[siteMarket][pageType].push(page);
132
131
  } else if (page) {
133
132
  transformed[siteMarket][pageType].push(page);
@@ -178,13 +177,19 @@ export function processSections(
178
177
  shouldSavePrefilled(module, siteName) &&
179
178
  savedModules[module.module_value_id]
180
179
  ) {
181
- const filteredModule = cloneDeep(savedModules[module.module_value_id]);
180
+ const filteredModule = cloneDeep(
181
+ savedModules[module.module_value_id]
182
+ );
182
183
 
183
184
  const relationID = pagesMappedById[pageId]?.relation_id;
184
- if (filteredModule.name === 'cards_v2' &&
185
- relationID && filteredModule.items
185
+ if (
186
+ filteredModule.name === "cards_v2" &&
187
+ relationID &&
188
+ filteredModule.items
186
189
  ) {
187
- filteredModule.items = filteredModule.items.filter((item) => !item.relation || item.relation.id !== relationID);
190
+ filteredModule.items = filteredModule.items.filter(
191
+ (item) => !item.relation || item.relation.id !== relationID
192
+ );
188
193
  }
189
194
 
190
195
  Object.assign(module, filteredModule);
@@ -195,13 +200,12 @@ export function processSections(
195
200
  module = {
196
201
  ...cloneDeep(
197
202
  prefilledMarketModules[module.module_value_id] ||
198
- prefilledMarketModules[module.value_id]
203
+ prefilledMarketModules[module.value_id]
199
204
  ),
200
205
  value_type: ModuleValue.VALUE_TYPE_PREFILLED_MODULE_MARKET,
201
206
  };
202
207
  }
203
208
 
204
-
205
209
  processModule(
206
210
  module,
207
211
  pages,
@@ -239,7 +243,10 @@ export function getReadingTime(sections, content) {
239
243
  sections[sectionKey].modules.forEach((module) => {
240
244
  // calculate reading time
241
245
  if (module.name === "content") {
242
- const nrOfWords = removeTags(content ? content[module.value] : module.value).split(" ").length / 250;
246
+ const nrOfWords =
247
+ removeTags(content ? content[module.value] : module.value).split(
248
+ " "
249
+ ).length / 250;
243
250
  const minPerModule = Math.floor(nrOfWords);
244
251
  const secPerModule = Math.floor((nrOfWords % 1) * 60);
245
252
 
@@ -277,7 +284,7 @@ function processSearchData(data, fs, filename) {
277
284
  if (error) {
278
285
  console.log(
279
286
  chalk.magenta("info") +
280
- chalk.whiteBright(` Error writing search json file : ${error}`)
287
+ chalk.whiteBright(` Error writing search json file : ${error}`)
281
288
  );
282
289
  }
283
290
  }
@@ -316,7 +323,6 @@ export function processExtraFields(
316
323
  }
317
324
 
318
325
  function updatePlaceholders(page, data, translationsData) {
319
-
320
326
  page.title =
321
327
  page.title &&
322
328
  generatePlaceholderString(page.title, translationsData, {
@@ -328,21 +334,21 @@ function updatePlaceholders(page, data, translationsData) {
328
334
  page.meta_title &&
329
335
  generatePlaceholderString(page.meta_title, translationsData, {
330
336
  siteName: data.site_name,
331
- pageTitle: page.title
337
+ pageTitle: page.title,
332
338
  });
333
339
 
334
340
  page.meta_description =
335
341
  page.meta_description &&
336
342
  generatePlaceholderString(page.meta_description, translationsData, {
337
343
  siteName: data.site_name,
338
- pageTitle: page.title
344
+ pageTitle: page.title,
339
345
  });
340
346
  }
341
347
 
342
348
  export default {
343
349
  run(data, themeOptions, fs, translationsData, previewPageID = null) {
344
350
  const start = new Date();
345
- const transformedPages = transform(data);
351
+ const transformedPages = transform(data);
346
352
 
347
353
  const allResponsibleGaming = data.responsible_gamings || null;
348
354
  const generalData = data.general;
@@ -365,12 +371,11 @@ export default {
365
371
 
366
372
  const searchEnabled =
367
373
  themeOptions.searchEnabled !== undefined &&
368
- themeOptions.searchEnabled !== null
374
+ themeOptions.searchEnabled !== null
369
375
  ? themeOptions.searchEnabled
370
376
  : true;
371
377
 
372
378
  menus = data.menus;
373
-
374
379
  // Menu changes when there is a path prefix configured on hercules
375
380
  Object.keys(menus).forEach((menu) => {
376
381
  if (data?.site_markets[menus[menu]?.market]?.path_prefix !== null) {
@@ -380,7 +385,6 @@ export default {
380
385
  );
381
386
  }
382
387
  });
383
-
384
388
  Object.keys(data.site_markets).forEach((market) => {
385
389
  relations = data.relations;
386
390
  pages = transformedPages[market];
@@ -393,10 +397,12 @@ export default {
393
397
 
394
398
  Object.keys(transformedPages[market]).forEach((pageType) => {
395
399
  transformedPages[market][pageType].forEach((page, index) => {
400
+ // Check if it should build fuilters for this template
396
401
  const translations = translationsData
397
402
  ? translationsData[page.language]
398
403
  : {};
399
404
  // process page extra fields
405
+ //
400
406
  page.extra_fields &&
401
407
  processExtraFields(
402
408
  page.extra_fields,
@@ -404,7 +410,6 @@ export default {
404
410
  relations,
405
411
  data.content
406
412
  );
407
-
408
413
  updatePlaceholders(page, generalData, translations);
409
414
 
410
415
  // Set Affiliate relations
@@ -528,7 +533,7 @@ export default {
528
533
  extra_fields?.operator &&
529
534
  filterRelation(
530
535
  extra_fields?.operator,
531
- searchReleationPickKeys.operator
536
+ searchReleationPickKeys?.operator
532
537
  );
533
538
 
534
539
  const minimalPage = {
@@ -549,12 +554,14 @@ export default {
549
554
  cloneDeep({
550
555
  ...minimalPage,
551
556
  ...(filteredRelation && { relation: filteredRelation }),
552
- ...(filteredAuthorRelation && { author: filteredAuthorRelation }),
553
- ...operatorExtraFileds && {
557
+ ...(filteredAuthorRelation && {
558
+ author: filteredAuthorRelation,
559
+ }),
560
+ ...(operatorExtraFileds && {
554
561
  extra_fields: {
555
- operator: operatorExtraFileds
556
- }
557
- },
562
+ operator: operatorExtraFileds,
563
+ },
564
+ }),
558
565
  })
559
566
  );
560
567
  }
@@ -575,7 +582,6 @@ export default {
575
582
  const postSectionModules =
576
583
  data.market_sections[market][res].modules || [];
577
584
  postSectionModules.forEach((item) => {
578
-
579
585
  if (!page.sections.main) {
580
586
  return;
581
587
  }
@@ -590,7 +596,6 @@ export default {
590
596
  ModuleValue.VALUE_TYPE_PREFILLED_MODULE_MARKET,
591
597
  });
592
598
  } else {
593
-
594
599
  if (
595
600
  transformedPages[market][pageType][index].relation &&
596
601
  checkForInactiveOperatorToplist(
@@ -611,7 +616,6 @@ export default {
611
616
  });
612
617
  });
613
618
 
614
-
615
619
  // fill market sections
616
620
  if (data.market_sections[market]) {
617
621
  data.market_sections[market] = processSections(
@@ -626,7 +630,7 @@ export default {
626
630
  data.content
627
631
  );
628
632
  }
629
-
633
+
630
634
  // fill page sections
631
635
  if (transformedPages[market]) {
632
636
  Object.keys(transformedPages[market]).forEach((pageType) => {
@@ -637,7 +641,6 @@ export default {
637
641
  (page.sections && !previewPageID) ||
638
642
  (previewPageID && page.id === previewPageID)
639
643
  ) {
640
-
641
644
  transformedPages[market][pageType][index] = Object.assign(page, {
642
645
  sections: processSections(
643
646
  page.sections,
@@ -15,7 +15,12 @@ import {
15
15
  import { sanitizeOperatorData } from "./operators.mjs";
16
16
  import settings from "../constants/settings.mjs";
17
17
  import ModuleValue from "../constants/module-value.mjs";
18
- import { shiftFirstOperator, getModuleTitle, trailingSlash } from "../helpers/getters.mjs";
18
+ import {
19
+ shiftFirstOperator,
20
+ getModuleTitle,
21
+ trailingSlash,
22
+ } from "../helpers/getters.mjs";
23
+ import buildToplistFilter from "./build-toplist-filter.mjs";
19
24
 
20
25
  const pagesGroupedByTemplateId = [];
21
26
  const cardItems = {};
@@ -185,7 +190,7 @@ export function processCardsV2(
185
190
  // Populate pagesList if page type and template exists
186
191
  pagesList =
187
192
  !pagesGroupedByTemplateId[`${cardType}_${market}`] ||
188
- !pagesGroupedByTemplateId[`${cardType}_${market}`][pageTemplateId]
193
+ !pagesGroupedByTemplateId[`${cardType}_${market}`][pageTemplateId]
189
194
  ? []
190
195
  : pagesGroupedByTemplateId[`${cardType}_${market}`][pageTemplateId];
191
196
  } else {
@@ -277,7 +282,6 @@ export function processCardsV2(
277
282
  }
278
283
  }
279
284
 
280
-
281
285
  if (styleName !== "comparison_table") {
282
286
  const relationID = pagesMappedById[pageId]?.relation_id;
283
287
 
@@ -288,7 +292,6 @@ export function processCardsV2(
288
292
  }
289
293
  }
290
294
 
291
-
292
295
  if (
293
296
  styleName === "comparison_table" &&
294
297
  pageId !== null &&
@@ -303,7 +306,8 @@ export function processCardsV2(
303
306
  }
304
307
 
305
308
  // modify page so it doesn't have too much data
306
- module.items = module.items.map((item) => clonePageForCards(cloneDeep(item), module.style, content)
309
+ module.items = module.items.map((item) =>
310
+ clonePageForCards(cloneDeep(item), module.style, content)
307
311
  );
308
312
  }
309
313
 
@@ -328,19 +332,33 @@ export function processTopListModule(
328
332
  data,
329
333
  toplists
330
334
  ) {
335
+ const filterEnabled = module.style === "filter";
336
+ const filters = {
337
+ popular_filters: {
338
+ best_online: { items: [] },
339
+ crypto: { items: [] },
340
+ mobile_optimized: { items: [] },
341
+ best_live: { items: [] },
342
+ },
343
+ rating: {
344
+ 1: { items: [] },
345
+ 2: { items: [] },
346
+ 3: { items: [] },
347
+ 4: { items: [] },
348
+ 5: { items: [] },
349
+ },
350
+ game_categories: {},
351
+ deposit_methods: {},
352
+ withdrawal_method: {},
353
+ payout_time: {},
354
+ payout_rate: {},
355
+ licenses: {},
356
+ };
357
+
331
358
  module.items = module.items.map((listItem) => {
332
359
  const { type } = listItem;
333
- const showLoadMore = listItem.show_load_more || 0;
334
- const itemsCount = listItem.num_items_initial_load
335
- ? Number(listItem.num_items_initial_load)
336
- : 0;
337
-
338
- if (showLoadMore === 0 && itemsCount > 0) {
339
- listItem.items = listItem.items
340
- ? listItem.items.slice(0, itemsCount)
341
- : [];
342
- }
343
-
360
+ const showLoadMore = +listItem.show_load_more;
361
+ const itemsCount = +listItem.num_items_initial_load;
344
362
  if (listItem.id && toplists && toplists[listItem.id.toString()]) {
345
363
  listItem.market = toplists[listItem.id].market?.short_code;
346
364
  listItem.items = toplists[listItem.id].items;
@@ -348,74 +366,84 @@ export function processTopListModule(
348
366
  listItem.tracker = toplists[listItem.id].tracker;
349
367
  }
350
368
 
369
+ if (!showLoadMore && itemsCount) {
370
+ listItem.items = listItem.items?.slice(0, itemsCount);
371
+ }
372
+
351
373
  listItem.items = listItem.items
352
374
  ? listItem.items.map((item) => {
353
- const operatorRelation = cloneDeep(
354
- Object.values(relations.operator).find(
355
- (operator) =>
356
- operator.operator_id === item.operator_id &&
357
- operator.market === listItem.market &&
358
- type === operator.type
359
- )
360
- );
361
-
362
- if (operatorRelation) {
363
- operatorRelation.ribbons =
364
- item.ribbon_ids && item.ribbon_ids.length === 0
365
- ? operatorRelation.ribbons
366
- : item.ribbon_ids;
367
-
368
- operatorRelation.selling_points =
369
- item.selling_points && item.selling_points.length === 0
370
- ? operatorRelation.selling_points
371
- : item.selling_points;
372
- }
373
-
374
- operatorRelation.updated_at = item.updated_at;
375
- operatorRelation.toplist_bonus = item.bonus_name;
376
-
377
- const operatorPage =
378
- pages && pages.operator && operatorRelation
379
- ? pages.operator.filter(
380
- (page) =>
381
- page.relation &&
382
- page.relation.operator_id ===
383
- operatorRelation.operator_id &&
384
- page.relation.type === operatorRelation.type
375
+ const operatorRelation = cloneDeep(
376
+ Object.values(relations.operator).find(
377
+ (operator) =>
378
+ operator.operator_id === item.operator_id &&
379
+ operator.market === listItem.market &&
380
+ type === operator.type
385
381
  )
386
- : [];
387
-
388
- const reviewLink =
389
- process.env.DMS_REVIEW_LINKS_ENABLED === 'true'
390
- ? stripDomainAndLeadingSlash(operatorRelation?.review_link) || operatorPage[0]?.path
391
- : operatorPage[0]?.path;
392
-
393
- const authorTitle = operatorPage[0] && operatorPage[0]?.author?.author_title;
394
-
395
- const clone = sanitizeOperatorData(
396
- cloneDeep(operatorRelation),
397
- operatorPage,
398
- data,
399
- toplists && toplists[listItem.id].label
400
- );
401
-
402
- const socialAuthorLinks = [
403
- 'facebook_profile',
404
- 'twitter_profile',
405
- 'instagram_profile',
406
- 'linkedin_profile',
407
- ];
408
-
409
- return Object.assign(clone, {
410
- review_link: reviewLink,
411
- author_title: authorTitle,
412
- author_same_as: operatorPage[0] && operatorPage[0]?.author && socialAuthorLinks
413
- .map((socialLink) => operatorPage[0]?.author?.[socialLink])
414
- .filter((socialLink) => socialLink),
415
- });
416
- })
382
+ );
383
+
384
+ if (operatorRelation) {
385
+ operatorRelation.ribbons =
386
+ item.ribbon_ids && item.ribbon_ids.length === 0
387
+ ? operatorRelation.ribbons
388
+ : item.ribbon_ids;
389
+
390
+ operatorRelation.selling_points =
391
+ item.selling_points && item.selling_points.length === 0
392
+ ? operatorRelation.selling_points
393
+ : item.selling_points;
394
+ }
395
+
396
+ operatorRelation.updated_at = item.updated_at;
397
+ operatorRelation.toplist_bonus = item.bonus_name;
398
+
399
+ const operatorPage =
400
+ pages && pages.operator && operatorRelation
401
+ ? pages.operator.filter(
402
+ (page) =>
403
+ page.relation &&
404
+ page.relation.operator_id ===
405
+ operatorRelation.operator_id &&
406
+ page.relation.type === operatorRelation.type
407
+ )
408
+ : [];
409
+
410
+ const reviewLink =
411
+ process.env.DMS_REVIEW_LINKS_ENABLED === "true"
412
+ ? stripDomainAndLeadingSlash(operatorRelation?.review_link) ||
413
+ operatorPage[0]?.path
414
+ : operatorPage[0]?.path;
415
+
416
+ const authorTitle =
417
+ operatorPage[0] && operatorPage[0]?.author?.author_title;
418
+
419
+ const clone = sanitizeOperatorData(
420
+ cloneDeep(operatorRelation),
421
+ operatorPage,
422
+ data,
423
+ toplists && toplists[listItem.id].label
424
+ );
425
+
426
+ const socialAuthorLinks = [
427
+ "facebook_profile",
428
+ "twitter_profile",
429
+ "instagram_profile",
430
+ "linkedin_profile",
431
+ ];
432
+ if (filterEnabled) {
433
+ buildToplistFilter(filters, clone);
434
+ }
435
+ return Object.assign(clone, {
436
+ review_link: reviewLink,
437
+ author_title: authorTitle,
438
+ author_same_as:
439
+ operatorPage[0] &&
440
+ operatorPage[0]?.author &&
441
+ socialAuthorLinks
442
+ .map((socialLink) => operatorPage[0]?.author?.[socialLink])
443
+ .filter((socialLink) => socialLink),
444
+ });
445
+ })
417
446
  : [];
418
-
419
447
  const latestItems = listItem.items
420
448
  .map((toplist) => ({
421
449
  ...toplist,
@@ -441,10 +469,10 @@ export function processTopListModule(
441
469
  // eslint-disable-next-line no-restricted-globals
442
470
  latestUpdatedDate instanceof Date && !isNaN(latestUpdatedDate)
443
471
  ? new Intl.DateTimeFormat("en-US", {
444
- year: "numeric",
445
- month: "long",
446
- day: "numeric",
447
- }).format(latestUpdatedDate)
472
+ year: "numeric",
473
+ month: "long",
474
+ day: "numeric",
475
+ }).format(latestUpdatedDate)
448
476
  : null;
449
477
 
450
478
  listItem.latest_items = formattedLatestItems;
@@ -452,6 +480,8 @@ export function processTopListModule(
452
480
 
453
481
  return listItem;
454
482
  });
483
+
484
+ if (filterEnabled) module.filters = filters;
455
485
  }
456
486
 
457
487
  export function processContentModule(
@@ -523,7 +553,7 @@ export function processFaq(module = {}, content, relationData) {
523
553
  null,
524
554
  relationData
525
555
  )) ||
526
- item.question
556
+ item.question
527
557
  );
528
558
  item.answer = trailingSlash(
529
559
  (content && content[item.answer]) || item.answer