gatsby-core-theme 44.29.0 → 44.30.1
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 +26 -0
- package/package.json +1 -1
- package/src/components/atoms/iframe/index.js +0 -8
- package/src/components/atoms/notifications/index.js +4 -1
- package/src/components/atoms/notifications/notification-items/bonuses/index.js +28 -4
- package/src/components/atoms/notifications/notification-items/cards-v2/index.js +6 -7
- package/src/components/atoms/notifications/notification-items/cards-v2/notification-items.module.scss +10 -9
- package/src/components/atoms/notifications/notification-items/spotlight/index.js +7 -8
- package/src/components/atoms/notifications/notifications.module.scss +19 -0
- package/src/components/atoms/notifications/panel-header/panel-header.module.scss +2 -2
- package/src/components/atoms/notifications/panel-tabs/index.js +3 -3
- package/src/components/atoms/notifications/panel-tabs/panel-tabs.module.scss +1 -3
- package/src/resolver/games.mjs +59 -17
- package/src/resolver/games.test.js +66 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
## [44.30.1](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.30.0...v44.30.1) (2026-06-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* fix style of notification panel ([b21a180](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/b21a1808842776e36ef14f3f8f1fbe70a20f1854))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
* Merge branch 'master' of gitlab.com:g2m-gentoo/team-floyd/themes/gatsby-themes ([850c758](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/850c7581eb1a7a19fa20b63eace13032cd54919a))
|
|
10
|
+
|
|
11
|
+
# [44.30.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.29.0...v44.30.0) (2026-06-22)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* update iframe module by removing unecessary noscript ([e84bef4](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e84bef46dd629827a7a6eb2c4d58c8171ece48b6))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
* Merge branch 'update-iframe' into 'master' ([409530a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/409530a1af0ad65ca69ae1dbf65b6fb91ef8e84b))
|
|
20
|
+
* Merge branch 'feat/new-jackpot-response' into 'master' ([38f26a6](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/38f26a6a244312d1e45a3567fdf54341c8f1bbff))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* new jackpot response format ([421c8a6](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/421c8a6e6a69072d290aefcb53d2c42a0caab511))
|
|
26
|
+
|
|
1
27
|
# [44.29.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.28.0...v44.29.0) (2026-06-18)
|
|
2
28
|
|
|
3
29
|
|
package/package.json
CHANGED
|
@@ -20,14 +20,6 @@ const Iframe = ({
|
|
|
20
20
|
loading={lazyLoad ? 'lazy' : 'eager'}
|
|
21
21
|
frameBorder={frameBorder}
|
|
22
22
|
/>
|
|
23
|
-
<noscript>
|
|
24
|
-
{`<iframe title="${title}"
|
|
25
|
-
style="width: 100%, ${minHeight}, display: block"
|
|
26
|
-
width={868}
|
|
27
|
-
height={454}
|
|
28
|
-
src="${src}"
|
|
29
|
-
loading="${lazyLoad ? 'lazy' : 'eager'}" />`}
|
|
30
|
-
</noscript>
|
|
31
23
|
</div>
|
|
32
24
|
</>
|
|
33
25
|
);
|
|
@@ -25,7 +25,7 @@ const getNotificationToplist = (modules) => {
|
|
|
25
25
|
);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const Notifications = ({ section, market }) => {
|
|
28
|
+
const Notifications = ({ section, market, hideBadges = false }) => {
|
|
29
29
|
const { setShowSearch, setShowMenu, showMenu, showSearch } =
|
|
30
30
|
useContext(NavigationContext);
|
|
31
31
|
const notificationRef = useRef(null);
|
|
@@ -139,6 +139,7 @@ const Notifications = ({ section, market }) => {
|
|
|
139
139
|
activeTab={activeTab}
|
|
140
140
|
onTabChange={setActiveTab}
|
|
141
141
|
market={market}
|
|
142
|
+
hideBadges={hideBadges}
|
|
142
143
|
/>
|
|
143
144
|
|
|
144
145
|
<div className={styles.content}>
|
|
@@ -146,6 +147,7 @@ const Notifications = ({ section, market }) => {
|
|
|
146
147
|
<BonusesItems
|
|
147
148
|
toplist={notificationToplist}
|
|
148
149
|
showUnread={newNotification}
|
|
150
|
+
hideBadges={hideBadges}
|
|
149
151
|
/>
|
|
150
152
|
) : (
|
|
151
153
|
renderTrendingContent()
|
|
@@ -163,6 +165,7 @@ Notifications.propTypes = {
|
|
|
163
165
|
section: PropTypes.shape({
|
|
164
166
|
modules: PropTypes.arrayOf(PropTypes.shape({})),
|
|
165
167
|
}),
|
|
168
|
+
hideBadges: PropTypes.bool
|
|
166
169
|
};
|
|
167
170
|
|
|
168
171
|
export default Notifications;
|
|
@@ -10,11 +10,13 @@ import keygen from "~helpers/keygen";
|
|
|
10
10
|
import {
|
|
11
11
|
getBonusData,
|
|
12
12
|
getPromoCode,
|
|
13
|
+
getOperatorTnc,
|
|
13
14
|
imagePrettyUrl,
|
|
14
15
|
} from "~helpers/getters";
|
|
15
16
|
import { getAltText } from "~helpers/image";
|
|
16
17
|
import { getTimeAgo } from "~helpers/date-time";
|
|
17
18
|
import { TrackingKeys } from "~constants/tracking-api";
|
|
19
|
+
import VerifiedBadgeIcon from "~images/icons/verifiedBadgeIcon";
|
|
18
20
|
import useTranslate from "~hooks/useTranslate/useTranslate";
|
|
19
21
|
import styles from "../../notifications.module.scss";
|
|
20
22
|
|
|
@@ -25,6 +27,7 @@ const BonusItem = ({
|
|
|
25
27
|
showUnread,
|
|
26
28
|
bonusCodeLabel,
|
|
27
29
|
updatedLabel,
|
|
30
|
+
hideBadges
|
|
28
31
|
}) => {
|
|
29
32
|
const bonus = getBonusData(item, tracker);
|
|
30
33
|
const oneliner = [bonus?.mainLine, bonus?.secondLine]
|
|
@@ -42,6 +45,16 @@ const BonusItem = ({
|
|
|
42
45
|
const timeAgo = timeData.value
|
|
43
46
|
? `${updatedLabel} ${timeData.value} ${timeKeyLabel}`
|
|
44
47
|
: "";
|
|
48
|
+
const hasTnc = Boolean(getOperatorTnc(item, tracker));
|
|
49
|
+
|
|
50
|
+
const verifiedMonth = new Intl.DateTimeFormat("en-US", {
|
|
51
|
+
month: "long",
|
|
52
|
+
}).format(new Date());
|
|
53
|
+
|
|
54
|
+
const verifiedLabel = useTranslate(
|
|
55
|
+
"notification_verified_in",
|
|
56
|
+
"Verified in [month]"
|
|
57
|
+
).replace("[month]", verifiedMonth);
|
|
45
58
|
|
|
46
59
|
return (
|
|
47
60
|
<li className={styles.bonusItem}>
|
|
@@ -102,10 +115,18 @@ const BonusItem = ({
|
|
|
102
115
|
)}
|
|
103
116
|
{timeAgo && <span className={styles.updated}>{timeAgo}</span>}
|
|
104
117
|
</div>
|
|
118
|
+
{hideBadges && (
|
|
119
|
+
<span className={styles.customVerifiedBadge}>
|
|
120
|
+
<VerifiedBadgeIcon />
|
|
121
|
+
{verifiedLabel}
|
|
122
|
+
</span>
|
|
123
|
+
)}
|
|
105
124
|
|
|
106
|
-
|
|
107
|
-
<
|
|
108
|
-
|
|
125
|
+
{hasTnc && (
|
|
126
|
+
<div className={styles.legal}>
|
|
127
|
+
<Tnc operator={item} tracker={tracker} isFixed />
|
|
128
|
+
</div>
|
|
129
|
+
)}
|
|
109
130
|
</li>
|
|
110
131
|
);
|
|
111
132
|
};
|
|
@@ -126,9 +147,10 @@ BonusItem.propTypes = {
|
|
|
126
147
|
showUnread: PropTypes.bool,
|
|
127
148
|
bonusCodeLabel: PropTypes.string.isRequired,
|
|
128
149
|
updatedLabel: PropTypes.string.isRequired,
|
|
150
|
+
hideBadges: PropTypes.bool
|
|
129
151
|
};
|
|
130
152
|
|
|
131
|
-
const BonusesItems = ({ toplist, showUnread }) => {
|
|
153
|
+
const BonusesItems = ({ toplist, showUnread, hideBadges }) => {
|
|
132
154
|
const items = toplist?.items || [];
|
|
133
155
|
const tracker =
|
|
134
156
|
toplist?.toplist_bonus || toplist?.one_liner || toplist?.tracker || "main";
|
|
@@ -149,6 +171,7 @@ const BonusesItems = ({ toplist, showUnread }) => {
|
|
|
149
171
|
showUnread={showUnread}
|
|
150
172
|
bonusCodeLabel={bonusCodeLabel}
|
|
151
173
|
updatedLabel={updatedLabel}
|
|
174
|
+
hideBadges={hideBadges}
|
|
152
175
|
/>
|
|
153
176
|
))}
|
|
154
177
|
</ul>
|
|
@@ -163,6 +186,7 @@ BonusesItems.propTypes = {
|
|
|
163
186
|
tracker: PropTypes.string,
|
|
164
187
|
}),
|
|
165
188
|
showUnread: PropTypes.bool,
|
|
189
|
+
hideBadges: PropTypes.bool
|
|
166
190
|
};
|
|
167
191
|
|
|
168
192
|
export default BonusesItems;
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
3
|
import React from "react";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
|
+
import { FaArrowRight } from "@react-icons/all-files/fa/FaArrowRight";
|
|
5
6
|
import LazyImage from "~hooks/lazy-image";
|
|
6
7
|
import keygen from "~helpers/keygen";
|
|
7
8
|
import Link from "~hooks/link";
|
|
8
9
|
import {
|
|
9
10
|
imagePrettyUrl,
|
|
10
11
|
getExtraField,
|
|
11
|
-
textWordsLimit,
|
|
12
12
|
} from "~helpers/getters";
|
|
13
13
|
import { getAltText, getImageFilename } from "~helpers/image";
|
|
14
14
|
import ArticleIcon from "../../../../../images/icons/articleIcon";
|
|
@@ -27,7 +27,7 @@ const CategoryTag = ({ category }) => {
|
|
|
27
27
|
return <span className={styles.tag}>{label}</span>;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
const CardsItems = ({ module,
|
|
30
|
+
const CardsItems = ({ module, showUnread = false }) => {
|
|
31
31
|
const { items } = module || {};
|
|
32
32
|
const noNewUpdates = useTranslate("noNewUpdates", "No new items");
|
|
33
33
|
const updatedLabel = useTranslate("updated", "Updated");
|
|
@@ -87,14 +87,13 @@ const CardsItems = ({ module, wordLimit = 12, showUnread = false }) => {
|
|
|
87
87
|
)}
|
|
88
88
|
{description && (
|
|
89
89
|
<p className={styles.subtitle}>
|
|
90
|
-
{
|
|
91
|
-
description.replace(/<\/?[^>]+(>|$)/g, ""),
|
|
92
|
-
wordLimit
|
|
93
|
-
)}
|
|
90
|
+
{description.replace(/<\/?[^>]+(>|$)/g, "")}
|
|
94
91
|
</p>
|
|
95
92
|
)}
|
|
96
93
|
</div>
|
|
97
|
-
<span className={styles.cta} aria-hidden="true"
|
|
94
|
+
<span className={styles.cta} aria-hidden="true">
|
|
95
|
+
<FaArrowRight size={12} />
|
|
96
|
+
</span>
|
|
98
97
|
</div>
|
|
99
98
|
{(categories.length > 0 || ribbon || timeAgo) && (
|
|
100
99
|
<div className={styles.meta}>
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
.unreadDot {
|
|
137
|
-
left: -
|
|
137
|
+
left: -0.8rem;
|
|
138
138
|
top: -0.8rem;
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -157,10 +157,6 @@
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
.text {
|
|
161
|
-
padding-right: 2.4rem;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
160
|
.title {
|
|
165
161
|
font-weight: 700;
|
|
166
162
|
color: var(--notification-oneliner-color, #1b1b1c);
|
|
@@ -169,6 +165,10 @@
|
|
|
169
165
|
.subtitle {
|
|
170
166
|
display: -webkit-box;
|
|
171
167
|
overflow: hidden;
|
|
168
|
+
-webkit-box-orient: vertical;
|
|
169
|
+
-webkit-line-clamp: 2;
|
|
170
|
+
line-clamp: 2;
|
|
171
|
+
text-overflow: ellipsis;
|
|
172
172
|
color: var(--notification-trending-description-color, #6e6e84);
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -206,15 +206,16 @@
|
|
|
206
206
|
flex-shrink: 0;
|
|
207
207
|
width: 3.6rem;
|
|
208
208
|
height: 3.6rem;
|
|
209
|
+
padding: 0.2rem 0.8rem 0.4rem;
|
|
210
|
+
border: var(--notification-panel-cta-border, none);
|
|
209
211
|
border-radius: var(--notification-cta-border-radius, 4.8rem);
|
|
210
|
-
background: var(--notification-trending-cta-bg, #f4f4f4)
|
|
211
|
-
|
|
212
|
-
no-repeat center;
|
|
212
|
+
background: var(--notification-trending-cta-bg, #f4f4f4);
|
|
213
|
+
color: var(--notification-trending-cta-color, #6b6a72);
|
|
213
214
|
pointer-events: none;
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
.embeddedList {
|
|
218
219
|
gap: 1.2rem;
|
|
219
|
-
padding: 0.8rem 0 0
|
|
220
|
+
padding: 0.8rem 0 0;
|
|
220
221
|
}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
3
3
|
import React from "react";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
|
-
import {
|
|
5
|
+
import { FaArrowRight } from "@react-icons/all-files/fa/FaArrowRight";
|
|
6
|
+
import { imagePrettyUrl } from "~helpers/getters";
|
|
6
7
|
import { getAltText, getImageFilename } from "~helpers/image";
|
|
7
8
|
import LazyImage from "~hooks/lazy-image";
|
|
8
9
|
import keygen from "~helpers/keygen";
|
|
@@ -11,7 +12,7 @@ import useTranslate from "~hooks/useTranslate/useTranslate";
|
|
|
11
12
|
import { getTimeAgo } from "~helpers/date-time";
|
|
12
13
|
import styles from "../cards-v2/notification-items.module.scss";
|
|
13
14
|
|
|
14
|
-
const SpotlightItems = ({ module, showUnread = false
|
|
15
|
+
const SpotlightItems = ({ module, showUnread = false }) => {
|
|
15
16
|
const { items } = module || {};
|
|
16
17
|
const noNewUpdates = useTranslate("noNewUpdates", "No new items");
|
|
17
18
|
const updatedLabel = useTranslate("updated", "Updated");
|
|
@@ -64,14 +65,13 @@ const SpotlightItems = ({ module, showUnread = false, wordLimit = 12 }) => {
|
|
|
64
65
|
)}
|
|
65
66
|
{description && (
|
|
66
67
|
<p className={styles.subtitle}>
|
|
67
|
-
{
|
|
68
|
-
description.replace(/<\/?[^>]+(>|$)/g, ""),
|
|
69
|
-
wordLimit
|
|
70
|
-
)}
|
|
68
|
+
{description.replace(/<\/?[^>]+(>|$)/g, "")}
|
|
71
69
|
</p>
|
|
72
70
|
)}
|
|
73
71
|
</div>
|
|
74
|
-
<span className={styles.cta} aria-hidden="true"
|
|
72
|
+
<span className={styles.cta} aria-hidden="true">
|
|
73
|
+
<FaArrowRight size={12} />
|
|
74
|
+
</span>
|
|
75
75
|
</div>
|
|
76
76
|
{(ribbon || timeAgo) && (
|
|
77
77
|
<div className={styles.meta}>
|
|
@@ -138,7 +138,6 @@ SpotlightItems.propTypes = {
|
|
|
138
138
|
items: PropTypes.arrayOf(PropTypes.shape({})),
|
|
139
139
|
}),
|
|
140
140
|
showUnread: PropTypes.bool,
|
|
141
|
-
wordLimit: PropTypes.number,
|
|
142
141
|
};
|
|
143
142
|
|
|
144
143
|
export default SpotlightItems;
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
height: calc(100% - var(--nav-height-mobile, 4.8rem));
|
|
63
63
|
background: var(--notification-panel-bg, #fff);
|
|
64
64
|
border-left: var(--notification-panel-border-left, 0 solid transparent);
|
|
65
|
+
border-top: var(--notification-panel-border-top, 0 solid transparent);
|
|
65
66
|
|
|
66
67
|
@include min(tablet) {
|
|
67
68
|
top: 0;
|
|
@@ -270,3 +271,21 @@
|
|
|
270
271
|
text-decoration: none;
|
|
271
272
|
}
|
|
272
273
|
}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
.customVerifiedBadge {
|
|
277
|
+
@include flex-align(center, flex-start);
|
|
278
|
+
|
|
279
|
+
box-sizing: border-box;
|
|
280
|
+
width: fit-content;
|
|
281
|
+
gap: 0.4rem;
|
|
282
|
+
height: 2rem;
|
|
283
|
+
padding: 0.1rem 0.6rem 0.1rem 0.2rem;
|
|
284
|
+
border-radius: var(--notification-badge-border-radius, 10rem);
|
|
285
|
+
font-size: 1.2rem;
|
|
286
|
+
font-weight: 400;
|
|
287
|
+
line-height: 1.8rem;
|
|
288
|
+
background: var(--notification-verified-badge-bg, #DEE9FF);
|
|
289
|
+
color: var(--notification-verified-badge-color, #000);
|
|
290
|
+
border: 1px solid var(--notification-verified-badge-border, transparent);
|
|
291
|
+
}
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
h2 {
|
|
11
11
|
flex: 1;
|
|
12
12
|
margin: 0;
|
|
13
|
-
font-size: 2rem;
|
|
13
|
+
font-size: var(--notification-panel-title-size, 2rem);
|
|
14
14
|
font-weight: 700;
|
|
15
|
-
line-height: 2.8rem;
|
|
15
|
+
line-height: var(--notification-panel-title-line-height, 2.8rem);
|
|
16
16
|
color: var(--notification-title-color, #0f0c28);
|
|
17
17
|
text-transform: capitalize;
|
|
18
18
|
}
|
|
@@ -5,7 +5,7 @@ import CountryFlagIcon from "~images/icons/countryFlag";
|
|
|
5
5
|
import useTranslate from "~hooks/useTranslate/useTranslate";
|
|
6
6
|
import styles from "./panel-tabs.module.scss";
|
|
7
7
|
|
|
8
|
-
const PanelTabs = ({ activeTab, onTabChange, market }) => {
|
|
8
|
+
const PanelTabs = ({ activeTab, onTabChange, market, hideBadges }) => {
|
|
9
9
|
const countryCode = market?.split("_")[0]?.toUpperCase();
|
|
10
10
|
const verifiedMonth = new Intl.DateTimeFormat("en-US", {
|
|
11
11
|
month: "long",
|
|
@@ -45,8 +45,7 @@ const PanelTabs = ({ activeTab, onTabChange, market }) => {
|
|
|
45
45
|
{trendingContentLabel}
|
|
46
46
|
</button>
|
|
47
47
|
</div>
|
|
48
|
-
|
|
49
|
-
{activeTab === "bonuses" && (
|
|
48
|
+
{(activeTab === "bonuses" && !hideBadges) && (
|
|
50
49
|
<div className={styles.badges}>
|
|
51
50
|
<span className={styles.verifiedBadge}>
|
|
52
51
|
<VerifiedBadgeIcon />
|
|
@@ -74,6 +73,7 @@ PanelTabs.propTypes = {
|
|
|
74
73
|
activeTab: PropTypes.oneOf(["bonuses", "trending"]).isRequired,
|
|
75
74
|
onTabChange: PropTypes.func.isRequired,
|
|
76
75
|
market: PropTypes.string,
|
|
76
|
+
hideBadges: PropTypes.bool
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
export default PanelTabs;
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
@include flex-align(flex-start, stretch);
|
|
12
12
|
|
|
13
13
|
box-sizing: border-box;
|
|
14
|
-
height: 4rem;
|
|
15
14
|
padding: 0.4rem;
|
|
16
15
|
border: 1px solid var(--notification-tabs-border, #dedede);
|
|
17
16
|
border-radius: var(--notification-tabs-border-radius, 1.2rem);
|
|
@@ -21,10 +20,9 @@
|
|
|
21
20
|
.tab,
|
|
22
21
|
.tabActive {
|
|
23
22
|
flex: 1;
|
|
24
|
-
height: 3.2rem;
|
|
25
23
|
border: 0;
|
|
26
24
|
border-radius: var(--notification-tab-border-radius, 0.8rem);
|
|
27
|
-
padding: 0.
|
|
25
|
+
padding: 0.7rem 1rem;
|
|
28
26
|
font-size: 1.2rem;
|
|
29
27
|
line-height: 1.8rem;
|
|
30
28
|
cursor: pointer;
|
package/src/resolver/games.mjs
CHANGED
|
@@ -83,25 +83,67 @@ export function transformGames(jsonData, relationsData) {
|
|
|
83
83
|
export function transformGamesJackpot(data) {
|
|
84
84
|
const transformedData = {};
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
86
|
+
// Accepts both jackpot payloads and normalises them to the shape the site
|
|
87
|
+
// consumes, keyed by game id:
|
|
88
|
+
// { [gameId]: { [jackpotType]: { …jackpot… } } }
|
|
89
|
+
//
|
|
90
|
+
// New (flat) shape — one jackpot leaf per game:
|
|
91
|
+
// { [gameId]: { game_id, jackpot_type, jackpot, … } }
|
|
92
|
+
//
|
|
93
|
+
// Legacy (nested) shape — grouped by operator then tier. Operators carry
|
|
94
|
+
// identical network jackpots, so the operator dimension is collapsed:
|
|
95
|
+
// { [gameId]: {
|
|
96
|
+
// game_short_name,
|
|
97
|
+
// [operatorId]: { operator_short_name, [jackpotType]: { …jackpot… } }
|
|
98
|
+
// } }
|
|
99
|
+
Object.values(data).forEach((gameEntry) => {
|
|
100
|
+
if (!gameEntry || typeof gameEntry !== "object") {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// New flat shape: the entry *is* a single jackpot leaf (one per game).
|
|
105
|
+
// { [gameId]: { game_id, jackpot_type, jackpot, … } }
|
|
106
|
+
if (gameEntry.game_id !== null && gameEntry.game_id !== undefined) {
|
|
107
|
+
const { game_id: gameId, jackpot_type: jackpotType } = gameEntry;
|
|
108
|
+
transformedData[gameId] = { [jackpotType || "n/a"]: gameEntry };
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Object.entries(gameEntry).forEach(([operatorKey, operatorEntry]) => {
|
|
113
|
+
// Skip the game-level metadata, keep only the operator buckets.
|
|
114
|
+
if (
|
|
115
|
+
operatorKey === "game_short_name" ||
|
|
116
|
+
!operatorEntry ||
|
|
117
|
+
typeof operatorEntry !== "object"
|
|
118
|
+
) {
|
|
119
|
+
return;
|
|
101
120
|
}
|
|
102
|
-
});
|
|
103
121
|
|
|
104
|
-
|
|
122
|
+
Object.entries(operatorEntry).forEach(([jackpotType, jackpot]) => {
|
|
123
|
+
// Skip the operator-level metadata, keep only jackpot buckets.
|
|
124
|
+
if (
|
|
125
|
+
jackpotType === "operator_short_name" ||
|
|
126
|
+
!jackpot ||
|
|
127
|
+
typeof jackpot !== "object"
|
|
128
|
+
) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const { game_id: gameId } = jackpot;
|
|
133
|
+
if (gameId === null || gameId === undefined) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!transformedData[gameId]) {
|
|
138
|
+
transformedData[gameId] = {};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// First operator wins per jackpot type (values match across operators).
|
|
142
|
+
if (!(jackpotType in transformedData[gameId])) {
|
|
143
|
+
transformedData[gameId][jackpotType] = jackpot;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
105
147
|
});
|
|
106
148
|
|
|
107
149
|
return transformedData;
|
|
@@ -105,6 +105,72 @@ describe("transformGamesJackpot", () => {
|
|
|
105
105
|
expect(transformGamesJackpot(inputData)).toEqual(expectedOutput);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
+
test("should collapse multiple operators of the same game into one entry", () => {
|
|
109
|
+
const progressive = {
|
|
110
|
+
game_id: 32,
|
|
111
|
+
game_short_name: "mega_moolah",
|
|
112
|
+
jackpot_type: "progressive",
|
|
113
|
+
operator_id: 352,
|
|
114
|
+
currency: "GBP",
|
|
115
|
+
jackpot: 11477605,
|
|
116
|
+
};
|
|
117
|
+
const minor = {
|
|
118
|
+
game_id: 32,
|
|
119
|
+
game_short_name: "mega_moolah",
|
|
120
|
+
jackpot_type: "minor",
|
|
121
|
+
operator_id: 352,
|
|
122
|
+
currency: "GBP",
|
|
123
|
+
jackpot: 94,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const inputData = {
|
|
127
|
+
32: {
|
|
128
|
+
game_short_name: "mega_moolah",
|
|
129
|
+
352: {
|
|
130
|
+
operator_short_name: "fun_casino",
|
|
131
|
+
progressive,
|
|
132
|
+
minor,
|
|
133
|
+
},
|
|
134
|
+
// Second operator carries the same network jackpots and must not
|
|
135
|
+
// produce a duplicate or extra nesting level.
|
|
136
|
+
312: {
|
|
137
|
+
operator_short_name: "no_bonus_casino",
|
|
138
|
+
progressive,
|
|
139
|
+
minor,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
expect(transformGamesJackpot(inputData)).toEqual({
|
|
145
|
+
32: { progressive, minor },
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("should transform the new flat shape", () => {
|
|
150
|
+
const leaf = {
|
|
151
|
+
game_id: 32,
|
|
152
|
+
game_short_name: "mega_moolah",
|
|
153
|
+
jackpot_type: "progressive",
|
|
154
|
+
operator_name: "Fun Casino",
|
|
155
|
+
operator_id: 352,
|
|
156
|
+
currency: "GBP",
|
|
157
|
+
jackpot: 10975893,
|
|
158
|
+
};
|
|
159
|
+
const untyped = {
|
|
160
|
+
game_id: 491,
|
|
161
|
+
game_short_name: "gladiator",
|
|
162
|
+
jackpot_type: null,
|
|
163
|
+
operator_id: null,
|
|
164
|
+
currency: "EUR",
|
|
165
|
+
jackpot: 854887,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
expect(transformGamesJackpot({ 32: leaf, 491: untyped })).toEqual({
|
|
169
|
+
32: { progressive: leaf },
|
|
170
|
+
491: { "n/a": untyped },
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
108
174
|
test("should return an empty object if input is empty", () => {
|
|
109
175
|
expect(transformGamesJackpot({})).toEqual({});
|
|
110
176
|
});
|