gatsby-core-theme 40.0.29 → 40.0.31
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 +38 -0
- package/gatsby-node.mjs +20 -19
- package/package.json +1 -1
- package/src/components/molecules/search/index.js +5 -5
- package/src/components/molecules/search/search.test.js +13 -19
- package/src/components/organisms/anchor/template-one/index.js +4 -3
- package/src/components/organisms/search/index.js +18 -3
- package/src/components/organisms/search/search.module.scss +23 -24
- package/src/helpers/getPrioritySortedKeys.js +11 -0
- package/src/helpers/getPrioritySortedKeys.test.js +92 -0
- package/src/helpers/processor/index.mjs +22 -6
- package/src/helpers/processor/index.test.js +9 -6
- package/src/helpers/processor/modules.mjs +14 -3
- package/src/helpers/schema.js +4 -3
- package/src/helpers/tracker.mjs +3 -0
- package/tests/factories/pages/multiple-markets-pages_v2.factory.js +108 -0
- package/tests/factories/pages/pages_v2.factory.js +283 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
## [40.0.31](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v40.0.30...v40.0.31) (2024-11-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* convert all page creations to V2 apis ([9247ccc](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/9247ccc8c6c1db5ce499a0912c0ba01c74814a4d))
|
|
7
|
+
* search bar ([f4fca5c](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f4fca5c18bdab617d935d581a35127c0c9663d0b))
|
|
8
|
+
* search show nav ([063f27f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/063f27f888bc54aa6f53cea3c183b6b0b0af3712))
|
|
9
|
+
* search show nav ([522a245](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/522a245c24ed7f57ae6f77d0bd87730f6c18a307))
|
|
10
|
+
* site name ([2273e13](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/2273e1317f0525de8d698feb53de389e636b7612))
|
|
11
|
+
* tests ([7ef4caa](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/7ef4caaab2aa09ac3ea5bd79f752e210e37b7846))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
* Merge branch 'tm-3392-pages-v2' into 'master' ([d1a2403](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/d1a2403aadbfc9d03945cae6e7c7b610bf725549))
|
|
15
|
+
* Merge branch 'tm-4925-search-bar' into 'master' ([741a2ce](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/741a2ce879309c4fcb55fc4577dfa6e510c5d085))
|
|
16
|
+
|
|
17
|
+
## [40.0.30](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v40.0.29...v40.0.30) (2024-11-06)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* add tets for prioritysortedkeys function ([808a44f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/808a44fb56ab77d5ed6e2a82a2ed2ed588af0c53))
|
|
23
|
+
* checked with template ([da6a1b1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/da6a1b10b776df5751dd914513bafbf533b7ce1b))
|
|
24
|
+
* get latst changes ([86aa9bd](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/86aa9bd30d2f721780d7128e29525e9d23f8a452))
|
|
25
|
+
* remove breadcrumbs and webPage schema on tracker ([d2da70a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/d2da70a673cf50c2c904de7cfe017faf81e642a3))
|
|
26
|
+
* resolve conflicts ([3547eb2](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/3547eb2df7185c15ca3f3ca10685bdcfb27c6f8d))
|
|
27
|
+
* revert back changes ([67fab31](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/67fab3151e99266bc265761b9ac62caf13592dda))
|
|
28
|
+
* transaltion data ([5430b90](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/5430b90bed91a20c01d3a0b14df87a0eb60dbc7b))
|
|
29
|
+
* unique selling points ([fb8813e](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/fb8813eee68b036c1cadbb2c7c2a5433e415041f))
|
|
30
|
+
* update search logic so the first tabs and items to appear to be the operator and game ([f95d9fd](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f95d9fd62bf6744f33bf898416d5e83bbf9bcbcc))
|
|
31
|
+
* update tests ([7ab4ce0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/7ab4ce07b620030bf826bc9515eb872c76811a85))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
* Merge branch 'translation-page-description' into 'master' ([3f5632a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/3f5632abfed9e927947c400e41f81fc4d605bbe9))
|
|
35
|
+
* Merge branch 'tm-4878-search-page' into 'master' ([4d6b3c4](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/4d6b3c440d2df4d33388b4a5664724bbdebbb751))
|
|
36
|
+
* Merge branch 'tm-4917-schema' into 'master' ([545e278](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/545e2786b5acb1f76a1a7eb255bd7edace7af2be))
|
|
37
|
+
* Merge branch 'master' into tm-4917-schema ([db5e910](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/db5e9105bcbbeedabf9a0755901e345336d3c524))
|
|
38
|
+
|
|
1
39
|
## [40.0.29](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v40.0.28...v40.0.29) (2024-11-04)
|
|
2
40
|
|
|
3
41
|
|
package/gatsby-node.mjs
CHANGED
|
@@ -196,6 +196,7 @@ export const createPages = async ({ actions: { createPage } }, themeOptions) =>
|
|
|
196
196
|
console.log(chalk.magenta('info') + chalk.whiteBright(' starting processor'));
|
|
197
197
|
|
|
198
198
|
delete response.site_markets;
|
|
199
|
+
delete response.pages;
|
|
199
200
|
delete response.redirects;
|
|
200
201
|
delete response.breadcrumbs;
|
|
201
202
|
delete response.general;
|
|
@@ -210,6 +211,7 @@ export const createPages = async ({ actions: { createPage } }, themeOptions) =>
|
|
|
210
211
|
delete response.relations.translations;
|
|
211
212
|
delete response.relations.responsible_gamings;
|
|
212
213
|
delete response.relations.dms_affiliate_settings;
|
|
214
|
+
|
|
213
215
|
// Note: Not used
|
|
214
216
|
delete response.colors;
|
|
215
217
|
delete response.module_styles
|
|
@@ -219,6 +221,7 @@ export const createPages = async ({ actions: { createPage } }, themeOptions) =>
|
|
|
219
221
|
const processed = processor.run({
|
|
220
222
|
...response,
|
|
221
223
|
...siteSettingsData,
|
|
224
|
+
pages: pagesData,
|
|
222
225
|
general: siteGeneralData,
|
|
223
226
|
prefilled_market_modules: siteSettingsData.prefilled_modules,
|
|
224
227
|
responsible_gamings: responsableGamingData,
|
|
@@ -525,27 +528,25 @@ export const sourceNodes = async ({ actions, createNodeId, createContentDigest }
|
|
|
525
528
|
const page = pagesData[pageId]
|
|
526
529
|
if(page && page.robot_options && page.robot_options.page_index) {
|
|
527
530
|
const pageSitemap = {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
531
|
+
'path': page.path,
|
|
532
|
+
'updated_at': page.updated_at,
|
|
533
|
+
'market': page.market,
|
|
534
|
+
'language': page.language
|
|
535
|
+
}
|
|
533
536
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
537
|
+
const nodeMeta = {
|
|
538
|
+
id: createNodeId(keygen()),
|
|
539
|
+
parent: null,
|
|
540
|
+
children: [],
|
|
541
|
+
internal: {
|
|
542
|
+
type: `Sitemap`,
|
|
543
|
+
mediaType: `text/html`,
|
|
544
|
+
contentDigest: createContentDigest(pageId),
|
|
545
|
+
},
|
|
546
|
+
};
|
|
547
|
+
const node = { ...pageSitemap, ...nodeMeta}
|
|
548
|
+
createNode(node)
|
|
546
549
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
550
|
})
|
|
550
551
|
|
|
551
552
|
};
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ import ModuleTitle from '~atoms/module-title';
|
|
|
9
9
|
import Archive from '~organisms/archive';
|
|
10
10
|
import keygen from '~helpers/keygen';
|
|
11
11
|
import { sortDateOn, sortIntOn, sortStringOn } from '~helpers/search';
|
|
12
|
+
import { getOrderedKeys } from '../../../helpers/getPrioritySortedKeys';
|
|
12
13
|
import CustomSelect from '~atoms/custom-select';
|
|
13
14
|
import Tabs from '~hooks/tabs';
|
|
14
15
|
|
|
@@ -27,7 +28,7 @@ const Search = ({
|
|
|
27
28
|
|
|
28
29
|
const marketPrefix = activeMarket?.path_prefix || '/';
|
|
29
30
|
const showAll = useTranslate('showAll', "showAll");
|
|
30
|
-
|
|
31
|
+
|
|
31
32
|
const sortHandle = (field, name, type) => {
|
|
32
33
|
// eslint-disable-next-line array-callback-return
|
|
33
34
|
Object.keys(searchData).map((item) => {
|
|
@@ -45,9 +46,8 @@ const Search = ({
|
|
|
45
46
|
});
|
|
46
47
|
setSearchData({ ...searchData });
|
|
47
48
|
};
|
|
48
|
-
|
|
49
|
-
const typeTabs = searchData ? [showAll, ...
|
|
50
|
-
|
|
49
|
+
|
|
50
|
+
const typeTabs = searchData ? [showAll, ...getOrderedKeys(searchData)] : [];
|
|
51
51
|
const getItems = (item) => {
|
|
52
52
|
const titleObj = pageSearchOptions.archiveOptions.titles.find((title) => title.type === item);
|
|
53
53
|
const items = {
|
|
@@ -133,7 +133,7 @@ const Search = ({
|
|
|
133
133
|
|
|
134
134
|
return (
|
|
135
135
|
<div results={data.length} label={item} tabId="scas" key={keygen()}>
|
|
136
|
-
{
|
|
136
|
+
{getOrderedKeys(searchData).map((item2) => getItems(item2))}
|
|
137
137
|
</div>
|
|
138
138
|
);
|
|
139
139
|
})}
|
|
@@ -65,7 +65,7 @@ describe('Search Component', () => {
|
|
|
65
65
|
/>
|
|
66
66
|
);
|
|
67
67
|
|
|
68
|
-
expect(getByText('Search For: casino')).
|
|
68
|
+
expect(getByText('Search For: casino')).toBeInTheDocument();
|
|
69
69
|
const input = container.querySelectorAll('input');
|
|
70
70
|
expect(input).toHaveLength(1);
|
|
71
71
|
expect(input[0].getAttribute('placeholder')).toEqual('casino');
|
|
@@ -74,34 +74,28 @@ describe('Search Component', () => {
|
|
|
74
74
|
expect(container.querySelectorAll('.tab-content > div h2').length).toBe(8);
|
|
75
75
|
expect(container.querySelectorAll('.tabList ol li').length).toBe(2);
|
|
76
76
|
|
|
77
|
-
//
|
|
78
|
-
expect(getByText('
|
|
79
|
-
expect(getByText('
|
|
80
|
-
expect(getByText('
|
|
77
|
+
// Operator pages re-ordered
|
|
78
|
+
expect(getByText('VIPArabClub Casino Review 2024')).toBeInTheDocument();
|
|
79
|
+
expect(getByText('Casombie Casino Review 2024')).toBeInTheDocument();
|
|
80
|
+
expect(getByText('Playfina Casino Review 2024')).toBeInTheDocument();
|
|
81
81
|
|
|
82
82
|
const button = container.querySelector('.tabList ol li:nth-child(2) button');
|
|
83
83
|
fireEvent.click(button);
|
|
84
84
|
|
|
85
|
-
//
|
|
86
|
-
expect(getByText('
|
|
87
|
-
expect(getByText('
|
|
88
|
-
expect(getByText('
|
|
85
|
+
// Article Cards
|
|
86
|
+
expect(getByText('Best Online Casino Payment Methods For Arab Players In 2024')).toBeInTheDocument();
|
|
87
|
+
expect(getByText('Real Money Online Casinos for Arab Players 2024')).toBeInTheDocument();
|
|
88
|
+
expect(getByText('VIP Online Casinos for Arab Players 2024')).toBeInTheDocument();
|
|
89
|
+
|
|
89
90
|
|
|
90
91
|
const button2 = container.querySelector('.customSelectContainer ol li:nth-child(2) button');
|
|
91
92
|
fireEvent.click(button2);
|
|
92
93
|
|
|
93
94
|
// Default Pages
|
|
94
|
-
expect(getByText('
|
|
95
|
-
expect(getByText('
|
|
96
|
-
expect(getByText('
|
|
97
|
-
|
|
98
|
-
const button3 = container.querySelector('.customSelectContainer ol li:last-child button');
|
|
99
|
-
fireEvent.click(button3);
|
|
95
|
+
expect(getByText('Best Arabic Online Casinos 2024')).toBeInTheDocument();
|
|
96
|
+
expect(getByText('Best Online Casino Payment Methods For Arab Players In 2024')).toBeInTheDocument();
|
|
97
|
+
expect(getByText('Best Online Casinos in Algeria 2024')).toBeInTheDocument();
|
|
100
98
|
|
|
101
|
-
// Payment pages re-ordered
|
|
102
|
-
expect(getByText('10bet Casino Review 2024')).toBeTruthy();
|
|
103
|
-
expect(getByText('Megapari Casino Review 2024')).toBeTruthy();
|
|
104
|
-
expect(getByText('Lucky Dreams Casino 2024')).toBeTruthy();
|
|
105
99
|
});
|
|
106
100
|
});
|
|
107
101
|
});
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/* eslint-disable react/no-array-index-key */
|
|
2
|
-
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
1
|
/* eslint-disable no-nested-ternary */
|
|
4
2
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
5
3
|
/* eslint-disable no-unused-expressions */
|
|
6
4
|
/* eslint-disable prefer-destructuring */
|
|
7
5
|
/* eslint-disable react-hooks/exhaustive-deps */
|
|
8
|
-
import React, { useRef, useState } from
|
|
6
|
+
import React, { useRef, useState } from "react";
|
|
9
7
|
import PropTypes from 'prop-types';
|
|
10
8
|
import { IoIosArrowBack } from '@react-icons/all-files/io/IoIosArrowBack';
|
|
11
9
|
import { IoIosArrowForward } from '@react-icons/all-files/io/IoIosArrowForward';
|
|
@@ -124,6 +122,7 @@ function Anchor({
|
|
|
124
122
|
const sticky = isFixed && isSticky(stickyOffset, setActiveAnchor, anchorContainerRef);
|
|
125
123
|
|
|
126
124
|
const anchorItems = anchorList?.map((item, index) => (
|
|
125
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
127
126
|
<li key={index} className={styles.anchorItem || ''}>
|
|
128
127
|
<a
|
|
129
128
|
className={`${styles.link || ''} anchor-carousel-gtm anchor-menu-gtm`}
|
|
@@ -133,6 +132,7 @@ function Anchor({
|
|
|
133
132
|
ref={(el) => (itemsRef.current[index] = el)}
|
|
134
133
|
href={`#${item?.id && item.id}`}
|
|
135
134
|
>
|
|
135
|
+
{/* eslint-disable-next-line react-hooks/rules-of-hooks */}
|
|
136
136
|
{useTranslate(item.slug, item.label)}
|
|
137
137
|
{icon}
|
|
138
138
|
</a>
|
|
@@ -143,6 +143,7 @@ function Anchor({
|
|
|
143
143
|
<div className={styles.containerAnchor || ''} ref={anchorContainerRef}>
|
|
144
144
|
{showTitle && (
|
|
145
145
|
<div className={`${styles.anchorTitle || ''}`}>
|
|
146
|
+
{/* eslint-disable-next-line react-hooks/rules-of-hooks */}
|
|
146
147
|
<span>{useTranslate('anchor_title', 'Table of Contents')}</span>
|
|
147
148
|
</div>
|
|
148
149
|
)}
|
|
@@ -18,6 +18,7 @@ const SearchForm = ({
|
|
|
18
18
|
const [localSearch, setLocalSearch] = useState(false);
|
|
19
19
|
const [searchBoxQuery,] = useState();
|
|
20
20
|
const searchInputRef = useRef();
|
|
21
|
+
const searchFormRef = useRef();
|
|
21
22
|
|
|
22
23
|
const handleOnSearchIconClick = () => {
|
|
23
24
|
setLocalSearch(!localSearch);
|
|
@@ -45,12 +46,26 @@ const SearchForm = ({
|
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
useEffect(() => {
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
const handleClickOutside = (event) => {
|
|
50
|
+
if (localSearch && searchFormRef.current && !searchFormRef.current.contains(event.target)) {
|
|
51
|
+
setLocalSearch(false);
|
|
52
|
+
toggleScroll('search');
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
57
|
+
|
|
58
|
+
return () => {
|
|
59
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
60
|
+
};
|
|
61
|
+
}, [localSearch]);
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (localSearch) searchInputRef.current.focus();
|
|
50
65
|
}, [localSearch]);
|
|
51
66
|
|
|
52
67
|
return (
|
|
53
|
-
<div className={className || ''}>
|
|
68
|
+
<div className={className || ''} ref={searchFormRef}>
|
|
54
69
|
<button
|
|
55
70
|
type="button"
|
|
56
71
|
aria-label="Search"
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
.searchForm {
|
|
2
2
|
position: absolute;
|
|
3
|
-
top: 0;
|
|
3
|
+
top: var(--nav-height, 0);
|
|
4
4
|
left: 0;
|
|
5
5
|
width: 100%;
|
|
6
6
|
background-color: var(--modal-overlay-color);
|
|
7
|
-
height: 100vh;
|
|
8
|
-
z-index: map-get($z-index, search);
|
|
7
|
+
height: calc(100vh - var(--nav-height));
|
|
9
8
|
|
|
9
|
+
@include customZindex(search);
|
|
10
10
|
@include collapse(0s, 100vh);
|
|
11
11
|
}
|
|
12
|
+
|
|
12
13
|
.storyContainer {
|
|
13
14
|
position: relative;
|
|
14
15
|
height: 20rem;
|
|
15
16
|
width: 100%;
|
|
17
|
+
|
|
16
18
|
> div {
|
|
17
19
|
position: absolute;
|
|
18
20
|
width: 100%;
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
|
|
23
24
|
.form {
|
|
24
25
|
width: 100%;
|
|
25
26
|
max-width: var(--main-container-max);
|
|
@@ -30,41 +31,39 @@
|
|
|
30
31
|
top: var(--search-top-space, 2.4rem);
|
|
31
32
|
left: 50%;
|
|
32
33
|
transform: translateX(-50%);
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
> input {
|
|
34
36
|
align-items: center;
|
|
35
37
|
border-radius: var(--border-radius);
|
|
36
38
|
color: #0e1118;
|
|
37
39
|
display: flex;
|
|
38
|
-
font-size: 1.8rem;
|
|
39
40
|
font-size: 1.6rem;
|
|
40
41
|
font-weight: 500;
|
|
41
42
|
line-height: 2.7rem;
|
|
42
43
|
padding: 2.2rem 1.6rem;
|
|
43
44
|
width: 100%;
|
|
44
45
|
}
|
|
46
|
+
}
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
.searchButton > button > img {
|
|
49
|
+
filter: brightness(0);
|
|
50
|
+
height: 2.4rem;
|
|
51
|
+
width: 2.4rem;
|
|
52
|
+
}
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
.searchButton {
|
|
55
|
+
position: absolute;
|
|
56
|
+
right: 3rem;
|
|
57
|
+
top: 2.3rem;
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
59
|
+
svg {
|
|
60
|
+
color: var(--nav-icon-color);
|
|
61
|
+
font-size: 3rem;
|
|
61
62
|
}
|
|
62
|
-
}
|
|
63
63
|
|
|
64
|
-
.searchButton {
|
|
65
64
|
&:disabled {
|
|
66
65
|
background: transparent;
|
|
67
|
-
border:
|
|
68
|
-
cursor: not-allowed
|
|
66
|
+
border: unset;
|
|
67
|
+
cursor: not-allowed;
|
|
69
68
|
}
|
|
70
|
-
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
2
|
+
export const getOrderedKeys = (incomingData) => {
|
|
3
|
+
const priority = ["operator", "game"];
|
|
4
|
+
return Object.keys(incomingData).sort((a, b) => {
|
|
5
|
+
const aIndex = priority.indexOf(a);
|
|
6
|
+
const bIndex = priority.indexOf(b);
|
|
7
|
+
if (aIndex === -1) return 1;
|
|
8
|
+
if (bIndex === -1) return -1;
|
|
9
|
+
return aIndex - bIndex;
|
|
10
|
+
});
|
|
11
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { getOrderedKeys } from "./getPrioritySortedKeys";
|
|
2
|
+
|
|
3
|
+
describe("getOrderedKeys", () => {
|
|
4
|
+
test("sorts keys with priority items appearing first", () => {
|
|
5
|
+
const incomingData = {
|
|
6
|
+
game: "game value",
|
|
7
|
+
operator: "operator value",
|
|
8
|
+
article: "article value",
|
|
9
|
+
page: "default value",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const result = getOrderedKeys(incomingData);
|
|
13
|
+
expect(result).toEqual(["operator", "game", "article", "page"]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("returns non-priority items in original order after priority items", () => {
|
|
17
|
+
const incomingData = {
|
|
18
|
+
page: "default value",
|
|
19
|
+
article: "article value",
|
|
20
|
+
operator: "operator value",
|
|
21
|
+
game: "game value",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const result = getOrderedKeys(incomingData);
|
|
25
|
+
expect(result).toEqual(["operator", "game", "page", "article"]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("returns all keys in the order if no priority keys are present", () => {
|
|
29
|
+
const incomingData = {
|
|
30
|
+
page: "default value",
|
|
31
|
+
article: "article value",
|
|
32
|
+
news: "news value",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const result = getOrderedKeys(incomingData);
|
|
36
|
+
expect(result).toEqual(["page", "article", "news"]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("returns only priority keys if they are the only keys present", () => {
|
|
40
|
+
const incomingData = {
|
|
41
|
+
game: "game value",
|
|
42
|
+
operator: "operator value",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const result = getOrderedKeys(incomingData);
|
|
46
|
+
expect(result).toEqual(["operator", "game"]);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("returns empty array if incomingData is empty", () => {
|
|
50
|
+
const incomingData = {};
|
|
51
|
+
|
|
52
|
+
const result = getOrderedKeys(incomingData);
|
|
53
|
+
expect(result).toEqual([]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("places multiple non-priority keys after priority keys in the original order", () => {
|
|
57
|
+
const incomingData = {
|
|
58
|
+
game: "game value",
|
|
59
|
+
article: "article value",
|
|
60
|
+
page: "default value",
|
|
61
|
+
operator: "operator value",
|
|
62
|
+
news: "news value",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const result = getOrderedKeys(incomingData);
|
|
66
|
+
expect(result).toEqual(["operator", "game", "article", "page", "news"]);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("places priority key correctly if only one is present, in this case only operator", () => {
|
|
70
|
+
const incomingData = {
|
|
71
|
+
article: "article value",
|
|
72
|
+
page: "default value",
|
|
73
|
+
operator: "operator value",
|
|
74
|
+
news: "news value",
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const result = getOrderedKeys(incomingData);
|
|
78
|
+
expect(result).toEqual(["operator", "article", "page", "news"]);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("places priority key correctly if only one is present, in this case only game", () => {
|
|
82
|
+
const incomingData = {
|
|
83
|
+
article: "article value",
|
|
84
|
+
page: "default value",
|
|
85
|
+
game: "game value",
|
|
86
|
+
news: "news value",
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const result = getOrderedKeys(incomingData);
|
|
90
|
+
expect(result).toEqual(["game", "article", "page", "news"]);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -88,16 +88,33 @@ export function processSitemapPages(pages, markets) {
|
|
|
88
88
|
return pageListByMarket;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
const groupByLanguageAndType = (data) => Object.values(data).reduce((acc, item) => {
|
|
92
|
+
const lang = item.language;
|
|
93
|
+
const type = item.type;
|
|
94
|
+
|
|
95
|
+
// Initialize language and type groupings if not already present
|
|
96
|
+
if (!acc[lang]) acc[lang] = {};
|
|
97
|
+
if (!acc[lang][type]) acc[lang][type] = [];
|
|
98
|
+
|
|
99
|
+
// Add the item to the appropriate group
|
|
100
|
+
acc[lang][type].push(item);
|
|
101
|
+
return acc;
|
|
102
|
+
}, {});
|
|
103
|
+
|
|
91
104
|
export function transform(response) {
|
|
92
105
|
const transformed = {};
|
|
106
|
+
|
|
107
|
+
const pages = groupByLanguageAndType(response.pages);
|
|
108
|
+
|
|
93
109
|
Object.keys(response.site_markets).forEach((siteMarket) => {
|
|
94
110
|
const language = siteMarket.split("_")[1];
|
|
95
111
|
transformed[siteMarket] = {};
|
|
96
|
-
|
|
97
|
-
|
|
112
|
+
|
|
113
|
+
if (pages[language]) {
|
|
114
|
+
Object.keys(pages[language]).forEach((pageType) => {
|
|
98
115
|
transformed[siteMarket][pageType] = [];
|
|
99
|
-
Object.keys(
|
|
100
|
-
const page =
|
|
116
|
+
Object.keys(pages[language][pageType]).forEach((pageId) => {
|
|
117
|
+
const page = pages[language][pageType][pageId];
|
|
101
118
|
|
|
102
119
|
if (response.site_markets[siteMarket].path_prefix && page) {
|
|
103
120
|
// set page prefix for multiple markets
|
|
@@ -113,7 +130,6 @@ export function transform(response) {
|
|
|
113
130
|
}
|
|
114
131
|
});
|
|
115
132
|
console.log("transform done");
|
|
116
|
-
|
|
117
133
|
return transformed;
|
|
118
134
|
}
|
|
119
135
|
|
|
@@ -411,7 +427,7 @@ export default {
|
|
|
411
427
|
if (page.description !== null) {
|
|
412
428
|
page.description = generatePlaceholderString(
|
|
413
429
|
page.description,
|
|
414
|
-
|
|
430
|
+
translations,
|
|
415
431
|
{
|
|
416
432
|
siteName: generalData.site_name,
|
|
417
433
|
pageTitle: page.title,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { transform, processExtraFields, processSections, getReadingTime } from './index';
|
|
2
2
|
import pages from '~tests/factories/pages/pages.factory.js';
|
|
3
|
+
// eslint-disable-next-line camelcase
|
|
4
|
+
import pages_v2 from '~tests/factories/pages/pages_v2.factory.js';
|
|
3
5
|
import getPageList from '~tests/factories/pages/page.factory';
|
|
4
|
-
import multipleMarketsPages from '~tests/factories/pages/multiple-markets-
|
|
6
|
+
import multipleMarketsPages from '~tests/factories/pages/multiple-markets-pages_v2.factory.js';
|
|
5
7
|
import getOperatorData from '../../../tests/factories/relations/operator.factory';
|
|
6
8
|
|
|
7
9
|
const tempContent = {
|
|
@@ -32,12 +34,13 @@ const relations = {
|
|
|
32
34
|
|
|
33
35
|
describe('Index Processor', () => {
|
|
34
36
|
test('Transform', () => {
|
|
35
|
-
const results = transform(
|
|
36
|
-
expect(results?.za_en?.page).
|
|
37
|
+
const results = transform(pages_v2);
|
|
38
|
+
expect(results?.za_en?.page[0].id).toEqual(99408);
|
|
37
39
|
});
|
|
38
40
|
|
|
39
41
|
test('Transform multiple markets', () => {
|
|
40
42
|
const results = transform(multipleMarketsPages);
|
|
43
|
+
|
|
41
44
|
Object.keys(multipleMarketsPages.site_markets).forEach((siteMarket) => {
|
|
42
45
|
const prefix = multipleMarketsPages.site_markets[siteMarket].path_prefix;
|
|
43
46
|
expect(results[siteMarket].page[0].path).toBe(`${prefix ? `${prefix}/` : ''}test-page`);
|
|
@@ -103,8 +106,10 @@ describe('Index Processor', () => {
|
|
|
103
106
|
|
|
104
107
|
test('processSections', () => {
|
|
105
108
|
const result = processSections(pages.prefilled_market_modules);
|
|
106
|
-
expect(result).
|
|
109
|
+
expect(result.post_main['1059'].title).toBe('More casino reviews');
|
|
107
110
|
});
|
|
111
|
+
|
|
112
|
+
|
|
108
113
|
test('reading time', () => {
|
|
109
114
|
const relationType = 'author';
|
|
110
115
|
const market = 'ie_en';
|
|
@@ -122,7 +127,6 @@ describe('Index Processor', () => {
|
|
|
122
127
|
page.reading_time = result;
|
|
123
128
|
|
|
124
129
|
expect(result).toBe(1);
|
|
125
|
-
expect(page.reading_time).toBeTruthy();
|
|
126
130
|
expect(page.reading_time).toBe(result);
|
|
127
131
|
|
|
128
132
|
// Add more content for testing purpose of longer reading time
|
|
@@ -145,7 +149,6 @@ describe('Index Processor', () => {
|
|
|
145
149
|
page.reading_time = result1;
|
|
146
150
|
|
|
147
151
|
expect(result1).toBe(11);
|
|
148
|
-
expect(page.reading_time).toBeTruthy();
|
|
149
152
|
expect(page.reading_time).toBe(result1);
|
|
150
153
|
});
|
|
151
154
|
});
|
|
@@ -307,7 +307,8 @@ export function processTopListModule(
|
|
|
307
307
|
pages,
|
|
308
308
|
markets,
|
|
309
309
|
data,
|
|
310
|
-
toplists
|
|
310
|
+
toplists,
|
|
311
|
+
translations
|
|
311
312
|
) {
|
|
312
313
|
module.items = module.items.map((listItem) => {
|
|
313
314
|
const { type } = listItem;
|
|
@@ -358,7 +359,7 @@ export function processTopListModule(
|
|
|
358
359
|
operatorRelation.selling_points =
|
|
359
360
|
item.selling_points && item.selling_points.length === 0
|
|
360
361
|
? operatorRelation.selling_points
|
|
361
|
-
: item.selling_points;
|
|
362
|
+
: item.selling_points.map(sellingPoint => translations ? translations[sellingPoint] : sellingPoint);
|
|
362
363
|
}
|
|
363
364
|
|
|
364
365
|
const operatorPage =
|
|
@@ -431,6 +432,14 @@ export function processSpotlightModule(module = {}, content) {
|
|
|
431
432
|
return module;
|
|
432
433
|
}
|
|
433
434
|
|
|
435
|
+
export function processFaq(module = {}, content) {
|
|
436
|
+
// eslint-disable-next-line no-unused-expressions
|
|
437
|
+
module.items && module.items.map(item => {
|
|
438
|
+
item.question = (content && content[item.question]) || item.question;
|
|
439
|
+
item.answer = (content && content[item.answer]) || item.answer;
|
|
440
|
+
})
|
|
441
|
+
}
|
|
442
|
+
|
|
434
443
|
export function processModule(
|
|
435
444
|
module,
|
|
436
445
|
pages,
|
|
@@ -479,8 +488,10 @@ export function processModule(
|
|
|
479
488
|
markets,
|
|
480
489
|
data,
|
|
481
490
|
toplists,
|
|
482
|
-
|
|
491
|
+
translations
|
|
483
492
|
);
|
|
493
|
+
} else if(module.name === "faq") {
|
|
494
|
+
processFaq(module, content);
|
|
484
495
|
} else if (module.name === "spotlights") {
|
|
485
496
|
processSpotlightModule(module, content);
|
|
486
497
|
} else if (module.name === "menu" && menus && menus[module.menu_id]) {
|
package/src/helpers/schema.js
CHANGED
|
@@ -486,16 +486,17 @@ export function templateSchemas(page, pageImage) {
|
|
|
486
486
|
|
|
487
487
|
export function schemaGenerator(page = {}, pageImage) {
|
|
488
488
|
const isHomepage = page.path === '/';
|
|
489
|
-
|
|
489
|
+
const tracker = page?.template === 'tracker';
|
|
490
|
+
|
|
490
491
|
const jsonSchema = [
|
|
491
492
|
// Page Schema
|
|
492
493
|
...(page.seo_json_schemas && page.seo_json_schemas.length
|
|
493
494
|
? page.seo_json_schemas
|
|
494
495
|
: [page.seo_json_schema]),
|
|
495
496
|
// Breadcrumbs Schema
|
|
496
|
-
!isHomepage ? breadcrumbsSchema(page) : null,
|
|
497
|
+
(!isHomepage && !tracker) ? breadcrumbsSchema(page) : null,
|
|
497
498
|
// Modules Schemas
|
|
498
|
-
|
|
499
|
+
!tracker ? webPageSchema(page, pageImage): null,
|
|
499
500
|
organizationSchema(page, pageImage),
|
|
500
501
|
templateSchemas(page, pageImage),
|
|
501
502
|
...(page.sections?.main?.modules
|
package/src/helpers/tracker.mjs
CHANGED
|
@@ -109,6 +109,8 @@ function buildUrlParams(operator, trackerName, headers, cookie, extraParams) {
|
|
|
109
109
|
const userAgent = headers?.get("user-agent") || null;
|
|
110
110
|
const affObject = isJsonString(cookie.affObject) ? JSON.parse(cookie.affObject) : {};
|
|
111
111
|
|
|
112
|
+
if (extraParams && extraParams.pt) affObject.module = extraParams.pt;
|
|
113
|
+
|
|
112
114
|
return {
|
|
113
115
|
site_id: process.env.SITE_ID,
|
|
114
116
|
operator_short_name: operator.short_name,
|
|
@@ -138,6 +140,7 @@ export async function getAffiliateLink(operator, path, page, headers, url) {
|
|
|
138
140
|
const trackerName = await getTrackerName(operator, page, path);
|
|
139
141
|
const cookie = parseCookies(headers);
|
|
140
142
|
const extraParams = extractUrlParams(url);
|
|
143
|
+
|
|
141
144
|
const urlParam = buildUrlParams(operator, trackerName, headers, cookie, extraParams);
|
|
142
145
|
|
|
143
146
|
const queryString = new URLSearchParams(clean(urlParam)).toString();
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
site_markets: {
|
|
3
|
+
za_en: { path_prefix: null },
|
|
4
|
+
es_es: {
|
|
5
|
+
path_prefix: "es",
|
|
6
|
+
},
|
|
7
|
+
},
|
|
8
|
+
pages: {
|
|
9
|
+
99407: {
|
|
10
|
+
id: 99407,
|
|
11
|
+
market_id: 67,
|
|
12
|
+
updated_at: "2021-12-08",
|
|
13
|
+
created_at: "2021-12-08 16:15:50",
|
|
14
|
+
template_id: 97,
|
|
15
|
+
page_hreflang_group_id: null,
|
|
16
|
+
page_hreflang_combined: 0,
|
|
17
|
+
relation_id: 0,
|
|
18
|
+
relation_type: "page",
|
|
19
|
+
market: "za_en",
|
|
20
|
+
region_code: null,
|
|
21
|
+
author: null,
|
|
22
|
+
hard_coded_breadcrumbs: 0,
|
|
23
|
+
breadcrumb_ids: null,
|
|
24
|
+
categories: [],
|
|
25
|
+
author_id: null,
|
|
26
|
+
style_id: null,
|
|
27
|
+
language: "en",
|
|
28
|
+
description: null,
|
|
29
|
+
meta_title: null,
|
|
30
|
+
meta_robots: null,
|
|
31
|
+
robot_options: {
|
|
32
|
+
page_index: 0,
|
|
33
|
+
links_followed: 0,
|
|
34
|
+
images_index: 0,
|
|
35
|
+
show_snippet: 0,
|
|
36
|
+
},
|
|
37
|
+
meta_description: null,
|
|
38
|
+
seo_keywords: null,
|
|
39
|
+
seo_raw_js: "",
|
|
40
|
+
seo_json_schema: null,
|
|
41
|
+
seo_json_schemas: [],
|
|
42
|
+
page_custom_hreflangs: null,
|
|
43
|
+
title: "test-page",
|
|
44
|
+
vanity_label: null,
|
|
45
|
+
path: "test-page",
|
|
46
|
+
type: "page",
|
|
47
|
+
template: "default",
|
|
48
|
+
extra_fields: [],
|
|
49
|
+
banner: null,
|
|
50
|
+
featured_image: null,
|
|
51
|
+
canonical_url: null,
|
|
52
|
+
canonical_url_page_id: null,
|
|
53
|
+
status: "active",
|
|
54
|
+
page_group_id: null,
|
|
55
|
+
page_group_combined: 0,
|
|
56
|
+
page_group_custom_items: null,
|
|
57
|
+
},
|
|
58
|
+
99408: {
|
|
59
|
+
id: 99408,
|
|
60
|
+
market_id: 67,
|
|
61
|
+
updated_at: "2021-12-08",
|
|
62
|
+
created_at: "2021-12-08 16:15:50",
|
|
63
|
+
template_id: 97,
|
|
64
|
+
page_hreflang_group_id: null,
|
|
65
|
+
page_hreflang_combined: 0,
|
|
66
|
+
relation_id: 0,
|
|
67
|
+
relation_type: "page",
|
|
68
|
+
market: "es_es",
|
|
69
|
+
region_code: null,
|
|
70
|
+
author: null,
|
|
71
|
+
hard_coded_breadcrumbs: 0,
|
|
72
|
+
breadcrumb_ids: null,
|
|
73
|
+
categories: [],
|
|
74
|
+
author_id: null,
|
|
75
|
+
style_id: null,
|
|
76
|
+
language: "es",
|
|
77
|
+
description: null,
|
|
78
|
+
meta_title: null,
|
|
79
|
+
meta_robots: null,
|
|
80
|
+
robot_options: {
|
|
81
|
+
page_index: 0,
|
|
82
|
+
links_followed: 0,
|
|
83
|
+
images_index: 0,
|
|
84
|
+
show_snippet: 0,
|
|
85
|
+
},
|
|
86
|
+
meta_description: null,
|
|
87
|
+
seo_keywords: null,
|
|
88
|
+
seo_raw_js: "",
|
|
89
|
+
seo_json_schema: null,
|
|
90
|
+
seo_json_schemas: [],
|
|
91
|
+
page_custom_hreflangs: null,
|
|
92
|
+
title: "test-page",
|
|
93
|
+
vanity_label: null,
|
|
94
|
+
path: "test-page",
|
|
95
|
+
type: "page",
|
|
96
|
+
template: "default",
|
|
97
|
+
extra_fields: [],
|
|
98
|
+
banner: null,
|
|
99
|
+
featured_image: null,
|
|
100
|
+
canonical_url: null,
|
|
101
|
+
canonical_url_page_id: null,
|
|
102
|
+
status: "active",
|
|
103
|
+
page_group_id: null,
|
|
104
|
+
page_group_combined: 0,
|
|
105
|
+
page_group_custom_items: null,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
site_markets: { za_en: [] },
|
|
3
|
+
pages: {
|
|
4
|
+
99408: {
|
|
5
|
+
id: 99408,
|
|
6
|
+
market_id: 67,
|
|
7
|
+
updated_at: "2021-12-08",
|
|
8
|
+
created_at: "2021-12-08 16:15:50",
|
|
9
|
+
template_id: 97,
|
|
10
|
+
page_hreflang_group_id: null,
|
|
11
|
+
page_hreflang_combined: 0,
|
|
12
|
+
relation_id: 0,
|
|
13
|
+
relation_type: "page",
|
|
14
|
+
market: "za_en",
|
|
15
|
+
region_code: null,
|
|
16
|
+
author: null,
|
|
17
|
+
hard_coded_breadcrumbs: 0,
|
|
18
|
+
breadcrumb_ids: null,
|
|
19
|
+
categories: [],
|
|
20
|
+
author_id: null,
|
|
21
|
+
style_id: null,
|
|
22
|
+
language: "en",
|
|
23
|
+
description: null,
|
|
24
|
+
meta_title: null,
|
|
25
|
+
meta_robots: null,
|
|
26
|
+
robot_options: {
|
|
27
|
+
page_index: 0,
|
|
28
|
+
links_followed: 0,
|
|
29
|
+
images_index: 0,
|
|
30
|
+
show_snippet: 0,
|
|
31
|
+
},
|
|
32
|
+
meta_description: null,
|
|
33
|
+
seo_keywords: null,
|
|
34
|
+
seo_raw_js: "",
|
|
35
|
+
seo_json_schema: null,
|
|
36
|
+
seo_json_schemas: [],
|
|
37
|
+
page_custom_hreflangs: null,
|
|
38
|
+
title: "404 Page",
|
|
39
|
+
vanity_label: null,
|
|
40
|
+
path: "404",
|
|
41
|
+
type: "page",
|
|
42
|
+
template: "default",
|
|
43
|
+
extra_fields: [],
|
|
44
|
+
banner: null,
|
|
45
|
+
featured_image: null,
|
|
46
|
+
canonical_url: null,
|
|
47
|
+
canonical_url_page_id: null,
|
|
48
|
+
status: "active",
|
|
49
|
+
page_group_id: null,
|
|
50
|
+
page_group_combined: 0,
|
|
51
|
+
page_group_custom_items: null,
|
|
52
|
+
sections: {
|
|
53
|
+
navigation: null,
|
|
54
|
+
header: null,
|
|
55
|
+
main: null,
|
|
56
|
+
links: null,
|
|
57
|
+
site_markets: { za_en: [] },
|
|
58
|
+
pages: {
|
|
59
|
+
en: {
|
|
60
|
+
page: {
|
|
61
|
+
404: {
|
|
62
|
+
za_en: {
|
|
63
|
+
id: 99408,
|
|
64
|
+
market_id: 67,
|
|
65
|
+
updated_at: "2021-12-08",
|
|
66
|
+
created_at: "2021-12-08 16:15:50",
|
|
67
|
+
template_id: 97,
|
|
68
|
+
page_hreflang_group_id: null,
|
|
69
|
+
page_hreflang_combined: 0,
|
|
70
|
+
relation_id: 0,
|
|
71
|
+
relation_type: "page",
|
|
72
|
+
market: "za_en",
|
|
73
|
+
region_code: null,
|
|
74
|
+
author: null,
|
|
75
|
+
hard_coded_breadcrumbs: 0,
|
|
76
|
+
breadcrumb_ids: null,
|
|
77
|
+
categories: [],
|
|
78
|
+
author_id: null,
|
|
79
|
+
style_id: null,
|
|
80
|
+
language: "en",
|
|
81
|
+
description: null,
|
|
82
|
+
meta_title: null,
|
|
83
|
+
meta_robots: null,
|
|
84
|
+
robot_options: {
|
|
85
|
+
page_index: 0,
|
|
86
|
+
links_followed: 0,
|
|
87
|
+
images_index: 0,
|
|
88
|
+
show_snippet: 0,
|
|
89
|
+
},
|
|
90
|
+
meta_description: null,
|
|
91
|
+
seo_keywords: null,
|
|
92
|
+
seo_raw_js: "",
|
|
93
|
+
seo_json_schema: null,
|
|
94
|
+
seo_json_schemas: [],
|
|
95
|
+
page_custom_hreflangs: null,
|
|
96
|
+
title: "404 Page",
|
|
97
|
+
vanity_label: null,
|
|
98
|
+
path: "404",
|
|
99
|
+
type: "page",
|
|
100
|
+
template: "default",
|
|
101
|
+
extra_fields: [],
|
|
102
|
+
banner: null,
|
|
103
|
+
featured_image: null,
|
|
104
|
+
canonical_url: null,
|
|
105
|
+
canonical_url_page_id: null,
|
|
106
|
+
status: "active",
|
|
107
|
+
page_group_id: null,
|
|
108
|
+
page_group_combined: 0,
|
|
109
|
+
page_group_custom_items: null,
|
|
110
|
+
sections: {
|
|
111
|
+
navigation: null,
|
|
112
|
+
header: null,
|
|
113
|
+
main: null,
|
|
114
|
+
links: null,
|
|
115
|
+
footer: null,
|
|
116
|
+
popup: null,
|
|
117
|
+
footer_navigation: null,
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
footer: null,
|
|
125
|
+
popup: null,
|
|
126
|
+
footer_navigation: null,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
market_sections: {
|
|
131
|
+
za_en: {
|
|
132
|
+
footer: {
|
|
133
|
+
extra_fields: {
|
|
134
|
+
logos: {
|
|
135
|
+
value: "339",
|
|
136
|
+
type: "menu",
|
|
137
|
+
},
|
|
138
|
+
links: {
|
|
139
|
+
value: "340",
|
|
140
|
+
type: "menu",
|
|
141
|
+
},
|
|
142
|
+
social_icons: {
|
|
143
|
+
value: "341",
|
|
144
|
+
type: "menu",
|
|
145
|
+
},
|
|
146
|
+
copyright_disclaimer: {
|
|
147
|
+
value:
|
|
148
|
+
'<p ><br><a href="https://www.dmca.com/Protection/Status.aspx?ID=c33e0a2a-0b14-4cba-bb31-194e23738540&refurl=https://www.playcasino.co.za" target="_blank" title="DMCA Compliance information for playcasino.co.za"></a><a href="https://responsiblegambling.org.za/" target="_blank"></a>Advertising Disclosure: <a href="https://www.playcasino.co.za/">Playcasino.co.za</a> contains paid links to our partner affiliates. If a user visiting our site clicks on any of these paid links and makes a purchase from our partner, Playcasino.co.za will get paid a commission.</p><p>© PlayCasino All rights reserved</p><p>Marketing Performance Media Limited BVI Company number: 2028811 </p>',
|
|
149
|
+
type: "html",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
modules: [],
|
|
153
|
+
},
|
|
154
|
+
navigation: {
|
|
155
|
+
extra_fields: [],
|
|
156
|
+
modules: [
|
|
157
|
+
{
|
|
158
|
+
menu_id: 337,
|
|
159
|
+
menu_short_code: "main_menu",
|
|
160
|
+
module_value_id: 213604,
|
|
161
|
+
name: "menu",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
value: "14076",
|
|
165
|
+
type: null,
|
|
166
|
+
module_value_id: 213608,
|
|
167
|
+
name: "bonus",
|
|
168
|
+
anchored: 0,
|
|
169
|
+
anchor_label: null,
|
|
170
|
+
anchor_slug: null,
|
|
171
|
+
module_title:
|
|
172
|
+
"R500 Free No Deposit Bonus (Code: 500FM) + 500% up to R15,000",
|
|
173
|
+
module_title_tag: null,
|
|
174
|
+
background_color: null,
|
|
175
|
+
style: null,
|
|
176
|
+
style_id: null,
|
|
177
|
+
see_more_link: {
|
|
178
|
+
type: "page",
|
|
179
|
+
value: null,
|
|
180
|
+
title: null,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
prefilled_market_modules: {
|
|
188
|
+
post_main: {
|
|
189
|
+
1059: {
|
|
190
|
+
title: "More casino reviews",
|
|
191
|
+
link_label: null,
|
|
192
|
+
link_value: null,
|
|
193
|
+
model_type: "operator",
|
|
194
|
+
display_input: "automatic",
|
|
195
|
+
display_type: "default",
|
|
196
|
+
sort_by: "random",
|
|
197
|
+
sort_order: "ascending",
|
|
198
|
+
num_of_items: 3,
|
|
199
|
+
desktop_num_of_columns: 3,
|
|
200
|
+
tablet_num_of_columns: 3,
|
|
201
|
+
mobile_num_of_columns: 1,
|
|
202
|
+
featured_index: null,
|
|
203
|
+
show_load_more: false,
|
|
204
|
+
extra_data: null,
|
|
205
|
+
module_value_id: 1059,
|
|
206
|
+
name: "cards",
|
|
207
|
+
anchored: 0,
|
|
208
|
+
anchor_label: null,
|
|
209
|
+
anchor_slug: null,
|
|
210
|
+
module_title: "More Casino Reviews",
|
|
211
|
+
module_title_tag: null,
|
|
212
|
+
background_color: null,
|
|
213
|
+
style: null,
|
|
214
|
+
style_id: null,
|
|
215
|
+
see_more_link: {
|
|
216
|
+
type: "page",
|
|
217
|
+
value: null,
|
|
218
|
+
title: null,
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
1061: {
|
|
222
|
+
title: "More slots reviews",
|
|
223
|
+
link_label: null,
|
|
224
|
+
link_value: null,
|
|
225
|
+
model_type: "game",
|
|
226
|
+
display_input: "automatic",
|
|
227
|
+
display_type: "default",
|
|
228
|
+
sort_by: "created_at",
|
|
229
|
+
sort_order: "ascending",
|
|
230
|
+
num_of_items: 3,
|
|
231
|
+
desktop_num_of_columns: 3,
|
|
232
|
+
tablet_num_of_columns: 3,
|
|
233
|
+
mobile_num_of_columns: 1,
|
|
234
|
+
featured_index: null,
|
|
235
|
+
show_load_more: false,
|
|
236
|
+
extra_data: null,
|
|
237
|
+
module_value_id: 1061,
|
|
238
|
+
name: "cards",
|
|
239
|
+
anchored: 0,
|
|
240
|
+
anchor_label: null,
|
|
241
|
+
anchor_slug: null,
|
|
242
|
+
module_title: "More Game Reviews",
|
|
243
|
+
module_title_tag: null,
|
|
244
|
+
background_color: null,
|
|
245
|
+
style: null,
|
|
246
|
+
style_id: null,
|
|
247
|
+
see_more_link: {
|
|
248
|
+
type: "page",
|
|
249
|
+
value: null,
|
|
250
|
+
title: null,
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
1063: {
|
|
254
|
+
title: "Latest news",
|
|
255
|
+
link_label: null,
|
|
256
|
+
link_value: null,
|
|
257
|
+
model_type: "article",
|
|
258
|
+
display_input: "automatic",
|
|
259
|
+
display_type: "default",
|
|
260
|
+
sort_by: "created_at",
|
|
261
|
+
sort_order: "ascending",
|
|
262
|
+
num_of_items: 3,
|
|
263
|
+
desktop_num_of_columns: 3,
|
|
264
|
+
tablet_num_of_columns: 3,
|
|
265
|
+
mobile_num_of_columns: 1,
|
|
266
|
+
featured_index: null,
|
|
267
|
+
show_load_more: false,
|
|
268
|
+
extra_data: null,
|
|
269
|
+
module_value_id: 1063,
|
|
270
|
+
name: "cards",
|
|
271
|
+
anchored: 0,
|
|
272
|
+
anchor_label: null,
|
|
273
|
+
anchor_slug: null,
|
|
274
|
+
module_title: null,
|
|
275
|
+
module_title_tag: null,
|
|
276
|
+
background_color: null,
|
|
277
|
+
style: null,
|
|
278
|
+
style_id: null,
|
|
279
|
+
see_more_link: null,
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
};
|