@opexa/portal-components 0.0.885 β†’ 0.0.887

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.
Files changed (49) hide show
  1. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
  2. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
  3. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/QRPHDepositContext.d.ts +2 -2
  4. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/useQRPHDeposit.d.ts +1 -1
  5. package/dist/components/ForgotPassword/Crazywin/CWForgotPassword.d.ts +6 -0
  6. package/dist/components/ForgotPassword/Crazywin/CWForgotPassword.js +11 -0
  7. package/dist/components/ForgotPassword/Crazywin/CWForgotPasswordForm.d.ts +2 -0
  8. package/dist/components/ForgotPassword/Crazywin/CWForgotPasswordForm.js +75 -0
  9. package/dist/components/ForgotPassword/Crazywin/ForgotPassword.module.css +43 -0
  10. package/dist/components/ForgotPassword/ForgotPassword.lazy.d.ts +3 -0
  11. package/dist/components/ForgotPassword/ForgotPassword.lazy.js +6 -1
  12. package/dist/components/Jackpots/JackpotsCarousel/JackpotsCarousel.client.js +2 -1
  13. package/dist/components/Jackpots/JackpotsCarousel/JackpotsCarouselItem.CrazyWin.js +8 -19
  14. package/dist/components/Jackpots/JackpotsCarousel/JackpotsCarouselItem.HappyBingo.d.ts +8 -0
  15. package/dist/components/Jackpots/JackpotsCarousel/JackpotsCarouselItem.HappyBingo.js +154 -0
  16. package/dist/components/Jackpots/JackpotsList/JackpotsList.d.ts +1 -0
  17. package/dist/components/Jackpots/JackpotsList/JackpotsList.js +3 -1
  18. package/dist/components/Jackpots/JackpotsList/JackpotsListItem.CrazyWin.d.ts +6 -0
  19. package/dist/components/Jackpots/JackpotsList/JackpotsListItem.CrazyWin.js +167 -0
  20. package/dist/components/Jackpots/JackpotsList/JackpotsListItem.HappyBingo.d.ts +6 -0
  21. package/dist/components/Jackpots/JackpotsList/JackpotsListItem.HappyBingo.js +167 -0
  22. package/dist/components/Jackpots/JackpotsList/JackpotsListItemGameProviders.d.ts +3 -1
  23. package/dist/components/Jackpots/JackpotsList/JackpotsListItemGameProviders.js +2 -2
  24. package/dist/components/Jackpots/utils.d.ts +15 -1
  25. package/dist/components/Jackpots/utils.js +59 -1
  26. package/dist/components/Promos/Cashback.d.ts +4 -1
  27. package/dist/components/Promos/Cashback.js +6 -3
  28. package/dist/components/Promos/CustomPromo.d.ts +3 -1
  29. package/dist/components/Promos/CustomPromo.js +3 -2
  30. package/dist/components/Promos/Promo.d.ts +4 -1
  31. package/dist/components/Promos/Promo.js +6 -3
  32. package/dist/components/Promos/PromosGrid.d.ts +3 -0
  33. package/dist/components/Promos/PromosGrid.js +1 -1
  34. package/dist/components/Promos/utils.d.ts +1 -0
  35. package/dist/components/Promos/utils.js +10 -0
  36. package/dist/components/SignIn/MobileNumberField.js +18 -11
  37. package/dist/icons/User02Icon.d.ts +2 -0
  38. package/dist/icons/User02Icon.js +4 -0
  39. package/dist/images/3d-star.webp +0 -0
  40. package/dist/images/happy-bingo-coins.webp +0 -0
  41. package/dist/schemas/forgotPasswordSchema.d.ts +32 -0
  42. package/dist/schemas/forgotPasswordSchema.js +15 -0
  43. package/dist/services/game.d.ts +1 -1
  44. package/dist/services/game.js +2 -0
  45. package/dist/services/queries.d.ts +1 -1
  46. package/dist/services/queries.js +8 -0
  47. package/dist/services/wallet.d.ts +1 -1
  48. package/dist/services/wallet.js +2 -0
  49. package/package.json +1 -1
@@ -0,0 +1,167 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Progress } from '@ark-ui/react/progress';
4
+ import { format } from 'date-fns';
5
+ import isMobile from 'is-mobile';
6
+ import Image from 'next/image';
7
+ import { useCallback, useEffect, useMemo, useState } from 'react';
8
+ import { twMerge } from 'tailwind-merge';
9
+ import { useIntersectionObserver } from 'usehooks-ts';
10
+ import { useJackpotPayoutsQuery } from '../../../client/hooks/useJackpotPayoutsQuery.js';
11
+ import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
12
+ import { ChevronDownIcon } from '../../../icons/ChevronDownIcon.js';
13
+ import { ChevronLeftIcon } from '../../../icons/ChevronLeftIcon.js';
14
+ import { ChevronRightIcon } from '../../../icons/ChevronRightIcon.js';
15
+ import { ChevronUpIcon } from '../../../icons/ChevronUpIcon.js';
16
+ import { User02Icon } from '../../../icons/User02Icon.js';
17
+ import treasureChestBg from '../../../images/chest-bg.webp';
18
+ import coin from '../../../images/coin.webp';
19
+ import coins from '../../../images/coins.webp';
20
+ import star from '../../../images/star.webp';
21
+ import treasureChest from '../../../images/treasure.webp';
22
+ import { formatNumber } from '../../../utils/formatNumber.js';
23
+ import { getPercentage } from '../../../utils/getPercentage.js';
24
+ import styles from '../Jackpots.module.css';
25
+ import { CRAZYWIN_JACKPOTS_VARIATIONS, formatProviderName, maskName } from '../utils.js';
26
+ import { useJackpotsListItemContext } from './JackpotsListContext.js';
27
+ import { JackpotsListItemGameProviders } from './JackpotsListItemGameProviders.js';
28
+ import { useJackpotsListItemData } from './useJackpotsListItemData.js';
29
+ export function JackpotsListItemCrazyWin({ index, }) {
30
+ const jackpot = useJackpotsListItemContext();
31
+ const localeInfo = useLocaleInfo();
32
+ const { getAccumulatingJackpotDescription, filteredGameProviders } = useJackpotsListItemData();
33
+ const jackpotPayoutsQuery = useJackpotPayoutsQuery({
34
+ first: 30,
35
+ filter: {
36
+ jackpot: {
37
+ equal: jackpot.id,
38
+ },
39
+ },
40
+ });
41
+ const [ref] = useIntersectionObserver({
42
+ threshold: 0.5,
43
+ rootMargin: '50px',
44
+ });
45
+ const [infoIndex, setInfoIndex] = useState(0);
46
+ const [seeDetails, setSeeDetails] = useState(false);
47
+ const [mainTooltipOpen, setMainTooltipOpen] = useState(false);
48
+ const isPayingOut = jackpot.drawing;
49
+ const jackpotAmount = jackpot.pool;
50
+ const jackpotPayouts = jackpotPayoutsQuery.data?.pages[0].edges.map((edge) => edge.node) ?? [];
51
+ const variation = CRAZYWIN_JACKPOTS_VARIATIONS[index % CRAZYWIN_JACKPOTS_VARIATIONS.length];
52
+ const isMobileDevice = useMemo(() => isMobile(), []);
53
+ const getInfoBlocks = useCallback(() => {
54
+ return [
55
+ `Current Jackpot: <b>${formatNumber(jackpotAmount, {
56
+ currency: localeInfo.currency.code,
57
+ minDecimalPlaces: 2,
58
+ maxDecimalPlaces: 2,
59
+ })}</b>`,
60
+ `Minimum Payout Limit: <b>${formatNumber(jackpot.minimumJackpotPoolDrawingLimit, {
61
+ currency: localeInfo.currency.code,
62
+ minDecimalPlaces: 2,
63
+ maxDecimalPlaces: 2,
64
+ })}</b>`,
65
+ `Maximum Payout Limit: <b>${formatNumber(jackpot.maximumJackpotPoolLimit, {
66
+ currency: localeInfo.currency.code,
67
+ minDecimalPlaces: 2,
68
+ maxDecimalPlaces: 2,
69
+ })}</b>`,
70
+ isPayingOut
71
+ ? `The pot has hit <b>${formatNumber(jackpot.maximumJackpotPoolLimit, {
72
+ currency: localeInfo.currency.code,
73
+ minDecimalPlaces: 2,
74
+ maxDecimalPlaces: 2,
75
+ })}</b> Play now for your chance to win big! πŸ”₯`
76
+ : getAccumulatingJackpotDescription(Number(jackpot.pool), Number(jackpot.maximumJackpotPoolLimit)),
77
+ ];
78
+ }, [
79
+ isPayingOut,
80
+ jackpot,
81
+ jackpotAmount,
82
+ localeInfo,
83
+ getAccumulatingJackpotDescription,
84
+ ]);
85
+ const Arrow = useCallback(({ index }) => {
86
+ const Icon = isPayingOut ? ChevronLeftIcon : ChevronRightIcon;
87
+ return (_jsx(Icon, { className: twMerge('min-w-2.5 scale-400 text-brand-300 lg:min-w-4 lg:scale-250', isPayingOut
88
+ ? styles['animate-wave-color-error']
89
+ : styles['animate-wave-color-success']), style: {
90
+ animationDelay: isPayingOut
91
+ ? `${(40 - index - 1) * 0.1}s`
92
+ : `${index * 0.1}s`,
93
+ } }));
94
+ }, [isPayingOut]);
95
+ const arrowImages = useMemo(() => Array.from({ length: 40 }, (_, i) => _jsx(Arrow, { index: i }, i)), [Arrow]);
96
+ useEffect(() => {
97
+ const interval = setInterval(() => {
98
+ setInfoIndex((i) => (i + 1) % getInfoBlocks().length);
99
+ }, 4000);
100
+ return () => clearInterval(interval);
101
+ }, [getInfoBlocks]);
102
+ useEffect(() => {
103
+ if (isMobileDevice && mainTooltipOpen) {
104
+ const timeout = setTimeout(() => setMainTooltipOpen(false), 3000);
105
+ return () => clearTimeout(timeout);
106
+ }
107
+ }, [mainTooltipOpen, isMobileDevice]);
108
+ if (jackpot.status === 'DISABLED' && jackpot.drawing !== true) {
109
+ return null;
110
+ }
111
+ return (_jsxs("div", { className: "w-full shrink-0", children: [_jsxs("div", { ref: ref, className: twMerge('relative flex w-full shrink-0 rounded-t-2xl p-3 text-center lg:gap-4 lg:p-5', variation.background), children: [_jsxs("div", { className: "flex w-full flex-col gap-6 lg:flex-row lg:gap-0", children: [_jsxs("div", { className: "relative z-1 flex flex-1 flex-col", children: [[
112
+ [
113
+ styles['flicker-scale-fade-2'],
114
+ 'absolute right-[38%] top-[2%] h-2 w-2 delay-75',
115
+ ],
116
+ [
117
+ styles['flicker-scale-fade'],
118
+ 'absolute right-[20%] top-[10%] h-3 w-3',
119
+ ],
120
+ [
121
+ styles['flicker-scale-fade-2'],
122
+ 'absolute right-[30%] top-[10%] h-5 w-5',
123
+ ],
124
+ [
125
+ styles['flicker-scale-fade'],
126
+ 'absolute right-[36%] top-[35%] h-3 w-3',
127
+ ],
128
+ [
129
+ styles['flicker-scale-fade'],
130
+ 'absolute right-[15%] top-[56%] h-3 w-3',
131
+ ],
132
+ [
133
+ styles['flicker-scale-fade-2'],
134
+ 'absolute right-[50%] top-[55%] h-4 w-4',
135
+ ],
136
+ ].map(([animationClass, positionClass], i) => (_jsx(Image, { src: star, alt: "star", draggable: "false", className: twMerge(animationClass, positionClass), unoptimized: true }, i))), _jsx("div", { className: "flex h-full flex-col justify-between", children: _jsx("div", { className: "flex w-full justify-between", children: _jsx("div", { className: "flex w-full flex-col", children: _jsxs("div", { className: "relative flex w-full justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "mb-2 flex gap-1 font-medium", children: _jsxs("div", { className: twMerge('flex w-fit items-center justify-center gap-1 rounded-[10px] border border-[#82F0D0] px-[10px] py-1 text-[#82F0D0] text-xs lg:text-sm'), children: [_jsx("div", { className: twMerge('h-[6px] w-[6px] animate-color rounded-full', isPayingOut
137
+ ? styles['pulse-error']
138
+ : styles['pulse-success']) }), _jsx("div", { className: twMerge('rounded text-[#CECFD2]'), children: isPayingOut ? 'Paying Out' : 'Accumulating' })] }) }), _jsx("div", { className: "mb-2 text-left font-semibold text-[18px] text-white lg:mb-0 lg:text-2xl", children: jackpot?.name }), _jsx("div", { className: `${variation.poolBg} ${variation.textColor} flex w-fit rounded-lg px-2 font-semibold text-[26px] lg:text-[36px]`, children: formatNumber(jackpotAmount, {
139
+ currency: localeInfo.currency.code,
140
+ minDecimalPlaces: 2,
141
+ maxDecimalPlaces: 2,
142
+ }) })] }), _jsx(Image, { width: 175, height: 175, src: treasureChest, alt: "treasure chest", className: twMerge('absolute top-[0px] right-[-3px] h-[124px] w-[124px] md:top-0 lg:top-[-30px] lg:h-[175px] lg:w-[175px]'), priority: false, loading: "lazy", unoptimized: true })] }) }) }) }), _jsxs("div", { className: "mt-3 lg:mt-4", children: [_jsxs("div", { className: "mb-1 flex justify-between", children: [_jsx("div", { className: "font-semibold text-text-primary-900 text-xs", "aria-live": "polite", children: formatNumber(0, {
143
+ currency: localeInfo.currency.code,
144
+ compact: true,
145
+ }) }), _jsxs("div", { className: "relative flex items-center justify-end gap-1.5", children: [isPayingOut ? (_jsx("div", { className: "flex w-6 items-center", children: [0, 1.5, 3].map((left, i) => (_jsx("div", { className: twMerge(`absolute left-${left}`, styles[`animate-arrow-red-flash-${i + 1}`]), children: _jsx(ChevronLeftIcon, { className: "size-4.5" }) }, i))) })) : (_jsx("div", { className: "flex w-6 items-center", children: [0, 1.5, 3].map((left, i) => (_jsx("div", { className: twMerge(`absolute left-${left}`, styles[`animate-arrow-green-flash-${i + 1}`]), children: _jsx(ChevronRightIcon, { className: "size-4.5" }) }, i))) })), _jsx("div", { className: "font-semibold text-text-primary-900 text-xs", children: formatNumber(jackpot?.maximumJackpotPoolLimit, {
146
+ currency: localeInfo.currency.code,
147
+ compact: true,
148
+ }) })] })] }), _jsx(Progress.Root, { className: "h-2 w-full rounded-full bg-bg-primary lg:h-4", max: 100, value: getPercentage(jackpot.pool, jackpot.maximumJackpotPoolLimit), "aria-valuenow": getPercentage(jackpot.pool, jackpot.maximumJackpotPoolLimit), "aria-valuemax": 100, "aria-label": "Jackpot progress", children: _jsx(Progress.Track, { className: twMerge('h-full overflow-hidden rounded-full', variation.progressBg), children: _jsx(Progress.Range, { className: "relative h-full overflow-hidden rounded-full bg-brand-500 pl-1.5", children: _jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-start pl-1.5", "aria-hidden": "true", children: arrowImages }) }) }) }), _jsx("div", { className: "mt-2 h-2 text-left text-[#F5F5F6] text-xs lg:h-auto lg:text-sm", dangerouslySetInnerHTML: { __html: getInfoBlocks()[infoIndex] } }, infoIndex)] })] }), _jsx("div", { className: "z-1 flex items-start gap-5 text-white", children: jackpotPayouts.length ? (_jsxs("div", { className: "flex h-full w-full flex-row items-center justify-between gap-3 lg:w-[280px] lg:flex-col lg:justify-center", children: [_jsx("p", { className: "hidden font-bold text-lg lg:block", children: "Recent Payout \uD83C\uDF89" }), _jsxs("div", { children: [_jsx("p", { className: "mb-1 block font-bold text-[14px] lg:hidden lg:text-lg", children: "Recent Payout \uD83C\uDF89" }), _jsxs("p", { className: "block text-xs leading-[18px] tracking-wider lg:hidden", children: ["Massive payout unlocked! ", _jsx("br", {}), " Who's next? \uD83D\uDCB0"] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: `${variation.topPayoutImgBorderColor} relative flex h-[54px] w-[54px] items-center justify-center rounded-full object-contain p-[3.5px] lg:h-[74px] lg:w-[74px]`, children: [_jsx("div", { className: `flex h-full w-full items-center justify-center rounded-full ${variation.topPayoutImgBg}`, children: _jsx(User02Icon, { className: "h-[34px] w-auto lg:h-[44px]" }) }), _jsx("div", { className: `${variation.topPayoutImgBorderColor} absolute right-[-6px] bottom-[-5px] flex h-8 w-8 items-center justify-center rounded-full p-[2px] lg:right-0 lg:bottom-0`, children: _jsxs("div", { className: `flex h-full w-full items-center justify-center rounded-full font-bold text-[10px] ${variation.topPayoutImgBorderColor} ${variation.textColor} ${variation.multiplierBg} ${variation.multiplierColor}`, children: [jackpotPayouts[0].multiplier, "x"] }) })] }), _jsxs("div", { children: [_jsx("p", { className: "font-semibold text-2xl", children: maskName(jackpotPayouts[0].member.name) }), _jsx("p", { className: `${variation.poolBg} rounded-lg px-2 font-semibold text-[22px] ${variation.textColor}`, children: formatNumber(jackpotPayouts[0].amount, {
149
+ currency: localeInfo.currency.code,
150
+ minDecimalPlaces: 2,
151
+ maxDecimalPlaces: 2,
152
+ }) })] })] }), _jsxs("p", { className: "hidden text-center text-xs leading-[18px] tracking-wider lg:block", children: ["Massive payout unlocked! ", _jsx("br", {}), " Who's next? \uD83D\uDCB0"] })] })) : (_jsxs("div", { className: "flex h-full w-full flex-row-reverse items-center justify-between lg:w-[280px] lg:flex-col lg:justify-center", children: [_jsx(Image, { src: coins, alt: "coins", className: "ml-2", unoptimized: true }), _jsxs("div", { children: [_jsx("p", { className: "mt-1 font-semibold text-lg leading-6", children: "No one has won big yet" }), _jsxs("p", { className: "mt-1 text-start text-[0.75rem] leading-[1.125rem] lg:text-center", children: ["You could be the first to win the ", _jsx("br", {}), " jackpot!"] })] })] })) })] }), isPayingOut ? (_jsx("div", { className: twMerge(styles['light-rays'], variation.raysColor, 'rounded-t-2xl [--light-rays-left:70%] [--light-rays-top:100px]') })) : (_jsx(Image, { width: 175, height: 175, src: treasureChestBg, alt: "treasure chest background", className: twMerge('absolute top-0 right-0 h-full w-[380px] object-cover opacity-50'), priority: false, loading: "lazy", unoptimized: true }))] }), _jsxs("div", { className: "relative flex w-full flex-col items-center rounded-b-2xl bg-[#171b26] px-4", children: [_jsxs("div", { className: "flex w-full justify-between py-4", children: [_jsxs("button", { onClick: () => setSeeDetails((v) => !v), type: "button", className: "flex items-center gap-1 font-medium text-[#fff] text-sm", children: ["See details", ' ', seeDetails ? (_jsx(ChevronUpIcon, { className: "h-5" })) : (_jsx(ChevronDownIcon, { className: "h-5" }))] }), _jsx("button", { type: "button", className: "text-nowrap text-[#FFE5AF] text-sm underline underline-offset-4", children: "Jackpot Rules" })] }), seeDetails && (_jsxs("div", { className: "w-full", children: [_jsxs("div", { children: [_jsx("div", { className: "mt-[6px] flex justify-between text-[#CECFD2] text-lg", children: _jsxs("div", { className: "flex items-center gap-3 font-semibold", children: [_jsx(Image, { src: coin, alt: "coin", className: "h-6", unoptimized: true }), "Recent Payouts"] }) }), _jsx("div", { className: "mt-[1.25rem] mb-[2rem] gap-[0.625rem]", children: _jsx("div", { className: "flex-1 overflow-x-auto rounded-lg border border-[#1F242F]", children: _jsxs("table", { className: "w-full min-w-[700px]", children: [_jsx("thead", { children: _jsx("tr", { className: "h-[44px] bg-[#0C111D] text-[#94969C] text-xs", children: [
153
+ 'Player',
154
+ 'Game Provider',
155
+ 'Multiplier',
156
+ 'Prize',
157
+ 'Timestamp',
158
+ ].map((label) => (_jsx("th", { className: "whitespace-nowrap border-[#1F242F] border-b px-6 py-2 text-left", children: label }, label))) }) }), _jsx("tbody", { children: jackpotPayouts.length
159
+ ? jackpotPayouts
160
+ .filter((jp) => jp.id !== '5HMmGqAZDPqqeFHBmv')
161
+ .map((jp) => (_jsxs("tr", { className: "h-[44px] bg-[#0C111D] text-left text-[#94969C] text-sm", children: [_jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: maskName(jp?.member?.name) }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: formatProviderName(jp?.game.provider ?? '-') }), _jsxs("td", { className: "border-[#1F242F] border-b px-6 py-2", children: [jp?.multiplier, "x"] }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2 text-[#47CD89]", children: formatNumber(jp?.amount ?? 0, {
162
+ currency: localeInfo.currency.code,
163
+ minDecimalPlaces: 2,
164
+ maxDecimalPlaces: 2,
165
+ }) }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: format(new Date(jp.dateTimeCreated), 'dd MMM yyyy h:mm a') })] }, jp.id)))
166
+ : Array.from({ length: 5 }).map((_, i) => (_jsxs("tr", { className: "h-[44px] bg-[#0C111D] text-left text-[#94969C] text-sm", children: [_jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: "-" }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: "-" }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: "-" }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: "-" }), _jsx("td", { className: "border-[#1F242F] border-b px-6 py-2", children: "-" })] }, i))) })] }) }) })] }), _jsx("div", { className: "w-full", children: Boolean(filteredGameProviders.length) && (_jsx(JackpotsListItemGameProviders, { gameProviders: filteredGameProviders, heading: _jsxs("div", { className: "flex items-center gap-3 font-semibold", children: [_jsx(Image, { src: treasureChest, alt: "treasure chest", className: "size-6", unoptimized: true }), "Game Providers"] }) })) })] }))] })] }));
167
+ }
@@ -0,0 +1,6 @@
1
+ import type { ClassNameEntries } from './JackpotsList';
2
+ export interface JackpotsListItemDesktopHappyBingoProps {
3
+ index: number;
4
+ className?: ClassNameEntries;
5
+ }
6
+ export declare function JackpotsListItemHappyBingo({ index, }: JackpotsListItemDesktopHappyBingoProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,167 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Progress } from '@ark-ui/react/progress';
4
+ import { format } from 'date-fns';
5
+ import isMobile from 'is-mobile';
6
+ import Image from 'next/image';
7
+ import { useCallback, useEffect, useMemo, useState } from 'react';
8
+ import { twMerge } from 'tailwind-merge';
9
+ import { useIntersectionObserver } from 'usehooks-ts';
10
+ import { useJackpotPayoutsQuery } from '../../../client/hooks/useJackpotPayoutsQuery.js';
11
+ import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
12
+ import { ChevronDownIcon } from '../../../icons/ChevronDownIcon.js';
13
+ import { ChevronLeftIcon } from '../../../icons/ChevronLeftIcon.js';
14
+ import { ChevronRightIcon } from '../../../icons/ChevronRightIcon.js';
15
+ import { ChevronUpIcon } from '../../../icons/ChevronUpIcon.js';
16
+ import { User02Icon } from '../../../icons/User02Icon.js';
17
+ import starTwo from '../../../images/3d-star.webp';
18
+ import treasureChestBg from '../../../images/chest-bg.webp';
19
+ import coins from '../../../images/happy-bingo-coins.webp';
20
+ import star from '../../../images/star.webp';
21
+ import treasureChest from '../../../images/treasure.webp';
22
+ import { formatNumber } from '../../../utils/formatNumber.js';
23
+ import { getPercentage } from '../../../utils/getPercentage.js';
24
+ import styles from '../Jackpots.module.css';
25
+ import { formatProviderName, HAPPYBINGO_JACKPOTS_VARIATIONS, maskName } from '../utils.js';
26
+ import { useJackpotsListItemContext } from './JackpotsListContext.js';
27
+ import { JackpotsListItemGameProviders } from './JackpotsListItemGameProviders.js';
28
+ import { useJackpotsListItemData } from './useJackpotsListItemData.js';
29
+ export function JackpotsListItemHappyBingo({ index, }) {
30
+ const jackpot = useJackpotsListItemContext();
31
+ const localeInfo = useLocaleInfo();
32
+ const { getAccumulatingJackpotDescription, filteredGameProviders } = useJackpotsListItemData();
33
+ const jackpotPayoutsQuery = useJackpotPayoutsQuery({
34
+ first: 30,
35
+ filter: {
36
+ jackpot: {
37
+ equal: jackpot.id,
38
+ },
39
+ },
40
+ });
41
+ const [ref] = useIntersectionObserver({
42
+ threshold: 0.5,
43
+ rootMargin: '50px',
44
+ });
45
+ const [infoIndex, setInfoIndex] = useState(0);
46
+ const [seeDetails, setSeeDetails] = useState(false);
47
+ const [mainTooltipOpen, setMainTooltipOpen] = useState(false);
48
+ const isPayingOut = jackpot.drawing;
49
+ const jackpotAmount = jackpot.pool;
50
+ const jackpotPayouts = jackpotPayoutsQuery.data?.pages[0].edges.map((edge) => edge.node) ?? [];
51
+ const variation = HAPPYBINGO_JACKPOTS_VARIATIONS[index % HAPPYBINGO_JACKPOTS_VARIATIONS.length];
52
+ const isMobileDevice = useMemo(() => isMobile(), []);
53
+ const getInfoBlocks = useCallback(() => {
54
+ return [
55
+ `Current Jackpot: <b>${formatNumber(jackpotAmount, {
56
+ currency: localeInfo.currency.code,
57
+ minDecimalPlaces: 2,
58
+ maxDecimalPlaces: 2,
59
+ })}</b>`,
60
+ `Minimum Payout Limit: <b>${formatNumber(jackpot.minimumJackpotPoolDrawingLimit, {
61
+ currency: localeInfo.currency.code,
62
+ minDecimalPlaces: 2,
63
+ maxDecimalPlaces: 2,
64
+ })}</b>`,
65
+ `Maximum Payout Limit: <b>${formatNumber(jackpot.maximumJackpotPoolLimit, {
66
+ currency: localeInfo.currency.code,
67
+ minDecimalPlaces: 2,
68
+ maxDecimalPlaces: 2,
69
+ })}</b>`,
70
+ isPayingOut
71
+ ? `The pot has hit <b>${formatNumber(jackpot.maximumJackpotPoolLimit, {
72
+ currency: localeInfo.currency.code,
73
+ minDecimalPlaces: 2,
74
+ maxDecimalPlaces: 2,
75
+ })}</b> Play now for your chance to win big! πŸ”₯`
76
+ : getAccumulatingJackpotDescription(Number(jackpot.pool), Number(jackpot.maximumJackpotPoolLimit)),
77
+ ];
78
+ }, [
79
+ isPayingOut,
80
+ jackpot,
81
+ jackpotAmount,
82
+ localeInfo,
83
+ getAccumulatingJackpotDescription,
84
+ ]);
85
+ const Arrow = useCallback(({ index }) => {
86
+ const Icon = isPayingOut ? ChevronLeftIcon : ChevronRightIcon;
87
+ return (_jsx(Icon, { className: twMerge('min-w-2.5 scale-400 text-brand-300 lg:min-w-4 lg:scale-250', isPayingOut
88
+ ? styles['animate-wave-color-error']
89
+ : styles['animate-wave-color-success']), style: {
90
+ animationDelay: isPayingOut
91
+ ? `${(40 - index - 1) * 0.1}s`
92
+ : `${index * 0.1}s`,
93
+ } }));
94
+ }, [isPayingOut]);
95
+ const arrowImages = useMemo(() => Array.from({ length: 40 }, (_, i) => _jsx(Arrow, { index: i }, i)), [Arrow]);
96
+ useEffect(() => {
97
+ const interval = setInterval(() => {
98
+ setInfoIndex((i) => (i + 1) % getInfoBlocks().length);
99
+ }, 4000);
100
+ return () => clearInterval(interval);
101
+ }, [getInfoBlocks]);
102
+ useEffect(() => {
103
+ if (isMobileDevice && mainTooltipOpen) {
104
+ const timeout = setTimeout(() => setMainTooltipOpen(false), 3000);
105
+ return () => clearTimeout(timeout);
106
+ }
107
+ }, [mainTooltipOpen, isMobileDevice]);
108
+ if (jackpot.status === 'DISABLED' && jackpot.drawing !== true) {
109
+ return null;
110
+ }
111
+ return (_jsxs("div", { className: "w-full shrink-0", children: [_jsxs("div", { ref: ref, className: twMerge('relative flex w-full shrink-0 rounded-t-2xl p-3 text-center lg:gap-4 lg:p-5', variation.background), children: [_jsxs("div", { className: "flex w-full flex-col gap-6 lg:flex-row lg:gap-0", children: [_jsxs("div", { className: "relative z-1 flex flex-1 flex-col", children: [[
112
+ [
113
+ styles['flicker-scale-fade-2'],
114
+ 'absolute right-[38%] top-[2%] h-2 w-2 delay-75',
115
+ ],
116
+ [
117
+ styles['flicker-scale-fade'],
118
+ 'absolute right-[20%] top-[10%] h-3 w-3',
119
+ ],
120
+ [
121
+ styles['flicker-scale-fade-2'],
122
+ 'absolute right-[30%] top-[10%] h-5 w-5',
123
+ ],
124
+ [
125
+ styles['flicker-scale-fade'],
126
+ 'absolute right-[36%] top-[35%] h-3 w-3',
127
+ ],
128
+ [
129
+ styles['flicker-scale-fade'],
130
+ 'absolute right-[15%] top-[56%] h-3 w-3',
131
+ ],
132
+ [
133
+ styles['flicker-scale-fade-2'],
134
+ 'absolute right-[50%] top-[55%] h-4 w-4',
135
+ ],
136
+ ].map(([animationClass, positionClass], i) => (_jsx(Image, { src: star, alt: "star", draggable: "false", className: twMerge(animationClass, positionClass), unoptimized: true }, i))), _jsx("div", { className: "flex h-full flex-col justify-between", children: _jsx("div", { className: "flex w-full justify-between", children: _jsx("div", { className: "flex w-full flex-col", children: _jsxs("div", { className: "relative flex w-full justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "mb-2 flex gap-1 font-medium", children: _jsxs("div", { className: twMerge('flex w-fit items-center justify-center gap-1 rounded-[10px] border border-[#FECDCA] bg-[#FEF3F2] px-2.5 py-1 text-sm'), children: [_jsx("div", { className: twMerge('h-[6px] w-[6px] animate-color rounded-full', isPayingOut
137
+ ? styles['pulse-error']
138
+ : styles['pulse-success']) }), _jsx("div", { className: twMerge('rounded text-[#344054]'), children: isPayingOut ? 'Paying Out' : 'Accumulating' })] }) }), _jsx("div", { className: "mb-2 text-left font-semibold text-[18px] text-white lg:mb-0 lg:text-2xl", children: jackpot?.name }), _jsx("div", { className: `${variation.poolBg} ${variation.textColor} flex w-fit rounded-lg px-2 font-semibold text-[26px] lg:text-[36px]`, children: formatNumber(jackpotAmount, {
139
+ currency: localeInfo.currency.code,
140
+ minDecimalPlaces: 2,
141
+ maxDecimalPlaces: 2,
142
+ }) })] }), _jsx(Image, { width: 175, height: 175, src: treasureChest, alt: "treasure chest", className: twMerge('absolute top-[0px] right-[-3px] h-[124px] w-[124px] md:top-0 lg:top-[-30px] lg:h-[175px] lg:w-[175px]'), priority: false, loading: "lazy", unoptimized: true })] }) }) }) }), _jsxs("div", { className: "mt-3 lg:mt-4", children: [_jsxs("div", { className: "mb-1 flex justify-between", children: [_jsx("div", { className: "font-semibold text-text-primary-900 text-xs", "aria-live": "polite", children: formatNumber(0, {
143
+ currency: localeInfo.currency.code,
144
+ compact: true,
145
+ }) }), _jsxs("div", { className: "relative flex items-center justify-end gap-1.5", children: [isPayingOut ? (_jsx("div", { className: "flex w-6 items-center", children: [0, 1.5, 3].map((left, i) => (_jsx("div", { className: twMerge(`absolute left-${left}`, styles[`animate-arrow-red-flash-${i + 1}`]), children: _jsx(ChevronLeftIcon, { className: "size-4.5" }) }, i))) })) : (_jsx("div", { className: "flex w-6 items-center", children: [0, 1.5, 3].map((left, i) => (_jsx("div", { className: twMerge(`absolute left-${left}`, styles[`animate-arrow-green-flash-${i + 1}`]), children: _jsx(ChevronRightIcon, { className: "size-4.5" }) }, i))) })), _jsx("div", { className: "font-semibold text-text-primary-900 text-xs", children: formatNumber(jackpot?.maximumJackpotPoolLimit, {
146
+ currency: localeInfo.currency.code,
147
+ compact: true,
148
+ }) })] })] }), _jsx(Progress.Root, { className: "h-2 w-full rounded-full bg-bg-primary lg:h-4", max: 100, value: getPercentage(jackpot.pool, jackpot.maximumJackpotPoolLimit), "aria-valuenow": getPercentage(jackpot.pool, jackpot.maximumJackpotPoolLimit), "aria-valuemax": 100, "aria-label": "Jackpot progress", children: _jsx(Progress.Track, { className: twMerge('h-full overflow-hidden rounded-full', variation.progressBg), children: _jsx(Progress.Range, { className: "relative h-full overflow-hidden rounded-full bg-brand-500 pl-1.5", children: _jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-start pl-1.5", "aria-hidden": "true", children: arrowImages }) }) }) }), _jsx("div", { className: "mt-2 h-2 text-left text-[#F5F5F6] text-xs lg:h-auto lg:text-sm", dangerouslySetInnerHTML: { __html: getInfoBlocks()[infoIndex] } }, infoIndex)] })] }), _jsx("div", { className: "z-1 flex items-start gap-5 text-white", children: jackpotPayouts.length ? (_jsxs("div", { className: "flex h-full w-full flex-row items-center justify-between gap-3 lg:w-[280px] lg:flex-col lg:justify-center", children: [_jsx("p", { className: "hidden font-bold text-lg lg:block", children: "Recent Payout \uD83C\uDF89" }), _jsxs("div", { children: [_jsx("p", { className: "mb-1 block font-bold text-[14px] lg:hidden lg:text-lg", children: "Recent Payout \uD83C\uDF89" }), _jsxs("p", { className: "block text-xs leading-[18px] tracking-wider lg:hidden", children: ["Massive payout unlocked! ", _jsx("br", {}), " Who's next? \uD83D\uDCB0"] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: `${variation.topPayoutImgBorderColor} relative flex h-[54px] w-[54px] items-center justify-center rounded-full object-contain p-[3.5px] lg:h-[74px] lg:w-[74px]`, children: [_jsx("div", { className: `flex h-full w-full items-center justify-center rounded-full ${variation.topPayoutImgBg}`, children: _jsx(User02Icon, { className: "h-[34px] w-auto lg:h-[44px]" }) }), _jsx("div", { className: `${variation.topPayoutImgBorderColor} absolute right-[-6px] bottom-[-5px] flex h-8 w-8 items-center justify-center rounded-full p-[2px] lg:right-0 lg:bottom-0`, children: _jsxs("div", { className: `flex h-full w-full items-center justify-center rounded-full font-bold text-[10px] ${variation.topPayoutImgBorderColor} ${variation.textColor} ${variation.multiplierBg} ${variation.multiplierColor}`, children: [jackpotPayouts[0].multiplier, "x"] }) })] }), _jsxs("div", { children: [_jsx("p", { className: "font-semibold text-2xl", children: maskName(jackpotPayouts[0].member.name) }), _jsx("p", { className: `${variation.poolBg} rounded-lg px-2 font-semibold text-[22px] ${variation.textColor}`, children: formatNumber(jackpotPayouts[0].amount, {
149
+ currency: localeInfo.currency.code,
150
+ minDecimalPlaces: 2,
151
+ maxDecimalPlaces: 2,
152
+ }) })] })] }), _jsxs("p", { className: "hidden text-center text-xs leading-[18px] tracking-wider lg:block", children: ["Massive payout unlocked! ", _jsx("br", {}), " Who's next? \uD83D\uDCB0"] })] })) : (_jsxs("div", { className: "flex h-full w-full flex-row-reverse items-center justify-between lg:w-[280px] lg:flex-col lg:justify-center", children: [_jsx(Image, { src: coins, alt: "coins", className: "ml-2", unoptimized: true }), _jsxs("div", { children: [_jsx("p", { className: "mt-1 font-semibold text-lg leading-6", children: "No one has won big yet" }), _jsxs("p", { className: "mt-1 text-start text-[0.75rem] leading-[1.125rem] lg:text-center", children: ["You could be the first to win the ", _jsx("br", {}), " jackpot!"] })] })] })) })] }), isPayingOut ? (_jsx("div", { className: twMerge(styles['light-rays'], variation.raysColor, 'rounded-t-2xl [--light-rays-left:70%] [--light-rays-top:100px]') })) : (_jsx(Image, { width: 175, height: 175, src: treasureChestBg, alt: "treasure chest background", className: twMerge('absolute top-0 right-0 h-full w-[380px] object-cover opacity-50'), priority: false, loading: "lazy", unoptimized: true }))] }), _jsxs("div", { className: "relative flex w-full flex-col items-center rounded-b-2xl bg-white px-4 text-[#475467] dark:bg-[#161B26] dark:text-[#94969C]", children: [_jsxs("div", { className: "flex w-full justify-between py-3", children: [_jsxs("button", { onClick: () => setSeeDetails((v) => !v), type: "button", className: "flex items-center gap-1 font-medium text-sm", children: ["See details", ' ', seeDetails ? (_jsx(ChevronUpIcon, { className: "h-5" })) : (_jsx(ChevronDownIcon, { className: "h-5" }))] }), _jsx("button", { type: "button", className: "inline-flex h-9 items-center justify-center gap-1.5 text-nowrap rounded-lg border border-[#EAAA08] bg-white px-4 py-2.5 font-semibold text-[#A15C07] text-sm text-sm shadow-xs transition-colors duration-200 hover:border-[#FDE272] hover:bg-[#FEFBE8] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:border-[#EAAA08] disabled:hover:bg-white dark:border-[#333741] dark:bg-[#161B26] dark:text-[#CECFD2] dark:disabled:hover:border-[#333741] dark:disabled:hover:bg-[#161B26]", children: "Jackpot Rules" })] }), seeDetails && (_jsxs("div", { className: "w-full", children: [_jsxs("div", { children: [_jsx("div", { className: "mt-[6px] flex justify-between text-[#344054] text-lg dark:text-[#CECFD2]", children: _jsxs("div", { className: "flex items-center gap-3 font-semibold", children: [_jsx(Image, { src: starTwo, alt: "3d star", className: "size-6", unoptimized: true }), "Recent Payouts"] }) }), _jsx("div", { className: "mt-[1.25rem] mb-[2rem] gap-[0.625rem]", children: _jsx("div", { className: "w-full max-w-full overflow-x-auto overflow-y-hidden whitespace-nowrap rounded-xl border border-[#eaecf0] dark:border-[#1f242f]", children: _jsxs("table", { className: "w-full min-w-[700px]", children: [_jsx("thead", { className: "border-[#EAECF0] border-b dark:border-[#1F242F]", children: _jsx("tr", { className: "border-[#EAECF0] border-b bg-white px-0 last:border-b-0 odd:bg-[#F9FAFB] dark:border-[#1F242F] dark:bg-[#0C111D] dark:odd:bg-[#0C111D]", children: [
153
+ 'Player',
154
+ 'Game Provider',
155
+ 'Multiplier',
156
+ 'Prize',
157
+ 'Timestamp',
158
+ ].map((label) => (_jsx("th", { className: "bg-white px-3xl py-lg text-left font-medium text-[#475467] text-xs dark:bg-[#0C111D] dark:text-[#94969C]", children: label }, label))) }) }), _jsx("tbody", { children: jackpotPayouts.length
159
+ ? jackpotPayouts
160
+ .filter((jp) => jp.id !== '5HMmGqAZDPqqeFHBmv')
161
+ .map((jp) => (_jsxs("tr", { className: "border-[#EAECF0] border-b bg-white last:border-b-0 odd:bg-[#F9FAFB] dark:border-[#1F242F] dark:bg-[#0C111D] dark:odd:bg-[#0C111D]", children: [_jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: maskName(jp?.member?.name) }), _jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: formatProviderName(jp?.game.provider ?? '-') }), _jsxs("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: [jp?.multiplier, "x"] }), _jsx("td", { className: "px-3xl py-xl text-left text-[#079455] text-sm dark:text-[#47CD89]", children: formatNumber(jp?.amount ?? 0, {
162
+ currency: localeInfo.currency.code,
163
+ minDecimalPlaces: 2,
164
+ maxDecimalPlaces: 2,
165
+ }) }), _jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: format(new Date(jp.dateTimeCreated), 'dd MMM yyyy h:mm a') })] }, jp.id)))
166
+ : Array.from({ length: 5 }).map((_, i) => (_jsxs("tr", { className: "h-[44px] bg-[#0C111D] text-left text-[#94969C] text-sm", children: [_jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: "-" }), _jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: "-" }), _jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: "-" }), _jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: "-" }), _jsx("td", { className: "px-3xl py-xl text-left text-[#475467] text-sm dark:text-[#94969C]", children: "-" })] }, i))) })] }) }) })] }), _jsx("div", { className: "w-full", children: Boolean(filteredGameProviders.length) && (_jsx(JackpotsListItemGameProviders, { gameProviders: filteredGameProviders, heading: _jsxs("div", { className: "flex items-center gap-3 font-semibold text-[#344054] dark:text-[#CECFD2]", children: [_jsx(Image, { src: treasureChest, alt: "treasure chest", className: "size-6", unoptimized: true }), "Jackpot Game Provider"] }) })) })] }))] })] }));
167
+ }
@@ -1,11 +1,13 @@
1
1
  import { type ImageProps } from 'next/image';
2
+ import { type ReactNode } from 'react';
2
3
  import type { GameProviderData } from '../../../types';
3
4
  interface JackpotGameProvider extends GameProviderData {
4
5
  redirectUrl: string;
5
6
  providedLogo?: ImageProps['src'];
6
7
  }
7
8
  export interface JackpotsListItemGameProvidersProps {
9
+ heading?: string | ReactNode;
8
10
  gameProviders: JackpotGameProvider[];
9
11
  }
10
- export declare function JackpotsListItemGameProviders({ gameProviders, }: JackpotsListItemGameProvidersProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function JackpotsListItemGameProviders({ heading, gameProviders, }: JackpotsListItemGameProvidersProps): import("react/jsx-runtime").JSX.Element;
11
13
  export {};
@@ -9,7 +9,7 @@ import { ArrowLeftIcon } from '../../../icons/ArrowLeftIcon.js';
9
9
  import { ArrowRightIcon } from '../../../icons/ArrowRightIcon.js';
10
10
  import { Button } from '../../../ui/Button/index.js';
11
11
  import { useJackpotsListPropsContext } from './JackpotsListContext.js';
12
- export function JackpotsListItemGameProviders({ gameProviders, }) {
12
+ export function JackpotsListItemGameProviders({ heading, gameProviders, }) {
13
13
  const jackpotsProps = useJackpotsListPropsContext();
14
14
  const classNames = isString(jackpotsProps.className)
15
15
  ? { root: jackpotsProps.className }
@@ -41,5 +41,5 @@ export function JackpotsListItemGameProviders({ gameProviders, }) {
41
41
  emblaApi.on('select', onSelect);
42
42
  emblaApi.on('reInit', onSelect);
43
43
  }, [emblaApi, onSelect]);
44
- return (_jsxs("div", { className: twMerge('p-4 pb-8', classNames.providerRoot), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: twMerge('font-semibold text-lg text-text-primary-900', classNames.providerHeading), children: "Jackpot Game Providers" }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { disabled: !canScrollPrev, onClick: scrollPrev, variant: "outline", colorScheme: "gray", className: twMerge('rounded-r-none border-r-0', classNames.providerNavigationButton), "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsxs(Button, { disabled: !canScrollNext, onClick: scrollNext, variant: "outline", colorScheme: "gray", className: twMerge('rounded-l-none', classNames.providerNavigationButton), "aria-label": "Next", children: [_jsx("span", { className: "sr-only", children: "Next" }), _jsx(ArrowRightIcon, { className: "size-5" })] })] })] }), _jsx("div", { className: "relative mt-3 overflow-hidden", ref: emblaRef, children: _jsx("div", { className: "flex gap-3.5", children: gameProviders.map((provider) => (_jsx(Link, { href: provider.redirectUrl, className: twMerge('min-w-27.5 rounded-md bg-brand-800 lg:bg-bg-primary-900', classNames.providerThumbnailRoot), children: _jsx(Image, { src: provider.providedLogo ?? provider.logo, alt: "provider", className: twMerge('size-full', classNames.providerThumbnailImage), width: 300, height: 150 }) }, provider.slug))) }) })] }));
44
+ return (_jsxs("div", { className: twMerge('p-4 pb-8', classNames.providerRoot), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: twMerge('font-semibold text-lg text-text-primary-900', classNames.providerHeading), children: heading ?? 'Jackpot Game Providers' }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { disabled: !canScrollPrev, onClick: scrollPrev, variant: "outline", colorScheme: "gray", className: twMerge('rounded-r-none border-r-0', classNames.providerNavigationButton), "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsxs(Button, { disabled: !canScrollNext, onClick: scrollNext, variant: "outline", colorScheme: "gray", className: twMerge('rounded-l-none', classNames.providerNavigationButton), "aria-label": "Next", children: [_jsx("span", { className: "sr-only", children: "Next" }), _jsx(ArrowRightIcon, { className: "size-5" })] })] })] }), _jsx("div", { className: "relative mt-3 overflow-hidden", ref: emblaRef, children: _jsx("div", { className: "flex gap-3.5", children: gameProviders.map((provider) => (_jsx(Link, { href: provider.redirectUrl, className: twMerge('min-w-27.5 rounded-md bg-brand-800 lg:bg-bg-primary-900', classNames.providerThumbnailRoot), children: _jsx(Image, { src: provider.providedLogo ?? provider.logo, alt: "provider", className: twMerge('size-full', classNames.providerThumbnailImage), width: 300, height: 150 }) }, provider.slug))) }) })] }));
45
45
  }
@@ -1,4 +1,4 @@
1
- export declare const JACKPOTS_VARIATIONS: {
1
+ export declare const CRAZYWIN_JACKPOTS_VARIATIONS: {
2
2
  background: string;
3
3
  progressBg: string;
4
4
  textColor: string;
@@ -9,3 +9,17 @@ export declare const JACKPOTS_VARIATIONS: {
9
9
  topPayoutImgBg: string;
10
10
  raysColor: string;
11
11
  }[];
12
+ export declare const HAPPYBINGO_JACKPOTS_VARIATIONS: {
13
+ background: string;
14
+ progressBg: string;
15
+ textColor: string;
16
+ poolBg: string;
17
+ multiplierColor: string;
18
+ multiplierBg: string;
19
+ topPayoutImgBorderColor: string;
20
+ topPayoutImgBg: string;
21
+ raysColor: string;
22
+ }[];
23
+ export declare function formatProviderName(provider: string): string;
24
+ export declare const maskName: (name: string) => string;
25
+ export declare const getAccumulatingJackpotDescription: (part: number, total: number) => string;
@@ -1,4 +1,4 @@
1
- export const JACKPOTS_VARIATIONS = [
1
+ export const CRAZYWIN_JACKPOTS_VARIATIONS = [
2
2
  // Green
3
3
  {
4
4
  background: 'bg-[linear-gradient(241.67deg,#1A534C_1.19%,#051B29_100%)]',
@@ -36,3 +36,61 @@ export const JACKPOTS_VARIATIONS = [
36
36
  raysColor: '[--color-jackpot-rays-primary:#c04e48] [--color-jackpot-rays-secondary:#8f2731]',
37
37
  },
38
38
  ];
39
+ export const HAPPYBINGO_JACKPOTS_VARIATIONS = [
40
+ // Orange
41
+ {
42
+ background: 'bg-[linear-gradient(241.67deg,#FFD238_1.19%,#FF7D02_100%)]',
43
+ progressBg: 'bg-[#CA8504]',
44
+ textColor: 'text-[#713B12]',
45
+ poolBg: 'bg-[linear-gradient(180deg,#FFDE21_0%,#FFD012_47%,#FFBF00_100%)]',
46
+ multiplierColor: 'text-[#713B12]',
47
+ multiplierBg: 'bg-[linear-gradient(241.67deg,#FFD238_1.19%,#FF7D02_100%)]',
48
+ topPayoutImgBorderColor: 'bg-[linear-gradient(180deg,#FFDE21_28.33%,#FFBF00_57.84%,#FF9442_100%)]',
49
+ topPayoutImgBg: 'bg-[#FFD238]',
50
+ raysColor: '[--color-rays-primary:#f2ac25] [--color-rays-secondary:#febb2a]',
51
+ },
52
+ // Purple
53
+ {
54
+ background: 'bg-[linear-gradient(45deg,#4300B1_0%,#A531DC_100%)]',
55
+ progressBg: 'bg-[#B485FF]',
56
+ textColor: 'text-[#fff]',
57
+ poolBg: 'bg-[linear-gradient(180deg,#9E77ED_0%,#8057D9_100%)]',
58
+ multiplierBg: 'bg-[linear-gradient(45deg,_#4300B1_0%,_#A531DC_100%)]',
59
+ multiplierColor: 'text-[#fff]',
60
+ topPayoutImgBorderColor: 'bg-[linear-gradient(180deg,#9E77ED_0%,#8057D9_100%)]',
61
+ topPayoutImgBg: 'bg-[#5E0DBD]',
62
+ raysColor: '[--color-rays-primary:#8222c6] [--color-rays-secondary:#8e24d2]',
63
+ },
64
+ // Blue
65
+ {
66
+ background: 'bg-[linear-gradient(241.67deg,#01C1FA_1.19%,#015EEA_100%)]',
67
+ progressBg: 'bg-[#01C4FB]',
68
+ textColor: 'text-[#344054]',
69
+ poolBg: 'bg-[linear-gradient(180deg,_#89F7FE_0%,_#66A6FF_100%)]',
70
+ multiplierBg: 'bg-[linear-gradient(241.67deg,_#01C1FA_1.19%,_#015EEA_100%)]',
71
+ multiplierColor: 'text-[#fff]',
72
+ topPayoutImgBorderColor: 'bg-[linear-gradient(180deg,_#89F7FE_0%,_#66A6FF_100%)]',
73
+ topPayoutImgBg: 'bg-[#01C1FA]',
74
+ raysColor: '[--color-rays-primary:#17a6f6] [--color-rays-secondary:#159ce9]',
75
+ },
76
+ ];
77
+ export function formatProviderName(provider) {
78
+ return provider
79
+ .split('_')
80
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
81
+ .join(' ');
82
+ }
83
+ export const maskName = (name) => {
84
+ if (name.length <= 7) {
85
+ return '*'.repeat(name.length);
86
+ }
87
+ const visiblePart = name.slice(0, 3);
88
+ const maskedPart = '*'.repeat(7);
89
+ return visiblePart + maskedPart;
90
+ };
91
+ export const getAccumulatingJackpotDescription = (part, total) => {
92
+ const percentage = total === 0 ? 0 : (part / total) * 100;
93
+ return percentage <= 90
94
+ ? 'The jackpot is heating up! Keep playing to stay in the action and watch it grow!'
95
+ : 'πŸ”₯ It’s about to pop! Stay in the game for your shot at the prize!';
96
+ };
@@ -2,6 +2,9 @@ import type { Cashback as TCashback } from '../../types';
2
2
  interface CashbackProps {
3
3
  data: TCashback;
4
4
  viewDetailsUrl: string;
5
+ hasPromotionPeriod?: boolean;
6
+ roundedButtons?: boolean;
7
+ textOrientation?: 'left' | 'center';
5
8
  }
6
- export declare function Cashback({ data, viewDetailsUrl }: CashbackProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function Cashback({ data, viewDetailsUrl, hasPromotionPeriod, roundedButtons, textOrientation, }: CashbackProps): import("react/jsx-runtime").JSX.Element;
7
10
  export {};
@@ -1,18 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Image from 'next/image';
3
3
  import Link from 'next/link';
4
+ import { twMerge } from 'tailwind-merge';
4
5
  import { useShallow } from 'zustand/shallow';
5
6
  import { useAvailablePromosQuery } from '../../client/hooks/useAvailablePromosQuery.js';
6
7
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
7
8
  import { Button } from '../../ui/Button/index.js';
8
- export function Cashback({ data, viewDetailsUrl }) {
9
+ import { formatPromotionPeriod } from './utils.js';
10
+ export function Cashback({ data, viewDetailsUrl, hasPromotionPeriod, roundedButtons, textOrientation = 'center', }) {
9
11
  const globalStore = useGlobalStore(useShallow((ctx) => ({
10
12
  depositWithdrawal: ctx.depositWithdrawal,
11
13
  })));
12
14
  const claimablePromos = useAvailablePromosQuery().data ?? [];
13
15
  const claimable = claimablePromos.find((availablePromo) => availablePromo.id === data.id);
14
- return (_jsxs("div", { className: "relative flex h-full flex-col overflow-hidden rounded-2xl border border-border-secondary bg-accent-50 bg-bg-primary-alt", children: [data.banner?.url && (_jsx(Image, { src: data.banner.url, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" })), _jsxs("div", { className: "flex flex-grow flex-col px-4 pt-2xl pb-3xl", children: [_jsx("div", { className: "w-full grow text-center font-semibold text-xl", children: data.name }), _jsxs("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: [claimable && (_jsx(Button, { size: "sm", onClick: () => {
16
+ const promotionPeriod = formatPromotionPeriod(data.activationStartDateTime, data.activationEndDateTime);
17
+ return (_jsxs("div", { className: "relative flex h-full flex-col overflow-hidden rounded-2xl border border-border-secondary bg-accent-50 bg-bg-primary-alt", children: [data.banner?.url && (_jsx(Image, { src: data.banner.url, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" })), hasPromotionPeriod && (_jsxs("div", { className: "bg-black py-1.5 text-center font-bold text-3xs uppercase", children: ["PROMOTION PERIOD: ", promotionPeriod] })), _jsxs("div", { className: "flex flex-grow flex-col px-4 pt-2xl pb-3xl", children: [_jsx("div", { className: twMerge('w-full grow font-semibold text-xl', textOrientation === 'center' ? 'text-center' : 'text-left'), children: data.name }), _jsxs("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: [claimable && (_jsx(Button, { size: "sm", onClick: () => {
15
18
  globalStore.depositWithdrawal.setOpen(true);
16
19
  globalStore.depositWithdrawal.setPromo(data.id);
17
- }, children: "Get bonus" })), _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsxs(Link, { href: `${viewDetailsUrl}/${data.id}`, children: ["Read more", _jsxs("span", { className: "sr-only", children: [" about ", data.name] })] }) })] })] })] }));
20
+ }, children: "Get bonus" })), _jsx(Button, { size: "sm", variant: "outline", asChild: true, className: roundedButtons ? 'rounded-full' : '', children: _jsxs(Link, { href: `${viewDetailsUrl}/${data.id}`, children: ["Read more", _jsxs("span", { className: "sr-only", children: [" about ", data.name] })] }) })] })] })] }));
18
21
  }
@@ -2,6 +2,8 @@ import type { CustomPromo as TCustomPromo } from '../../types';
2
2
  interface CustomPromoProps {
3
3
  data: TCustomPromo;
4
4
  viewDetailsUrl: string;
5
+ roundedButtons?: boolean;
6
+ textOrientation?: 'left' | 'center';
5
7
  }
6
- export declare function CustomPromo({ data, viewDetailsUrl }: CustomPromoProps): import("react/jsx-runtime").JSX.Element;
8
+ export declare function CustomPromo({ data, viewDetailsUrl, roundedButtons, textOrientation, }: CustomPromoProps): import("react/jsx-runtime").JSX.Element;
7
9
  export {};
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Image from 'next/image';
3
3
  import Link from 'next/link';
4
+ import { twMerge } from 'tailwind-merge';
4
5
  import { Button } from '../../ui/Button/index.js';
5
- export function CustomPromo({ data, viewDetailsUrl }) {
6
- return (_jsxs("div", { className: "relative flex h-full flex-col overflow-hidden rounded-2xl border border-border-secondary bg-accent-50 bg-bg-primary-alt", children: [_jsx(Image, { src: data.banner, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" }), _jsxs("div", { className: "flex flex-grow flex-col px-4 pt-2xl pb-3xl", children: [_jsx("div", { className: "w-full grow text-center font-semibold text-xl", children: data.name }), _jsx("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsxs(Link, { href: `${viewDetailsUrl}/${data.id}`, children: ["Read more", _jsxs("span", { className: "sr-only", children: [" about ", data.name] })] }) }) })] })] }));
6
+ export function CustomPromo({ data, viewDetailsUrl, roundedButtons, textOrientation = 'center', }) {
7
+ return (_jsxs("div", { className: "relative flex h-full flex-col overflow-hidden rounded-2xl border border-border-secondary bg-accent-50 bg-bg-primary-alt", children: [_jsx(Image, { src: data.banner, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" }), _jsxs("div", { className: "flex flex-grow flex-col px-4 pt-2xl pb-3xl", children: [_jsx("div", { className: twMerge('w-full grow font-semibold text-xl', textOrientation === 'center' ? 'text-center' : 'text-left'), children: data.name }), _jsx("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: _jsx(Button, { size: "sm", variant: "outline", asChild: true, className: roundedButtons ? 'rounded-full' : '', children: _jsxs(Link, { href: `${viewDetailsUrl}/${data.id}`, children: ["Read more", _jsxs("span", { className: "sr-only", children: [" about ", data.name] })] }) }) })] })] }));
7
8
  }
@@ -2,6 +2,9 @@ import type { Promo as TPromo } from '../../types';
2
2
  interface PromoProps {
3
3
  data: TPromo;
4
4
  viewDetailsUrl: string;
5
+ hasPromotionPeriod?: boolean;
6
+ roundedButtons?: boolean;
7
+ textOrientation?: 'left' | 'center';
5
8
  }
6
- export declare function Promo({ data, viewDetailsUrl }: PromoProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function Promo({ data, viewDetailsUrl, hasPromotionPeriod, roundedButtons, textOrientation, }: PromoProps): import("react/jsx-runtime").JSX.Element;
7
10
  export {};