@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
@@ -1,7 +1,7 @@
1
1
  export declare const OnlineBankDepositContext: (props: {
2
2
  value: {
3
3
  view: "form" | "vca";
4
- status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
4
+ status: "waiting" | "failed" | "processing" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
5
5
  verify: () => void;
6
6
  reset: () => void;
7
7
  deposit: import("../../../../types").Deposit | null;
@@ -14,7 +14,7 @@ export declare const OnlineBankDepositContext: (props: {
14
14
  children?: import("react").ReactNode | undefined;
15
15
  }) => React.ReactNode, useOnlineBankDepositContext: () => {
16
16
  view: "form" | "vca";
17
- status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
17
+ status: "waiting" | "failed" | "processing" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
18
18
  verify: () => void;
19
19
  reset: () => void;
20
20
  deposit: import("../../../../types").Deposit | null;
@@ -2,7 +2,7 @@ import type { Deposit } from '../../../../types';
2
2
  export type UseOnlineBankDepositReturn = ReturnType<typeof useOnlineBankDeposit>;
3
3
  export declare function useOnlineBankDeposit(): {
4
4
  view: "form" | "vca";
5
- status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
5
+ status: "waiting" | "failed" | "processing" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
6
6
  verify: () => void;
7
7
  reset: () => void;
8
8
  deposit: Deposit | null;
@@ -1,6 +1,6 @@
1
1
  export declare const QRPHDepositContext: (props: {
2
2
  value: {
3
- status: "failed" | "idle" | "generating-qr-code" | "qr-code-generated" | "confirmed";
3
+ status: "idle" | "generating-qr-code" | "qr-code-generated" | "failed" | "confirmed";
4
4
  deposit: import("../../../../types").Deposit | null;
5
5
  errorMessage: {
6
6
  name: string;
@@ -13,7 +13,7 @@ export declare const QRPHDepositContext: (props: {
13
13
  } & {
14
14
  children?: import("react").ReactNode | undefined;
15
15
  }) => React.ReactNode, useQRPHDepositContext: () => {
16
- status: "failed" | "idle" | "generating-qr-code" | "qr-code-generated" | "confirmed";
16
+ status: "idle" | "generating-qr-code" | "qr-code-generated" | "failed" | "confirmed";
17
17
  deposit: import("../../../../types").Deposit | null;
18
18
  errorMessage: {
19
19
  name: string;
@@ -5,7 +5,7 @@ export interface GenerateQRCodeInput {
5
5
  promo?: string | null;
6
6
  }
7
7
  export declare function useQRPHDeposit(): {
8
- status: "failed" | "idle" | "generating-qr-code" | "qr-code-generated" | "confirmed";
8
+ status: "idle" | "generating-qr-code" | "qr-code-generated" | "failed" | "confirmed";
9
9
  deposit: Deposit | null;
10
10
  errorMessage: {
11
11
  name: string;
@@ -0,0 +1,6 @@
1
+ import { type ImageProps } from 'next/image';
2
+ type Props = {
3
+ logo: ImageProps['src'];
4
+ };
5
+ declare const ForgotPassword: ({ logo }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export default ForgotPassword;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Image, {} from 'next/image';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { XIcon } from '../../../icons/XIcon.js';
5
+ import { Dialog } from '../../../ui/Dialog/index.js';
6
+ import CWForgotPasswordForm from './CWForgotPasswordForm.js';
7
+ import styles from './ForgotPassword.module.css';
8
+ const ForgotPassword = ({ logo }) => {
9
+ return (_jsx(Dialog.Content, { className: "bg-transparent h-full w-full overflow-y-invisible left-0 top-0 flex items-center", children: _jsxs("div", { className: "flex h-[90dvh] w-full flex-col justify-center scroll-smooth", children: [_jsxs("div", { className: "relative mx-auto w-full max-w-[22.5rem]", children: [_jsx(Image, { src: logo, alt: "", width: 200, height: 100, className: "mx-auto mt-8 h-auto w-[12.04544rem]", draggable: false }), _jsx(Dialog.CloseTrigger, { className: 'w-fit h-fit text-[#6C5200] rounded-md bg-gradient-to-t from-[#FFE5AF] to-[#EAC467] p-0.5', children: _jsx(XIcon, {}) })] }), _jsx("h2", { className: "mx-auto mt-10 w-fit bg-[linear-gradient(50deg,#c7802d_-5.1%,#ffe585_44.95%,#c7802d_109.05%)] bg-clip-text text-2xl font-bold uppercase text-transparent", children: "Forgot Password" }), _jsx("div", { className: twMerge('mx-auto mt-7.5 max-w-[20.6875rem] p-7.5', styles.card), children: _jsx(CWForgotPasswordForm, {}) })] }) }));
10
+ };
11
+ export default ForgotPassword;
@@ -0,0 +1,2 @@
1
+ declare const CWForgotPasswordForm: () => import("react/jsx-runtime").JSX.Element;
2
+ export default CWForgotPasswordForm;
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { zodResolver } from '@hookform/resolvers/zod';
3
+ import Image from 'next/image';
4
+ import { useMemo } from 'react';
5
+ import { useForm } from 'react-hook-form';
6
+ import { twMerge } from 'tailwind-merge';
7
+ import { useShallow } from 'zustand/shallow';
8
+ import { useCooldown } from '../../../client/hooks/useCooldown.js';
9
+ import { useGlobalStore } from '../../../client/hooks/useGlobalStore.js';
10
+ import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
11
+ import { useMobileNumberParser } from '../../../client/hooks/useMobileNumberParser.js';
12
+ import { useResetPasswordMutation } from '../../../client/hooks/useResetPasswordMutation.js';
13
+ import { useSendVerificationCodeMutation } from '../../../client/hooks/useSendVerificationCodeMutation.js';
14
+ import { toaster } from '../../../client/utils/toaster.js';
15
+ import { EyeIcon } from '../../../icons/EyeIcon.js';
16
+ import { EyeOffIcon } from '../../../icons/EyeOffIcon.js';
17
+ import lockIcon from '../../../images/lock-icon.webp';
18
+ import { createForgotPasswordSchema, } from '../../../schemas/forgotPasswordSchema.js';
19
+ import { Button } from '../../../ui/Button/index.js';
20
+ import { Field } from '../../../ui/Field/index.js';
21
+ import { PasswordInput } from '../../../ui/PasswordInput/index.js';
22
+ const CWForgotPasswordForm = () => {
23
+ const mobileNumberParser = useMobileNumberParser();
24
+ const schema = useMemo(() => createForgotPasswordSchema(mobileNumberParser), [mobileNumberParser]);
25
+ const { register, watch, getValues, handleSubmit, formState: { isValid, isDirty, errors }, } = useForm({
26
+ resolver: zodResolver(schema),
27
+ mode: 'onChange',
28
+ });
29
+ const mobileNumberValue = watch('mobileNumber');
30
+ const globalStore = useGlobalStore(useShallow((ctx) => ({
31
+ signIn: ctx.signIn,
32
+ forgotPassword: ctx.forgotPassword,
33
+ })));
34
+ const commonInputClass = 'h-10 w-full rounded-full border-none bg-black/40 text-xs placeholder:text-text-placeholder focus:outline-none focus:ring-0';
35
+ const localeInfo = useLocaleInfo();
36
+ const sendVerificationCodeMutation = useSendVerificationCodeMutation();
37
+ const resetPasswordMutation = useResetPasswordMutation({
38
+ onSuccess() {
39
+ globalStore.forgotPassword.setOpen(false);
40
+ globalStore.signIn.setOpen(true);
41
+ toaster.success({
42
+ description: 'Your password has been updated.',
43
+ });
44
+ },
45
+ onError(error) {
46
+ toaster.error({
47
+ description: error.message,
48
+ });
49
+ },
50
+ });
51
+ const cooldown = useCooldown({
52
+ max: 60,
53
+ duration: 1000 * 60,
54
+ });
55
+ const onSubmit = (data) => {
56
+ resetPasswordMutation.mutate({
57
+ mobileNumber: mobileNumberParser.format(data.mobileNumber),
58
+ newPassword: data.password,
59
+ verificationCode: data.verificationCode,
60
+ });
61
+ };
62
+ return (_jsx("form", { autoComplete: 'off', onSubmit: handleSubmit(onSubmit), children: _jsxs("div", { className: "space-y-4", children: [_jsxs(Field.Root, { invalid: !!errors.mobileNumber, children: [_jsx(Field.Label, { className: "text-xs", children: "Phone Number" }), _jsxs("div", { className: "relative flex h-10 gap-3", children: [_jsxs("div", { className: "flex h-full items-center gap-2 rounded-full bg-black/40 px-3.5 text-xs", children: [_jsx(localeInfo.country.flag, { className: "size-5" }), _jsx("span", { className: "text-text-placeholder", children: localeInfo.mobileNumber.areaCode })] }), _jsx(Field.Input, { className: commonInputClass, placeholder: "Enter Phone Number", ...register('mobileNumber') })] }), _jsx(Field.ErrorText, { className: "text-[#ff2525b3] text-xs", children: errors.mobileNumber?.message })] }), _jsx(Field.Root, { invalid: !!errors.password, children: _jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { className: "text-xs", children: "Password" }), _jsxs("div", { children: [_jsxs(PasswordInput.Control, { className: "relative flex h-10 items-center rounded-full text-xs bg-black/40 border-0", children: [_jsx(Image, { src: lockIcon, alt: "lock icon", width: 20, height: 20, className: "-translate-y-1/2 pointer-events-none absolute top-1/2 left-3 h-5 w-5" }), _jsx(PasswordInput.Input, { className: "pl-10", placeholder: "8 - 20 characters", ...register('password') }), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, { className: "text-white/50" }), asChild: true, children: _jsx(EyeIcon, { className: "text-white/50" }) }) })] }), _jsx(Field.ErrorText, { className: "text-[#ff2525b3] text-xs", children: errors.password?.message })] })] }) }), _jsx(Field.Root, { invalid: !!errors.confirmPassword, children: _jsxs(PasswordInput.Root, { children: [_jsx(PasswordInput.Label, { className: "text-xs", children: "Confirm Password" }), _jsxs("div", { children: [_jsxs(PasswordInput.Control, { className: "relative flex h-10 items-center rounded-full text-xs bg-black/40 border-0", children: [_jsx(Image, { src: lockIcon, alt: "lock icon", width: 20, height: 20, className: "-translate-y-1/2 pointer-events-none absolute top-1/2 left-3 h-5 w-5" }), _jsx(PasswordInput.Input, { className: "pl-10", placeholder: "8 - 20 characters", ...register('confirmPassword') }), _jsx(PasswordInput.VisibilityTrigger, { children: _jsx(PasswordInput.Indicator, { fallback: _jsx(EyeOffIcon, { className: "text-white/50" }), asChild: true, children: _jsx(EyeIcon, { className: "text-white/50" }) }) })] }), _jsx(Field.ErrorText, { className: "text-[#ff2525b3] text-xs", children: errors.confirmPassword?.message })] })] }) }), _jsxs(Field.Root, { invalid: !!errors.verificationCode, children: [_jsx(Field.Label, { className: "text-xs", children: "OTP Code" }), _jsxs("div", { className: "relative", children: [_jsx(Field.Input, { className: twMerge(commonInputClass, 'pr-[5.75rem]'), placeholder: "Enter OTP Code", ...register('verificationCode') }), _jsx(Button, { type: "button", className: "absolute right-1 top-1/2 h-fit w-fit -translate-y-1/2 rounded-full py-[0.375rem] text-sm shadow-[inset_0px_-1px_2px_1px_#fff7e1] bg-[linear-gradient(89deg,#c7802d_-15.91%,#ffe585_28.75%,#ffeca6_49.46%,#c7802d_112.69%)]", disabled: !mobileNumberValue || !!errors.mobileNumber || cooldown.cooling, onClick: async () => {
63
+ if (!cooldown.cooling) {
64
+ await sendVerificationCodeMutation.mutateAsync({
65
+ channel: 'SMS',
66
+ recipient: mobileNumberParser.format(getValues('mobileNumber'))
67
+ });
68
+ cooldown.start();
69
+ toaster.success({
70
+ description: `OTP sent to ${getValues('mobileNumber')}`
71
+ });
72
+ }
73
+ }, children: cooldown.cooling ? cooldown.countdown : 'Get OTP' })] }), _jsx(Field.ErrorText, { className: "text-[#ff2525b3] text-xs", children: errors.verificationCode?.message })] }), _jsx(Button, { type: "submit", className: "mt-7.5 text-sm rounded-full shadow-[inset_0px_-1px_2px_1px_#fff7e1] bg-[linear-gradient(89deg,#c7802d_-15.91%,#ffe585_28.75%,#ffeca6_49.46%,#c7802d_112.69%)]", fullWidth: true, disabled: !isValid || !isDirty, children: "Change Password" })] }) }));
74
+ };
75
+ export default CWForgotPasswordForm;
@@ -0,0 +1,43 @@
1
+ .card {
2
+ --gradient-bg: radial-gradient(103.87% 100% at 50.15% 0%, #072b37 20.3%, #051125 100%);
3
+
4
+ --gradient-border-top: radial-gradient(
5
+ 139.23% 113.41% at 50.14% 0%,
6
+ #8affdc 0.49%,
7
+ rgba(138, 255, 220, 0) 33.03%
8
+ );
9
+
10
+ --gradient-border-bottom: radial-gradient(
11
+ 42.09% 54.21% at 50.14% 100%,
12
+ #8affdc 5.74%,
13
+ rgba(138, 255, 220, 0) 93.84%
14
+ );
15
+
16
+ position: relative;
17
+ background: var(--gradient-bg);
18
+ box-shadow: 0px 4px 14px 6px rgba(0, 0, 0, 0.6);
19
+ backdrop-filter: blur(25px);
20
+ border-radius: 1.25em;
21
+ border: 1px solid rgba(255, 255, 255, 0.1);
22
+ }
23
+
24
+ .card::after,
25
+ .card::before {
26
+ content: '';
27
+ position: absolute;
28
+ top: 0;
29
+ left: 0;
30
+ width: 100%;
31
+ height: 100%;
32
+ z-index: -1;
33
+ border: 0.5px solid transparent;
34
+ border-image-slice: 1;
35
+ }
36
+
37
+ .card::before {
38
+ border-image-source: var(--gradient-border-bottom);
39
+ }
40
+
41
+ .card::after {
42
+ border-image-source: var(--gradient-border-top);
43
+ }
@@ -1,8 +1,11 @@
1
1
  import { type ImageProps } from 'next/image';
2
2
  import { type ReactNode } from 'react';
3
+ type ForgotPasswordLayout = 'crazywin';
3
4
  export interface ForgotPasswordProps {
4
5
  logo: ImageProps['src'];
5
6
  children?: ReactNode;
6
7
  className?: string;
8
+ layout?: ForgotPasswordLayout;
7
9
  }
8
10
  export declare function ForgotPassword(props: ForgotPasswordProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -8,12 +8,17 @@ import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
8
8
  import { XIcon } from '../../icons/XIcon.js';
9
9
  import { Dialog } from '../../ui/Dialog/index.js';
10
10
  import { Portal } from '../../ui/Portal/index.js';
11
+ import CrazywinForgotPassword from './Crazywin/CWForgotPassword.js';
11
12
  import { ForgotPasswordForm } from './ForgotPasswordForm.js';
12
13
  export function ForgotPassword(props) {
13
14
  const globalStore = useGlobalStore(useShallow((ctx) => ({
14
15
  forgotPassword: ctx.forgotPassword,
15
16
  })));
17
+ const Body = {
18
+ crazywin: (_jsx(CrazywinForgotPassword, { logo: props.logo })),
19
+ default: (_jsxs(Dialog.Content, { className: twMerge('mx-auto h-full w-full items-start bg-bg-primary-alt p-3xl pb-4xl lg:h-auto lg:w-[400px] lg:rounded-xl', props.className), children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Image, { src: props.logo, alt: "", width: 200, height: 100, className: "mx-auto h-auto w-[120px]", draggable: false }), _jsx(Suspense, { children: _jsx(ForgotPasswordForm, {}) })] }))
20
+ };
16
21
  return (_jsx(Dialog.Root, { open: globalStore.forgotPassword.open, onOpenChange: (details) => {
17
22
  globalStore.forgotPassword.setOpen(details.open);
18
- }, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { children: _jsxs(Dialog.Content, { className: twMerge('mx-auto h-full w-full items-start bg-bg-primary-alt p-3xl pb-4xl lg:h-auto lg:w-[400px] lg:rounded-xl', props.className), children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Image, { src: props.logo, alt: "", width: 200, height: 100, className: "mx-auto h-auto w-[120px]", draggable: false }), _jsx(Suspense, { children: _jsx(ForgotPasswordForm, {}) })] }) })] }) }));
23
+ }, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { children: Body[props.layout ?? 'default'] })] }) }));
19
24
  }
@@ -19,6 +19,7 @@ const JackpotsCarouselNext = lazy(() => import('../JackpotsCarouselNext/Jackpots
19
19
  import { JackpotsCarouselItemContext } from './JackpotsCarouselContext.js';
20
20
  import { JackpotsCarouselItem } from './JackpotsCarouselItem.js';
21
21
  import { JackpotsCarouselItemCrazyWin } from './JackpotsCarouselItem.CrazyWin.js';
22
+ import { JackpotsCarouselItemHappyBingo } from './JackpotsCarouselItem.HappyBingo.js';
22
23
  export function JackpotsCarousel__client({ style, className, ...props }) {
23
24
  const [emblaRef, emblaApi] = useEmblaCarousel({
24
25
  align: 'start',
@@ -71,7 +72,7 @@ export function JackpotsCarousel__client({ style, className, ...props }) {
71
72
  const classNames = useMemo(() => (isString(className) ? { root: className } : (className ?? {})), [className]);
72
73
  if (jackpots.length <= 0)
73
74
  return null;
74
- return (_jsxs("div", { ref: ref, style: styles.root, className: classNames.root, children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "font-semibold text-lg", children: props.heading ?? 'Jackpots' }), _jsxs("div", { className: "flex items-center md:gap-3xl", children: [_jsxs(Link, { href: props.viewAllUrl ?? '/jackpots', className: "flex gap-sm font-semibold text-button-tertiary-fg text-sm", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { disabled: !canScrollPrev, onClick: scrollPrev, variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsxs(Button, { disabled: !canScrollNext, onClick: scrollNext, variant: "outline", colorScheme: "gray", className: "rounded-l-none", "aria-label": "Next", children: [_jsx("span", { className: "sr-only", children: "Next" }), _jsx(ArrowRightIcon, { className: "size-5" })] })] })] })] }), _jsx("div", { className: 'relative overflow-hidden pt-lg', ref: emblaRef, children: _jsx("div", { className: "flex gap-2.5", children: jackpots.map((jackpot, index) => props.variant === 'crazywin' ? (_jsx(JackpotsCarouselItemContext, { value: jackpot, children: _jsx(JackpotsCarouselItemCrazyWin, { index: index, className: classNames, viewAllUrl: props.viewAllUrl }) }, jackpot.id ?? index)) : (_jsx(JackpotsCarouselItemContext, { value: jackpot, children: _jsx(JackpotsCarouselItem, { style: styles.itemRoot, className: classNames, viewAllUrl: props.viewAllUrl, animate: props.animate, customJackpotChestImage: props.customJackpotChestImage, jackpotProfileShape: props.jackpotProfileShape, chestImagesByTier: props.chestImagesByTier }) }, jackpot.id ?? index))) }) })] }));
75
+ return (_jsxs("div", { ref: ref, style: styles.root, className: classNames.root, children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "font-semibold text-lg", children: props.heading ?? 'Jackpots' }), _jsxs("div", { className: "flex items-center md:gap-3xl", children: [_jsxs(Link, { href: props.viewAllUrl ?? '/jackpots', className: "flex gap-sm font-semibold text-button-tertiary-fg text-sm", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { disabled: !canScrollPrev, onClick: scrollPrev, variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsxs(Button, { disabled: !canScrollNext, onClick: scrollNext, variant: "outline", colorScheme: "gray", className: "rounded-l-none", "aria-label": "Next", children: [_jsx("span", { className: "sr-only", children: "Next" }), _jsx(ArrowRightIcon, { className: "size-5" })] })] })] })] }), _jsx("div", { className: "relative overflow-hidden pt-lg", ref: emblaRef, children: _jsx("div", { className: "flex gap-2.5", children: jackpots.map((jackpot, index) => (_jsx(JackpotsCarouselItemContext, { value: jackpot, children: props.variant === 'crazywin' ? (_jsx(JackpotsCarouselItemCrazyWin, { index: index, className: classNames, viewAllUrl: props.viewAllUrl })) : props.variant === 'happybingo' ? (_jsx(JackpotsCarouselItemHappyBingo, { index: index, className: classNames, viewAllUrl: props.viewAllUrl })) : (_jsx(JackpotsCarouselItem, { style: styles.itemRoot, className: classNames, viewAllUrl: props.viewAllUrl, animate: props.animate, customJackpotChestImage: props.customJackpotChestImage, jackpotProfileShape: props.jackpotProfileShape, chestImagesByTier: props.chestImagesByTier })) }, jackpot.id ?? index))) }) })] }));
75
76
  }
76
77
  export function JackpotsCarousels__client(props) {
77
78
  const future = useFeatureFlag();
@@ -14,9 +14,9 @@ import treasureChestBg from '../../../images/chest-bg.webp';
14
14
  import star from '../../../images/star.webp';
15
15
  import treasureChest from '../../../images/treasure.webp';
16
16
  import { formatNumber } from '../../../utils/formatNumber.js';
17
- import { parseDecimal } from '../../../utils/parseDecimal.js';
17
+ import { getPercentage } from '../../../utils/getPercentage.js';
18
18
  import styles from '../Jackpots.module.css';
19
- import { JACKPOTS_VARIATIONS } from '../utils.js';
19
+ import { CRAZYWIN_JACKPOTS_VARIATIONS, getAccumulatingJackpotDescription } from '../utils.js';
20
20
  import { useJackpotsCarouselItemContext } from './JackpotsCarouselContext.js';
21
21
  export function JackpotsCarouselItemCrazyWin({ index, }) {
22
22
  const [ref] = useIntersectionObserver({
@@ -85,7 +85,7 @@ export function JackpotsCarouselItemCrazyWin({ index, }) {
85
85
  if (jackpot.status === 'DISABLED' && jackpot.drawing !== true) {
86
86
  return null;
87
87
  }
88
- const variation = JACKPOTS_VARIATIONS[index % JACKPOTS_VARIATIONS.length];
88
+ const variation = CRAZYWIN_JACKPOTS_VARIATIONS[index % CRAZYWIN_JACKPOTS_VARIATIONS.length];
89
89
  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: "relative z-1 flex flex-1 flex-col", children: [[
90
90
  [
91
91
  styles['flicker-scale-fade-2'],
@@ -111,34 +111,23 @@ export function JackpotsCarouselItemCrazyWin({ index, }) {
111
111
  styles['flicker-scale-fade-2'],
112
112
  'absolute right-[50%] top-[55%] h-4 w-4',
113
113
  ],
114
- ].map(([animationClass, positionClass], i) => (_jsx(Image, { src: star, alt: "star", draggable: "false", className: twMerge(animationClass, positionClass) }, 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
114
+ ].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
115
115
  ? styles['pulse-error']
116
- : styles['pulse-success']) }), _jsx("div", { className: twMerge('rounded text-[#CECFD2]'), children: isPayingOut ? 'Paying Out' : 'Accumulating' })] }) }), _jsx("div", { className: "mb-2 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, {
116
+ : 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, {
117
117
  currency: localeInfo.currency.code,
118
118
  minDecimalPlaces: 2,
119
119
  maxDecimalPlaces: 2,
120
- }) })] }), _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" })] }) }) }) }), _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, {
120
+ }) })] }), _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, {
121
121
  currency: localeInfo.currency.code,
122
122
  compact: true,
123
123
  }) }), _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, {
124
124
  currency: localeInfo.currency.code,
125
125
  compact: true,
126
- }) })] })] }), _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)] })] }), isPayingOut ? (_jsx("div", { className: twMerge(styles['light-rays'], variation.raysColor, 'rounded-t-2xl [--light-rays-left:90%] [--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" }))] }), _jsxs("div", { className: "relative flex h-[56px] min-h-[40px] w-full flex-1 items-center justify-between rounded-b-2xl bg-[#171b26] px-4 py-[10px]", children: [showSeeDetailsButton ? (_jsxs("button", { type: "button", className: "flex items-center gap-1 font-medium text-[#fff] text-sm", children: ["See details", _jsx(ArrowNarrowUpRightIcon, { className: "h-5 w-5" })] })) : (_jsxs("div", { className: "w-full text-white text-xs opacity-100 transition-opacity duration-500 ease-in-out", children: [_jsxs("div", { children: ["Minimum bet:", ' ', _jsxs("span", { className: "font-semibold text-[#FFE5AF]", children: ["PHP", ' ', formatNumber(jackpot.minimumBet, {
126
+ }) })] })] }), _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)] })] }), isPayingOut ? (_jsx("div", { className: twMerge(styles['light-rays'], variation.raysColor, 'rounded-t-2xl [--light-rays-left:90%] [--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 h-[56px] min-h-[40px] w-full flex-1 items-center justify-between rounded-b-2xl bg-[#171b26] px-4 py-[10px]", children: [showSeeDetailsButton ? (_jsxs("button", { type: "button", className: "flex items-center gap-1 font-medium text-[#fff] text-sm", children: ["See details", _jsx(ArrowNarrowUpRightIcon, { className: "h-5 w-5" })] })) : (_jsxs("div", { className: "w-full text-white text-xs opacity-100 transition-opacity duration-500 ease-in-out", children: [_jsxs("div", { children: ["Minimum bet:", ' ', _jsxs("span", { className: "font-semibold text-[#FFE5AF]", children: ["PHP", ' ', formatNumber(jackpot.minimumBet, {
127
127
  currency: localeInfo.currency.code,
128
128
  minDecimalPlaces: 2,
129
129
  maxDecimalPlaces: 2,
130
130
  }) || 'N/A'] })] }), _jsxs("div", { children: ["Multiplier Requirement:", ' ', _jsx("span", { className: "font-semibold text-[#FFE5AF]", children: jackpot.minimumMultiplier
131
131
  ? `${jackpot.minimumMultiplier}X or more`
132
- : 'N/A' })] })] })), _jsx("button", { type: "button", className: 'text-nowrap text-[#FFE5AF] text-sm underline underline-offset-4', children: "Jackpot Rules" })] })] }));
133
- }
134
- const getAccumulatingJackpotDescription = (part, total) => {
135
- const percentage = total === 0 ? 0 : (part / total) * 100;
136
- return percentage <= 90
137
- ? 'The jackpot is heating up! Keep playing to stay in the action and watch it grow!'
138
- : '🔥 It’s about to pop! Stay in the game for your shot at the prize!';
139
- };
140
- function getPercentage(value, total) {
141
- const v = parseDecimal(value, 0);
142
- const t = parseDecimal(total, 0);
143
- return t === 0 ? 0 : (v / t) * 100;
132
+ : 'N/A' })] })] })), _jsx("button", { type: "button", className: "text-nowrap text-[#FFE5AF] text-sm underline underline-offset-4", children: "Jackpot Rules" })] })] }));
144
133
  }
@@ -0,0 +1,8 @@
1
+ import type { ClassNameEntries } from './JackpotsCarousel';
2
+ export interface JackpotsCarouselItemHappyBingoProps {
3
+ index: number;
4
+ className?: ClassNameEntries;
5
+ /** @default "/jackpots" */
6
+ viewAllUrl?: string;
7
+ }
8
+ export declare function JackpotsCarouselItemHappyBingo({ index, }: JackpotsCarouselItemHappyBingoProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,154 @@
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 isMobile from 'is-mobile';
5
+ import Image from 'next/image';
6
+ import { useCallback, useEffect, useMemo, useState } from 'react';
7
+ import { twMerge } from 'tailwind-merge';
8
+ import { useIntersectionObserver } from 'usehooks-ts';
9
+ import { useJackpotPayoutsQuery } from '../../../client/hooks/useJackpotPayoutsQuery.js';
10
+ import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
11
+ import { ArrowNarrowUpRightIcon } from '../../../icons/ArrowNarrowUpRightIcon.js';
12
+ import { ChevronLeftIcon } from '../../../icons/ChevronLeftIcon.js';
13
+ import { ChevronRightIcon } from '../../../icons/ChevronRightIcon.js';
14
+ import { User02Icon } from '../../../icons/User02Icon.js';
15
+ import treasureChestBg from '../../../images/chest-bg.webp';
16
+ import coins from '../../../images/happy-bingo-coins.webp';
17
+ import star from '../../../images/star.webp';
18
+ import treasureChest from '../../../images/treasure.webp';
19
+ import { formatNumber } from '../../../utils/formatNumber.js';
20
+ import { getPercentage } from '../../../utils/getPercentage.js';
21
+ import styles from '../Jackpots.module.css';
22
+ import { getAccumulatingJackpotDescription, HAPPYBINGO_JACKPOTS_VARIATIONS, maskName } from '../utils.js';
23
+ import { useJackpotsCarouselItemContext } from './JackpotsCarouselContext.js';
24
+ export function JackpotsCarouselItemHappyBingo({ index, }) {
25
+ // 1. Hooks (Context, Data, State, Refs)
26
+ const [ref] = useIntersectionObserver({
27
+ threshold: 0.5,
28
+ rootMargin: '50px',
29
+ });
30
+ const jackpot = useJackpotsCarouselItemContext();
31
+ const jackpotPayoutsQuery = useJackpotPayoutsQuery({
32
+ first: 1,
33
+ filter: {
34
+ jackpot: {
35
+ equal: jackpot.id,
36
+ },
37
+ },
38
+ });
39
+ const jackpotPayouts = jackpotPayoutsQuery.data?.pages[0].edges.map((edge) => edge.node) ?? [];
40
+ const localeInfo = useLocaleInfo();
41
+ const [showSeeDetailsButton, setShowSeeDetailsButton] = useState(true);
42
+ const [infoIndex, setInfoIndex] = useState(0);
43
+ const [mainTooltipOpen, setMainTooltipOpen] = useState(false);
44
+ // 2. Derived State & Constants
45
+ const isPayingOut = jackpot.drawing;
46
+ const jackpotAmount = jackpot.pool;
47
+ const variation = HAPPYBINGO_JACKPOTS_VARIATIONS[index % HAPPYBINGO_JACKPOTS_VARIATIONS.length];
48
+ // 3. Memoized Callbacks & Values
49
+ const isMobileDevice = useMemo(() => isMobile(), []);
50
+ const getInfoBlocks = useCallback(() => {
51
+ return [
52
+ `Current Jackpot: <b>${formatNumber(jackpotAmount, {
53
+ currency: localeInfo.currency.code,
54
+ minDecimalPlaces: 2,
55
+ maxDecimalPlaces: 2,
56
+ })}</b>`,
57
+ `Minimum Payout Limit: <b>${formatNumber(jackpot.minimumJackpotPoolDrawingLimit, {
58
+ currency: localeInfo.currency.code,
59
+ minDecimalPlaces: 2,
60
+ maxDecimalPlaces: 2,
61
+ })}</b>`,
62
+ `Maximum Payout Limit: <b>${formatNumber(jackpot.maximumJackpotPoolLimit, {
63
+ currency: localeInfo.currency.code,
64
+ minDecimalPlaces: 2,
65
+ maxDecimalPlaces: 2,
66
+ })}</b>`,
67
+ isPayingOut
68
+ ? `The pot has hit <b>${formatNumber(jackpot.maximumJackpotPoolLimit, {
69
+ currency: localeInfo.currency.code,
70
+ minDecimalPlaces: 2,
71
+ maxDecimalPlaces: 2,
72
+ })}</b> Play now for your chance to win big! 🔥`
73
+ : getAccumulatingJackpotDescription(Number(jackpot.pool), Number(jackpot.maximumJackpotPoolLimit)),
74
+ ];
75
+ }, [isPayingOut, jackpot, jackpotAmount, localeInfo]);
76
+ const Arrow = useCallback(({ index }) => {
77
+ const Icon = isPayingOut ? ChevronLeftIcon : ChevronRightIcon;
78
+ return (_jsx(Icon, { className: twMerge('min-w-2.5 scale-400 text-brand-300 lg:min-w-4 lg:scale-250', isPayingOut
79
+ ? styles['animate-wave-color-error']
80
+ : styles['animate-wave-color-success']), style: {
81
+ animationDelay: isPayingOut
82
+ ? `${(40 - index - 1) * 0.1}s`
83
+ : `${index * 0.1}s`,
84
+ } }));
85
+ }, [isPayingOut]);
86
+ const arrowImages = useMemo(() => Array.from({ length: 40 }, (_, i) => _jsx(Arrow, { index: i }, i)), [Arrow]);
87
+ // 4. Effects
88
+ useEffect(() => {
89
+ const interval = setInterval(() => {
90
+ setInfoIndex((i) => (i + 1) % getInfoBlocks().length);
91
+ setShowSeeDetailsButton((v) => !v);
92
+ }, 4000);
93
+ return () => clearInterval(interval);
94
+ }, [getInfoBlocks]);
95
+ useEffect(() => {
96
+ if (isMobileDevice && mainTooltipOpen) {
97
+ const timeout = setTimeout(() => setMainTooltipOpen(false), 3000);
98
+ return () => clearTimeout(timeout);
99
+ }
100
+ }, [mainTooltipOpen, isMobileDevice]);
101
+ // 5. Early Return
102
+ if (jackpot.status === 'DISABLED' && jackpot.drawing !== true) {
103
+ return null;
104
+ }
105
+ // 6. Main Render
106
+ 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 lg:gap-4 lg:p-5', variation.background), children: [_jsxs("div", { className: "relative z-1 flex flex-1 flex-col", children: [[
107
+ [
108
+ styles['flicker-scale-fade-2'],
109
+ 'absolute right-[38%] top-[2%] h-2 w-2 delay-75',
110
+ ],
111
+ [
112
+ styles['flicker-scale-fade'],
113
+ 'absolute right-[20%] top-[10%] h-3 w-3',
114
+ ],
115
+ [
116
+ styles['flicker-scale-fade-2'],
117
+ 'absolute right-[30%] top-[10%] h-5 w-5',
118
+ ],
119
+ [
120
+ styles['flicker-scale-fade'],
121
+ 'absolute right-[36%] top-[35%] h-3 w-3',
122
+ ],
123
+ [
124
+ styles['flicker-scale-fade'],
125
+ 'absolute right-[15%] top-[56%] h-3 w-3',
126
+ ],
127
+ [
128
+ styles['flicker-scale-fade-2'],
129
+ 'absolute right-[50%] top-[55%] h-4 w-4',
130
+ ],
131
+ ].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
132
+ ? styles['pulse-error']
133
+ : 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, {
134
+ currency: localeInfo.currency.code,
135
+ minDecimalPlaces: 2,
136
+ maxDecimalPlaces: 2,
137
+ }) })] }), _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, {
138
+ currency: localeInfo.currency.code,
139
+ compact: true,
140
+ }) }), _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, {
141
+ currency: localeInfo.currency.code,
142
+ compact: true,
143
+ }) })] })] }), _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: "mt-5 hidden items-start gap-5 text-white lg:flex", children: jackpotPayouts.length ? (_jsxs("div", { className: "flex h-full w-full flex-row items-center justify-between gap-3", children: [_jsxs("div", { children: [_jsx("p", { className: "mb-1 block font-bold text-lg", children: "Recent Payout \uD83C\uDF89" }), _jsxs("p", { className: "block text-xs leading-[18px] tracking-wider", children: ["Massive payout unlocked! ", _jsx("br", {}), " Who's next? \uD83D\uDCB0"] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("div", { className: twMerge(variation.topPayoutImgBorderColor, 'relative flex h-[54px] w-[54px] items-center justify-center rounded-full object-contain p-[3.5px]'), children: [_jsx("div", { className: twMerge('flex h-full w-full items-center justify-center rounded-full', variation.topPayoutImgBg), children: _jsx(User02Icon, { className: "h-[34px] w-auto" }) }), _jsx("div", { className: twMerge(variation.topPayoutImgBorderColor, '-right-1.5 absolute bottom-[-5px] lg:right-[-5px] lg:bottom-[-5px]', 'flex h-[34px] w-[34px] items-center justify-center rounded-full p-0.5'), children: _jsxs("div", { className: twMerge('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: twMerge(variation.poolBg, 'rounded-lg px-2 font-semibold text-[22px]', variation.textColor), children: formatNumber(jackpotPayouts[0].amount, {
144
+ currency: localeInfo.currency.code,
145
+ minDecimalPlaces: 2,
146
+ maxDecimalPlaces: 2,
147
+ }) })] })] })] })) : (_jsxs("div", { className: "flex h-full w-full flex-row-reverse items-center justify-between", 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-[0.75rem] leading-[1.125rem]", 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:90%] [--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 h-[56px] min-h-[40px] w-full flex-1 items-center justify-between rounded-b-2xl bg-white px-4 py-[10px] text-[#475467] dark:bg-[#161B26] dark:text-[#94969C]", children: [showSeeDetailsButton ? (_jsxs("button", { type: "button", className: 'flex items-center gap-1 font-medium text-sm', children: ["See details", _jsx(ArrowNarrowUpRightIcon, { className: "h-5 w-5" })] })) : (_jsxs("div", { className: "w-full text-xs transition-opacity duration-500 ease-in-out", children: [_jsxs("div", { children: ["Minimum bet:", ' ', _jsxs("span", { className: "font-semibold text-[#A15C07] dark:text-[#EAAA08]", children: ["PHP", ' ', formatNumber(jackpot.minimumBet, {
148
+ currency: localeInfo.currency.code,
149
+ minDecimalPlaces: 2,
150
+ maxDecimalPlaces: 2,
151
+ }) || 'N/A'] })] }), _jsxs("div", { children: ["Multiplier Requirement:", ' ', _jsx("span", { className: "font-semibold text-[#A15C07] dark:text-[#EAAA08]", children: jackpot.minimumMultiplier
152
+ ? `${jackpot.minimumMultiplier}X or more`
153
+ : 'N/A' })] })] })), _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" })] })] }));
154
+ }
@@ -34,6 +34,7 @@ interface StyleEntries {
34
34
  itemRoot?: CSSProperties;
35
35
  }
36
36
  export interface JackpotsListProps {
37
+ variant?: 'happybingo' | 'crazywin';
37
38
  layout: 'list';
38
39
  /** @default "Jackpots" */
39
40
  heading?: string | ReactNode;
@@ -9,6 +9,8 @@ import closeChest from '../../../images/close-chest.png';
9
9
  import { isStyleEntries } from '../../../utils/isStyleEntries.js';
10
10
  import { JackpotsListNext } from '../JackpotsListNext/JackpotsList.js';
11
11
  import { JackpotsListItemContext, JackpotsListPropsContext, } from './JackpotsListContext.js';
12
+ import { JackpotsListItemCrazyWin } from './JackpotsListItem.CrazyWin.js';
13
+ import { JackpotsListItemHappyBingo } from './JackpotsListItem.HappyBingo.js';
12
14
  import { JackpotsListItemDesktop } from './JackpotsListItemDesktop.js';
13
15
  import { JackpotsListItemMobile } from './JackpotsListItemMobile.js';
14
16
  export function JackpotsList(props) {
@@ -43,5 +45,5 @@ export function JackpotsList(props) {
43
45
  future.enabled) {
44
46
  return _jsx(JackpotsListNext, { ...props });
45
47
  }
46
- return (_jsx(JackpotsListPropsContext, { value: props, children: _jsxs("div", { ref: ref, style: styles.root, className: classNames.root, children: [_jsx("div", { className: "mb-3 font-semibold text-lg lg:mb-4.5", children: props.heading ?? 'Jackpots' }), jackpots.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "hidden flex-col gap-6 lg:flex", children: jackpots.map((jackpot, index) => (_jsx(JackpotsListItemContext, { value: jackpot, children: _jsx(JackpotsListItemDesktop, { style: styles.itemRoot, className: classNames, animate: props.animate, customJackpotChestImage: props.customJackpotChestImage, jackpotProfileShape: props.jackpotProfileShape, chestImagesByTier: props.chestImagesByTier }) }, index))) }), _jsx("div", { className: "flex flex-col gap-6 lg:hidden", children: jackpots.map((jackpot, index) => (_jsx(JackpotsListItemContext, { value: jackpot, children: _jsx(JackpotsListItemMobile, { style: styles.itemRoot, className: classNames, animate: props.animate, customJackpotChestImage: props.customJackpotChestImage, jackpotProfileShape: props.jackpotProfileShape, chestImagesByTier: props.chestImagesByTier }) }, index))) })] })) : (_jsxs("div", { className: "mt-5 flex h-fit flex-col items-center justify-center lg:mt-0 lg:h-62", children: [_jsx(Image, { width: 100, height: 100, src: closeChest, alt: "closeChest", className: "size-full h-29.5 w-29.5 mix-blend-luminosity lg:h-25 lg:w-25" }), _jsx("div", { className: "mt-4 font-semibold text-base text-text-primary-900", children: "No Jackpots" }), _jsxs("div", { className: "mt-1 text-center text-sm text-text-tertiary-600", children: ["No jackpots are running at the moment. ", _jsx("br", {}), "Please check back later!"] })] }))] }) }));
48
+ return (_jsx(JackpotsListPropsContext, { value: props, children: _jsxs("div", { ref: ref, style: styles.root, className: classNames.root, children: [_jsx("div", { className: "mb-3 font-semibold text-lg lg:mb-4.5", children: props.heading ?? 'Jackpots' }), jackpots.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "hidden flex-col gap-6 lg:flex", children: jackpots.map((jackpot, index) => (_jsx(JackpotsListItemContext, { value: jackpot, children: props.variant === 'crazywin' ? (_jsx(JackpotsListItemCrazyWin, { index: index, className: classNames })) : props.variant === 'happybingo' ? (_jsx(JackpotsListItemHappyBingo, { index: index, className: classNames })) : (_jsx(JackpotsListItemDesktop, { style: styles.itemRoot, className: classNames, animate: props.animate, customJackpotChestImage: props.customJackpotChestImage, jackpotProfileShape: props.jackpotProfileShape, chestImagesByTier: props.chestImagesByTier })) }, index))) }), _jsx("div", { className: "flex flex-col gap-6 lg:hidden", children: jackpots.map((jackpot, index) => (_jsx(JackpotsListItemContext, { value: jackpot, children: props.variant === 'crazywin' ? (_jsx(JackpotsListItemCrazyWin, { index: index, className: classNames })) : props.variant === 'happybingo' ? (_jsx(JackpotsListItemHappyBingo, { index: index, className: classNames })) : (_jsx(JackpotsListItemMobile, { style: styles.itemRoot, className: classNames, animate: props.animate, customJackpotChestImage: props.customJackpotChestImage, jackpotProfileShape: props.jackpotProfileShape, chestImagesByTier: props.chestImagesByTier })) }, index))) })] })) : (_jsxs("div", { className: "mt-5 flex h-fit flex-col items-center justify-center lg:mt-0 lg:h-62", children: [_jsx(Image, { width: 100, height: 100, src: closeChest, alt: "closeChest", className: "size-full h-29.5 w-29.5 mix-blend-luminosity lg:h-25 lg:w-25" }), _jsx("div", { className: "mt-4 font-semibold text-base text-text-primary-900", children: "No Jackpots" }), _jsxs("div", { className: "mt-1 text-center text-sm text-text-tertiary-600", children: ["No jackpots are running at the moment. ", _jsx("br", {}), "Please check back later!"] })] }))] }) }));
47
49
  }
@@ -0,0 +1,6 @@
1
+ import type { ClassNameEntries } from './JackpotsList';
2
+ export interface JackpotsListItemDesktopCrazyWinProps {
3
+ index: number;
4
+ className?: ClassNameEntries;
5
+ }
6
+ export declare function JackpotsListItemCrazyWin({ index, }: JackpotsListItemDesktopCrazyWinProps): import("react/jsx-runtime").JSX.Element | null;