@opexa/portal-components 0.0.78 → 0.0.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/hooks/index.d.ts +1 -0
- package/dist/client/hooks/index.js +1 -0
- package/dist/client/hooks/useChunk.d.ts +8 -0
- package/dist/client/hooks/useChunk.js +26 -0
- package/dist/components/BetRecords/BetRecords.js +3 -3
- package/dist/components/Cashback/Cashback.client.js +1 -1
- package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
- package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
- package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/QRPHDepositContext.d.ts +2 -2
- package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/useQRPHDeposit.d.ts +1 -1
- package/dist/components/GameProviders/GameProviders.d.ts +3 -24
- package/dist/components/GameProviders/GameProviders.js +9 -41
- package/dist/components/GameProviders/GameProvidersCarousel.d.ts +31 -0
- package/dist/components/GameProviders/GameProvidersCarousel.js +47 -0
- package/dist/components/GameProviders/GameProvidersList.d.ts +27 -0
- package/dist/components/GameProviders/GameProvidersList.js +25 -0
- package/dist/components/Games/Game.d.ts +6 -1
- package/dist/components/Games/Game.js +7 -3
- package/dist/components/Games/Games.d.ts +1 -5
- package/dist/components/Games/GamesCarousel.client.js +10 -3
- package/dist/components/Games/GamesCarousel.d.ts +7 -2
- package/dist/components/Games/GamesContext.d.ts +4 -0
- package/dist/components/Games/GamesContext.js +3 -0
- package/dist/components/Games/GamesList.client.js +10 -4
- package/dist/components/Games/GamesList.d.ts +7 -2
- package/dist/components/Jackpots/JackpotGameProviders.js +4 -1
- package/dist/components/Jackpots/Jackpots.d.ts +2 -0
- package/dist/components/Promo/Promo.client.js +1 -1
- package/dist/components/Promos/Promos.d.ts +3 -14
- package/dist/components/Promos/PromosCarousel.d.ts +13 -2
- package/dist/components/Promos/PromosGrid.d.ts +11 -2
- package/dist/components/Search/Search.d.ts +1 -0
- package/dist/components/Search/Search.js +2 -1
- package/dist/components/TransactionRecords/TransactionRecords.js +1 -1
- package/dist/constants/gameProviders.js +1 -1
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@ export * from './useCashbackBonusQuery';
|
|
|
10
10
|
export * from './useCashbackQuery';
|
|
11
11
|
export * from './useCashbacksQuery';
|
|
12
12
|
export * from './useCheckInDailyCheckInQuestMutation';
|
|
13
|
+
export * from './useChunk';
|
|
13
14
|
export * from './useClaimCashbackBonusMutation';
|
|
14
15
|
export * from './useClaimSpotBonusMutation';
|
|
15
16
|
export * from './useControllableState';
|
|
@@ -10,6 +10,7 @@ export * from './useCashbackBonusQuery.js';
|
|
|
10
10
|
export * from './useCashbackQuery.js';
|
|
11
11
|
export * from './useCashbacksQuery.js';
|
|
12
12
|
export * from './useCheckInDailyCheckInQuestMutation.js';
|
|
13
|
+
export * from './useChunk.js';
|
|
13
14
|
export * from './useClaimCashbackBonusMutation.js';
|
|
14
15
|
export * from './useClaimSpotBonusMutation.js';
|
|
15
16
|
export * from './useControllableState.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { chunk } from 'lodash-es';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
export function useChunk(items, size) {
|
|
4
|
+
const chunks = chunk(items, size);
|
|
5
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
6
|
+
const currentItems = chunks.at(currentIndex) ?? [];
|
|
7
|
+
const loadedItems = (() => {
|
|
8
|
+
return chunks.filter((_, index) => index <= currentIndex).flat();
|
|
9
|
+
})();
|
|
10
|
+
const next = () => {
|
|
11
|
+
if (currentIndex >= chunks.length - 1)
|
|
12
|
+
return;
|
|
13
|
+
setCurrentIndex((prevIndex) => prevIndex + 1);
|
|
14
|
+
};
|
|
15
|
+
const totalItems = items.length;
|
|
16
|
+
const totalLoadedItems = loadedItems.length;
|
|
17
|
+
const hasNext = currentIndex < chunks.length - 1;
|
|
18
|
+
return {
|
|
19
|
+
totalItems,
|
|
20
|
+
currentItems,
|
|
21
|
+
loadedItems,
|
|
22
|
+
totalLoadedItems,
|
|
23
|
+
hasNext,
|
|
24
|
+
next,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -22,7 +22,7 @@ export function BetRecords(props) {
|
|
|
22
22
|
}), {
|
|
23
23
|
page: 1,
|
|
24
24
|
pageSize: 10,
|
|
25
|
-
type:
|
|
25
|
+
type: null,
|
|
26
26
|
});
|
|
27
27
|
const localeInfo = useLocaleInfo();
|
|
28
28
|
const providerCollection = createListCollection({
|
|
@@ -59,12 +59,12 @@ export function BetRecords(props) {
|
|
|
59
59
|
}),
|
|
60
60
|
},
|
|
61
61
|
});
|
|
62
|
-
return (_jsxs("div", { className: props.className, children: [_jsx("h2", { className: "text-sm font-semibold leading-tight lg:text-lg", children: "Bet Records" }), _jsx("p", { className: "text-text-tertiary-600 mt-xs text-sm leading-tight", children: "Review your betting history" }), _jsx("div", { className: "mt-lg lg:mt-2xl", children: _jsxs(SegmentGroup.Root, { value: state.type, onValueChange: (details) => {
|
|
62
|
+
return (_jsxs("div", { className: props.className, children: [_jsx("h2", { className: "text-sm font-semibold leading-tight lg:text-lg", children: "Bet Records" }), _jsx("p", { className: "text-text-tertiary-600 mt-xs text-sm leading-tight", children: "Review your betting history" }), _jsx("div", { className: "mt-lg lg:mt-2xl", children: _jsxs(SegmentGroup.Root, { value: state.type ?? 'all', onValueChange: (details) => {
|
|
63
63
|
firstPage();
|
|
64
64
|
setState({
|
|
65
65
|
type: z.enum(GAME_TYPES).safeParse(details.value).data ?? null,
|
|
66
66
|
});
|
|
67
|
-
}, children: [gameTypes.map((type) => (_jsxs(SegmentGroup.Item, { value: type.id, children: [_jsx(SegmentGroup.ItemText, { children: type.name }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }, type.id))), _jsx(SegmentGroup.Indicator, {})] }) }), _jsx("div", { className: "border-border-secondary mt-2xl hidden border-t lg:block" }), _jsx("h3", { className: "text-text-secondary-700 mt-3xl text-sm font-semibold", children: "Table" }), _jsxs("div", { className: "mt-xl flex flex-col gap-lg lg:flex-row lg:items-center", children: [_jsxs(DatePicker.Root, { lazyMount: true, unmountOnExit: true, value: [state.timestamp?.start, state.timestamp?.end]
|
|
67
|
+
}, children: [_jsxs(SegmentGroup.Item, { value: "all", children: [_jsx(SegmentGroup.ItemText, { children: "All" }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }), gameTypes.map((type) => (_jsxs(SegmentGroup.Item, { value: type.id, children: [_jsx(SegmentGroup.ItemText, { children: type.name }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }, type.id))), _jsx(SegmentGroup.Indicator, {})] }) }), _jsx("div", { className: "border-border-secondary mt-2xl hidden border-t lg:block" }), _jsx("h3", { className: "text-text-secondary-700 mt-3xl text-sm font-semibold", children: "Table" }), _jsxs("div", { className: "mt-xl flex flex-col gap-lg lg:flex-row lg:items-center", children: [_jsxs(DatePicker.Root, { lazyMount: true, unmountOnExit: true, value: [state.timestamp?.start, state.timestamp?.end]
|
|
68
68
|
.filter(Boolean)
|
|
69
69
|
.map((d) => parseDate(d)), onValueChange: (details) => {
|
|
70
70
|
firstPage();
|
|
@@ -27,5 +27,5 @@ export function Cashback__client(props) {
|
|
|
27
27
|
in: tz(localeInfo.timezone),
|
|
28
28
|
})] }), _jsx(Prose, { className: "mt-2xl lg:mt-6", dangerouslySetInnerHTML: {
|
|
29
29
|
__html: cashback.description,
|
|
30
|
-
} })
|
|
30
|
+
} })] }));
|
|
31
31
|
}
|
package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const OnlineBankDepositContext: import("react").Context<{
|
|
2
|
-
view: "
|
|
2
|
+
view: "form" | "vca";
|
|
3
3
|
status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
|
|
4
4
|
verify: () => void;
|
|
5
5
|
reset: () => void;
|
|
@@ -9,7 +9,7 @@ export declare const OnlineBankDepositContext: import("react").Context<{
|
|
|
9
9
|
promo?: string | null;
|
|
10
10
|
}) => void;
|
|
11
11
|
}>, useOnlineBankDepositContext: () => {
|
|
12
|
-
view: "
|
|
12
|
+
view: "form" | "vca";
|
|
13
13
|
status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
|
|
14
14
|
verify: () => void;
|
|
15
15
|
reset: () => void;
|
package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Deposit } from '@opexa/portal-sdk-core';
|
|
2
2
|
export type UseOnlineBankDepositReturn = ReturnType<typeof useOnlineBankDeposit>;
|
|
3
3
|
export declare function useOnlineBankDeposit(): {
|
|
4
|
-
view: "
|
|
4
|
+
view: "form" | "vca";
|
|
5
5
|
status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
|
|
6
6
|
verify: () => void;
|
|
7
7
|
reset: () => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const QRPHDepositContext: import("react").Context<{
|
|
2
|
-
view: "
|
|
2
|
+
view: "form" | "qrCode";
|
|
3
3
|
status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
|
|
4
4
|
verify: () => void;
|
|
5
5
|
reset: () => void;
|
|
@@ -9,7 +9,7 @@ export declare const QRPHDepositContext: import("react").Context<{
|
|
|
9
9
|
promo?: string | null;
|
|
10
10
|
}) => void;
|
|
11
11
|
}>, useQRPHDepositContext: () => {
|
|
12
|
-
view: "
|
|
12
|
+
view: "form" | "qrCode";
|
|
13
13
|
status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
|
|
14
14
|
verify: () => void;
|
|
15
15
|
reset: () => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Deposit } from '@opexa/portal-sdk-core';
|
|
2
2
|
export type UseQRPHDepositReturn = ReturnType<typeof useQRPHDeposit>;
|
|
3
3
|
export declare function useQRPHDeposit(): {
|
|
4
|
-
view: "
|
|
4
|
+
view: "form" | "qrCode";
|
|
5
5
|
status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
|
|
6
6
|
verify: () => void;
|
|
7
7
|
reset: () => void;
|
|
@@ -1,25 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
3
|
-
export
|
|
4
|
-
gameProviders: GameProvider[];
|
|
5
|
-
heading?: string;
|
|
6
|
-
/**
|
|
7
|
-
* @default '/providers'
|
|
8
|
-
*/
|
|
9
|
-
viewAllUrl?: string;
|
|
10
|
-
/**
|
|
11
|
-
* @default '/providers/<slug>'
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* '/bingo/:slug' // '/bingo/jili'
|
|
15
|
-
* '/bingo/:id' // '/bingo/JILI'
|
|
16
|
-
* // or using a function
|
|
17
|
-
* ({slug}) => `/bingo/${slug}`
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
viewGamesUrl?: string | ((gameProvider: GameProviderData) => string);
|
|
21
|
-
className?: string;
|
|
22
|
-
gameProviderContainerClass?: string;
|
|
23
|
-
gameProviderImageClass?: string;
|
|
24
|
-
}
|
|
1
|
+
import { type GameProvidersCarouselProps } from './GameProvidersCarousel';
|
|
2
|
+
import { type GameProvidersListProps } from './GameProvidersList';
|
|
3
|
+
export type GameProvidersProps = GameProvidersCarouselProps | GameProvidersListProps;
|
|
25
4
|
export declare function GameProviders(props: GameProvidersProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,43 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import Image from 'next/image';
|
|
5
|
-
import Link from 'next/link';
|
|
6
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
7
|
-
import { twMerge } from 'tailwind-merge';
|
|
8
|
-
import { GAME_PROVIDER_DATA } from '../../constants/index.js';
|
|
9
|
-
import { ArrowLeftIcon, ArrowRightIcon, ChevronRightIcon } from '../../icons/index.js';
|
|
10
|
-
import { Button } from '../../ui/index.js';
|
|
11
|
-
import { callIfFn } from '../../utils/index.js';
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { GameProvidersCarousel, } from './GameProvidersCarousel.js';
|
|
3
|
+
import { GameProvidersList, } from './GameProvidersList.js';
|
|
12
4
|
export function GameProviders(props) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const onPrevButtonClick = useCallback(() => emblaApi?.scrollPrev(), [emblaApi]);
|
|
20
|
-
const onNextButtonClick = useCallback(async () => {
|
|
21
|
-
emblaApi?.scrollNext();
|
|
22
|
-
}, [emblaApi]);
|
|
23
|
-
const onSelect = useCallback((emblaApi) => {
|
|
24
|
-
setPrevBtnDisabled(!emblaApi?.canScrollPrev());
|
|
25
|
-
setNextBtnDisabled(!emblaApi?.canScrollNext());
|
|
26
|
-
}, []);
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
if (!emblaApi)
|
|
29
|
-
return;
|
|
30
|
-
onSelect(emblaApi);
|
|
31
|
-
emblaApi.on('reInit', onSelect).on('select', onSelect);
|
|
32
|
-
}, [emblaApi, onSelect]);
|
|
33
|
-
const viewAllUrl = props.viewAllUrl ?? '/providers';
|
|
34
|
-
const viewGamesUrl = (data) => {
|
|
35
|
-
return props.viewGamesUrl
|
|
36
|
-
? callIfFn(props.viewGamesUrl, data)
|
|
37
|
-
.replace(':id', data.id)
|
|
38
|
-
.replace(':slug', data.slug)
|
|
39
|
-
: `/providers/${data.slug}`;
|
|
40
|
-
};
|
|
41
|
-
const gameProviders = props.gameProviders.map((provider) => GAME_PROVIDER_DATA[provider]);
|
|
42
|
-
return (_jsxs("div", { className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Providers' }), _jsx("div", { className: "grow" }), _jsxs("div", { className: "flex items-center justify-center gap-xl", children: [_jsxs(Link, { href: viewAllUrl, className: "text-button-tertiary-fg flex gap-sm text-sm font-semibold", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", onClick: onPrevButtonClick, disabled: prevBtnDisabled, "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-l-none", onClick: onNextButtonClick, disabled: nextBtnDisabled, "aria-label": "Next", children: _jsx(ArrowRightIcon, { className: "size-5" }) })] })] })] }), _jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsx("div", { className: "grid auto-cols-[calc((100%-(0.375rem*2))/3)] grid-flow-col grid-rows-1 gap-sm lg:auto-cols-[calc((100%-(0.5rem*5))/6)] lg:gap-md", children: gameProviders.map((provider) => (_jsx(Link, { href: viewGamesUrl(provider), className: twMerge('bg-gray-800 flex h-full w-full items-center overflow-hidden rounded-md lg:h-[5.75rem]', props.gameProviderContainerClass), "aria-label": `View ${provider.name} games`, children: _jsx(Image, { src: provider.logo, alt: "", width: 300, height: 150, className: twMerge('mx-auto h-auto w-full', props.gameProviderImageClass) }) }, provider.id))) }) })] }));
|
|
5
|
+
if (props.layout === 'list') {
|
|
6
|
+
return _jsx(GameProvidersList, { ...props });
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
return _jsx(GameProvidersCarousel, { ...props });
|
|
10
|
+
}
|
|
43
11
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GameProvider } from '@opexa/portal-sdk-core';
|
|
2
|
+
import { type ImageProps } from 'next/image';
|
|
3
|
+
import type { GameProviderData } from '../../types';
|
|
4
|
+
export interface ClassNameEntries {
|
|
5
|
+
root?: string;
|
|
6
|
+
thumbnailRoot?: string;
|
|
7
|
+
thumbnailImage?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface GameProvidersCarouselProps {
|
|
10
|
+
layout: 'carousel';
|
|
11
|
+
gameProviders: GameProvider[];
|
|
12
|
+
heading?: string;
|
|
13
|
+
/**
|
|
14
|
+
* @default '/providers'
|
|
15
|
+
*/
|
|
16
|
+
viewAllUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* @default '/providers/<slug>'
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* '/bingo/:slug' // '/bingo/jili'
|
|
22
|
+
* '/bingo/:id' // '/bingo/JILI'
|
|
23
|
+
* // or using a function
|
|
24
|
+
* ({slug}) => `/bingo/${slug}`
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
viewGamesUrl?: string | ((gameProvider: GameProviderData) => string);
|
|
28
|
+
gameProviderImages?: Partial<Record<GameProvider, ImageProps['src']>>;
|
|
29
|
+
className?: string | ClassNameEntries;
|
|
30
|
+
}
|
|
31
|
+
export declare function GameProvidersCarousel(props: GameProvidersCarouselProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import useEmblaCarousel from 'embla-carousel-react';
|
|
4
|
+
import { isString } from 'lodash-es';
|
|
5
|
+
import Image, {} from 'next/image';
|
|
6
|
+
import Link from 'next/link';
|
|
7
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
8
|
+
import { twMerge } from 'tailwind-merge';
|
|
9
|
+
import { GAME_PROVIDER_DATA } from '../../constants/index.js';
|
|
10
|
+
import { ArrowLeftIcon, ArrowRightIcon, ChevronRightIcon } from '../../icons/index.js';
|
|
11
|
+
import { Button } from '../../ui/index.js';
|
|
12
|
+
import { callIfFn } from '../../utils/index.js';
|
|
13
|
+
export function GameProvidersCarousel(props) {
|
|
14
|
+
const [emblaRef, emblaApi] = useEmblaCarousel({
|
|
15
|
+
align: 'start',
|
|
16
|
+
slidesToScroll: 1,
|
|
17
|
+
});
|
|
18
|
+
const [prevBtnDisabled, setPrevBtnDisabled] = useState(true);
|
|
19
|
+
const [nextBtnDisabled, setNextBtnDisabled] = useState(true);
|
|
20
|
+
const onPrevButtonClick = useCallback(() => emblaApi?.scrollPrev(), [emblaApi]);
|
|
21
|
+
const onNextButtonClick = useCallback(async () => {
|
|
22
|
+
emblaApi?.scrollNext();
|
|
23
|
+
}, [emblaApi]);
|
|
24
|
+
const onSelect = useCallback((emblaApi) => {
|
|
25
|
+
setPrevBtnDisabled(!emblaApi?.canScrollPrev());
|
|
26
|
+
setNextBtnDisabled(!emblaApi?.canScrollNext());
|
|
27
|
+
}, []);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!emblaApi)
|
|
30
|
+
return;
|
|
31
|
+
onSelect(emblaApi);
|
|
32
|
+
emblaApi.on('reInit', onSelect).on('select', onSelect);
|
|
33
|
+
}, [emblaApi, onSelect]);
|
|
34
|
+
const viewAllUrl = props.viewAllUrl ?? '/providers';
|
|
35
|
+
const viewGamesUrl = (data) => {
|
|
36
|
+
return props.viewGamesUrl
|
|
37
|
+
? callIfFn(props.viewGamesUrl, data)
|
|
38
|
+
.replace(':id', data.id)
|
|
39
|
+
.replace(':slug', data.slug)
|
|
40
|
+
: `/providers/${data.slug}`;
|
|
41
|
+
};
|
|
42
|
+
const gameProviders = props.gameProviders.map((provider) => GAME_PROVIDER_DATA[provider]);
|
|
43
|
+
const classNames = isString(props.className)
|
|
44
|
+
? { root: props.className }
|
|
45
|
+
: (props.className ?? {});
|
|
46
|
+
return (_jsxs("div", { className: classNames.root, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Providers' }), _jsx("div", { className: "grow" }), _jsxs("div", { className: "flex items-center justify-center gap-xl", children: [_jsxs(Link, { href: viewAllUrl, className: "text-button-tertiary-fg flex gap-sm text-sm font-semibold", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", onClick: onPrevButtonClick, disabled: prevBtnDisabled, "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-l-none", onClick: onNextButtonClick, disabled: nextBtnDisabled, "aria-label": "Next", children: _jsx(ArrowRightIcon, { className: "size-5" }) })] })] })] }), _jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsx("div", { className: "grid auto-cols-[calc((100%-(0.375rem*2))/3)] grid-flow-col grid-rows-1 gap-sm lg:auto-cols-[calc((100%-(0.5rem*5))/6)] lg:gap-md", children: gameProviders.map((provider) => (_jsx(Link, { href: viewGamesUrl(provider), className: twMerge('bg-gray-800 flex h-full w-full items-center overflow-hidden rounded-md lg:h-[5.75rem]', classNames.thumbnailRoot), "aria-label": `View ${provider.name} games`, children: _jsx(Image, { src: props.gameProviderImages?.[provider.id] ?? provider.logo, alt: "", width: 300, height: 150, className: twMerge('mx-auto h-auto w-full', classNames.thumbnailImage) }) }, provider.id))) }) })] }));
|
|
47
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GameProvider } from '@opexa/portal-sdk-core';
|
|
2
|
+
import { type ImageProps } from 'next/image';
|
|
3
|
+
import type { GameProviderData } from '../../types';
|
|
4
|
+
export interface ClassNameEntries {
|
|
5
|
+
root?: string;
|
|
6
|
+
thumbnailRoot?: string;
|
|
7
|
+
thumbnailImage?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface GameProvidersListProps {
|
|
10
|
+
layout: 'list';
|
|
11
|
+
gameProviders: GameProvider[];
|
|
12
|
+
heading?: string;
|
|
13
|
+
/**
|
|
14
|
+
* @default '/providers/<slug>'
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* '/bingo/:slug' // '/bingo/jili'
|
|
18
|
+
* '/bingo/:id' // '/bingo/JILI'
|
|
19
|
+
* // or using a function
|
|
20
|
+
* ({slug}) => `/bingo/${slug}`
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
viewGamesUrl?: string | ((gameProvider: GameProviderData) => string);
|
|
24
|
+
gameProviderImages?: Partial<Record<GameProvider, ImageProps['src']>>;
|
|
25
|
+
className?: string | ClassNameEntries;
|
|
26
|
+
}
|
|
27
|
+
export declare function GameProvidersList(props: GameProvidersListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { isString, noop } from 'lodash-es';
|
|
4
|
+
import Image, {} from 'next/image';
|
|
5
|
+
import Link from 'next/link';
|
|
6
|
+
import { twMerge } from 'tailwind-merge';
|
|
7
|
+
import { useChunk } from '../../client/hooks/index.js';
|
|
8
|
+
import { GAME_PROVIDER_DATA } from '../../constants/index.js';
|
|
9
|
+
import { Button, Progress } from '../../ui/index.js';
|
|
10
|
+
import { callIfFn } from '../../utils/index.js';
|
|
11
|
+
export function GameProvidersList(props) {
|
|
12
|
+
const viewGamesUrl = (data) => {
|
|
13
|
+
return props.viewGamesUrl
|
|
14
|
+
? callIfFn(props.viewGamesUrl, data)
|
|
15
|
+
.replace(':id', data.id)
|
|
16
|
+
.replace(':slug', data.slug)
|
|
17
|
+
: `/providers/${data.slug}`;
|
|
18
|
+
};
|
|
19
|
+
const gameProviders = props.gameProviders.map((provider) => GAME_PROVIDER_DATA[provider]);
|
|
20
|
+
const classNames = isString(props.className)
|
|
21
|
+
? { root: props.className }
|
|
22
|
+
: (props.className ?? {});
|
|
23
|
+
const chunked = useChunk(gameProviders, 18);
|
|
24
|
+
return (_jsxs("div", { className: classNames.root, children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Providers' }), _jsx("div", { className: "mt-lg grid grid-cols-3 gap-1.5 lg:grid-cols-6 lg:gap-2.5", children: chunked.loadedItems.map((provider) => (_jsx(Link, { href: viewGamesUrl(provider), className: twMerge('bg-gray-800 flex h-full w-full items-center overflow-hidden rounded-md lg:h-[5.75rem]', classNames.thumbnailRoot), "aria-label": `View ${provider.name} games`, children: _jsx(Image, { src: props.gameProviderImages?.[provider.id] ?? provider.logo, alt: "", width: 300, height: 150, className: twMerge('mx-auto h-auto w-full', classNames.thumbnailImage) }) }, provider.id))) }), _jsxs("div", { className: "mt-2xl flex flex-col items-center lg:mt-3xl", children: [_jsx(Progress.Root, { min: 0, max: chunked.totalItems, value: chunked.totalLoadedItems, onValueChange: noop, className: "w-[12.5rem]", children: _jsx(Progress.Track, { className: "bg-bg-tertiary", children: _jsx(Progress.Range, {}) }) }), _jsx("p", { className: "text-button-tertiary-fg mt-md text-sm", children: `Displaying ${chunked.totalLoadedItems} of ${chunked.totalItems}` }), chunked.hasNext && (_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, onClick: chunked.next, className: "mt-lg", children: "Load More" }))] })] }));
|
|
25
|
+
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
interface ClassNameEntries {
|
|
2
|
+
root?: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
}
|
|
1
5
|
export interface GameProps {
|
|
2
6
|
badge?: 'top' | 'new' | 'popular';
|
|
3
|
-
|
|
7
|
+
className?: string | ClassNameEntries;
|
|
4
8
|
}
|
|
5
9
|
export declare function Game(props: GameProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { isString } from 'lodash-es';
|
|
2
3
|
import Image from 'next/image';
|
|
3
4
|
import { twMerge } from 'tailwind-merge';
|
|
4
5
|
import { useFavoriteGamesQuery, useMarkGameAsFavoriteMutation, useSessionQuery, useUnmarkGameAsFavoriteMutation, } from '../../client/hooks/index.js';
|
|
@@ -7,7 +8,7 @@ import { GameLaunchTrigger } from '../GameLaunch/index.js';
|
|
|
7
8
|
import { BadgeNew } from './BadgeNew.js';
|
|
8
9
|
import { BadgePopular } from './BadgePopular.js';
|
|
9
10
|
import { BadgeTop } from './BadgeTop.js';
|
|
10
|
-
import { useGameContext } from './
|
|
11
|
+
import { useGameContext } from './GamesContext.js';
|
|
11
12
|
export function Game(props) {
|
|
12
13
|
const game = useGameContext();
|
|
13
14
|
const sessionQuery = useSessionQuery();
|
|
@@ -17,7 +18,10 @@ export function Game(props) {
|
|
|
17
18
|
const markGameAsFavoriteMutation = useMarkGameAsFavoriteMutation();
|
|
18
19
|
const unmarkGameAsFavoriteMutation = useUnmarkGameAsFavoriteMutation();
|
|
19
20
|
const markedAsFavorite = favoriteGames.some((favoriteGame) => favoriteGame.id === game.id);
|
|
20
|
-
|
|
21
|
+
const classNames = isString(props.className)
|
|
22
|
+
? { root: props.className }
|
|
23
|
+
: (props.className ?? {});
|
|
24
|
+
return (_jsxs(GameLaunchTrigger, { game: game, className: twMerge('animate-scale-in relative block w-full shadow-sm', classNames.root), children: [props.badge === 'new' && (_jsx(BadgeNew, { className: "absolute left-0 top-0 size-[3.75rem]" })), props.badge === 'top' && (_jsx(BadgeTop, { className: "absolute left-0 top-0 size-[3.75rem]" })), props.badge === 'popular' && (_jsx(BadgePopular, { className: "absolute left-0 top-0 size-[3.75rem]" })), session?.status === 'authenticated' && (_jsx("div", { role: "button", onClick: (e) => {
|
|
21
25
|
e.preventDefault();
|
|
22
26
|
e.stopPropagation();
|
|
23
27
|
if (markGameAsFavoriteMutation.isPending)
|
|
@@ -33,5 +37,5 @@ export function Game(props) {
|
|
|
33
37
|
}, "aria-disabled": markGameAsFavoriteMutation.isPending ||
|
|
34
38
|
unmarkGameAsFavoriteMutation.isPending, className: "rounded-xs absolute right-2 top-2 flex size-9 items-center justify-center bg-black/65 blur-[0.5px]", children: _jsx(Star01Icon, { className: twMerge('size-5', markedAsFavorite
|
|
35
39
|
? 'fill-yellow-400 text-yellow-400'
|
|
36
|
-
: 'text-white') }) })), _jsx(Image, { src: game.image, alt: "", width: 200, height: 200, priority: true, className: "aspect-square w-full rounded-t-md object-cover" }), _jsx("span", { className: twMerge('bg-bg-tertiary text-text-primary-brand block w-full truncate rounded-b-md px-2 py-3.5 text-center text-xs font-semibold',
|
|
40
|
+
: 'text-white') }) })), _jsx(Image, { src: game.image, alt: "", width: 200, height: 200, priority: true, className: "aspect-square w-full rounded-t-md object-cover" }), _jsx("span", { className: twMerge('bg-bg-tertiary text-text-primary-brand block w-full truncate rounded-b-md px-2 py-3.5 text-center text-xs font-semibold', classNames.title), children: game.name })] }));
|
|
37
41
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { type GamesCarouselProps } from './GamesCarousel';
|
|
2
2
|
import { type GamesListProps } from './GamesList';
|
|
3
|
-
export type GamesProps =
|
|
4
|
-
layout: 'list';
|
|
5
|
-
} & GamesListProps) | ({
|
|
6
|
-
layout?: 'carousel';
|
|
7
|
-
} & GamesCarouselProps);
|
|
3
|
+
export type GamesProps = GamesListProps | GamesCarouselProps;
|
|
8
4
|
export declare function Games(props: GamesProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import useEmblaCarousel, {} from 'embla-carousel-react';
|
|
4
|
+
import { isString } from 'lodash-es';
|
|
4
5
|
import Link from 'next/link';
|
|
5
6
|
import { useCallback, useEffect, useState } from 'react';
|
|
6
7
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -9,7 +10,7 @@ import { ArrowLeftIcon, ArrowRightIcon, ChevronRightIcon, GamingPad01Icon, Spinn
|
|
|
9
10
|
import { Button } from '../../ui/index.js';
|
|
10
11
|
import { Empty } from '../Empty.js';
|
|
11
12
|
import { Game } from './Game.js';
|
|
12
|
-
import { GameContext } from './
|
|
13
|
+
import { GameContext } from './GamesContext.js';
|
|
13
14
|
export function GamesCarousel__client(props) {
|
|
14
15
|
const numOfRows = props.numOfRows ?? 1;
|
|
15
16
|
const gamesQuery = useGamesQuery({
|
|
@@ -51,11 +52,17 @@ export function GamesCarousel__client(props) {
|
|
|
51
52
|
onSelect(emblaApi);
|
|
52
53
|
emblaApi.on('reInit', onSelect).on('select', onSelect);
|
|
53
54
|
}, [emblaApi, onSelect]);
|
|
54
|
-
|
|
55
|
+
const classNames = isString(props.className)
|
|
56
|
+
? { root: props.className }
|
|
57
|
+
: (props.className ?? {});
|
|
58
|
+
return (_jsxs("div", { className: classNames.root, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Games' }), _jsx("div", { className: "grow" }), _jsxs("div", { className: "flex items-center justify-center gap-xl", children: [_jsxs(Link, { href: props.viewAllUrl ?? '/games', className: "text-button-tertiary-fg flex gap-sm text-sm font-semibold", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", onClick: onPrevButtonClick, disabled: prevBtnDisabled, "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-l-none", onClick: onNextButtonClick, disabled: nextBtnDisabled && !gamesQuery.hasNextPage
|
|
55
59
|
? true
|
|
56
60
|
: gamesQuery.isFetchingNextPage, "aria-label": "Next", children: gamesQuery.isFetchingNextPage ? (_jsx(SpinnerIcon, { className: "size-5" })) : (_jsx(ArrowRightIcon, { className: "size-5" })) })] })] })] }), games.length <= 0 && (_jsx(Empty, { icon: GamingPad01Icon, title: "No games", message: "No game is currently available. Please check back later", className: "mt-lg" })), games.length >= 1 && (_jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsx("div", { className: twMerge('grid auto-cols-[calc((100%-(0.375rem*2))/3)] grid-flow-col gap-sm lg:auto-cols-[calc((100%-(0.5rem*5))/6)] lg:gap-md', numOfRows === 3
|
|
57
61
|
? 'grid-rows-3'
|
|
58
62
|
: numOfRows === 2
|
|
59
63
|
? 'grid-rows-2'
|
|
60
|
-
: 'grid-rows-1'), children: games.map((game) => (_jsx(GameContext, { value: game, children: _jsx(Game, { badge: props.badge,
|
|
64
|
+
: 'grid-rows-1'), children: games.map((game) => (_jsx(GameContext, { value: game, children: _jsx(Game, { badge: props.badge, className: {
|
|
65
|
+
root: classNames.thumbnailRoot,
|
|
66
|
+
title: classNames.thumbnailTitle,
|
|
67
|
+
} }) }, game.id))) }) }))] }));
|
|
61
68
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { GamesInput__Next } from '@opexa/portal-sdk-core';
|
|
2
|
+
export interface ClassNameEntries {
|
|
3
|
+
root?: string;
|
|
4
|
+
thumbnailRoot?: string;
|
|
5
|
+
thumbnailTitle?: string;
|
|
6
|
+
}
|
|
2
7
|
export interface GamesCarouselProps {
|
|
8
|
+
layout: 'carousel';
|
|
3
9
|
/** @default "Games" */
|
|
4
10
|
heading?: string;
|
|
5
11
|
/**
|
|
@@ -13,7 +19,6 @@ export interface GamesCarouselProps {
|
|
|
13
19
|
filter?: GamesInput__Next['filter'];
|
|
14
20
|
search?: string;
|
|
15
21
|
sort?: GamesInput__Next['sort'];
|
|
16
|
-
className?: string;
|
|
17
|
-
gameNameClass?: string;
|
|
22
|
+
className?: string | ClassNameEntries;
|
|
18
23
|
}
|
|
19
24
|
export declare function GamesCarousel(props: GamesCarouselProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Game } from '@opexa/portal-sdk-core';
|
|
2
|
+
import type { GamesProps } from './Games';
|
|
3
|
+
export declare const GamesPropsContext: import("react").Context<GamesProps>, useGamesPropsContext: () => GamesProps;
|
|
4
|
+
export declare const GameContext: import("react").Context<Game>, useGameContext: () => Game;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { noop } from 'lodash-es';
|
|
3
|
+
import { isString, noop } from 'lodash-es';
|
|
4
4
|
import { useGamesQuery, useInfiniteQueryHelper } from '../../client/hooks/index.js';
|
|
5
5
|
import { GamingPad01Icon, SpinnerIcon } from '../../icons/index.js';
|
|
6
6
|
import { Button, Progress } from '../../ui/index.js';
|
|
7
7
|
import { Empty } from '../Empty.js';
|
|
8
8
|
import { Game } from './Game.js';
|
|
9
|
-
import { GameContext } from './
|
|
9
|
+
import { GameContext } from './GamesContext.js';
|
|
10
10
|
export function GamesList__client(props) {
|
|
11
11
|
const { loading, availableRows, totalRows, totalAvailableRows, hasNextPage, next, } = useInfiniteQueryHelper(useGamesQuery, {
|
|
12
12
|
first: props.first ?? 24,
|
|
@@ -14,7 +14,13 @@ export function GamesList__client(props) {
|
|
|
14
14
|
search: props.search,
|
|
15
15
|
sort: props.sort,
|
|
16
16
|
});
|
|
17
|
-
|
|
17
|
+
const classNames = isString(props.className)
|
|
18
|
+
? { root: props.className }
|
|
19
|
+
: (props.className ?? {});
|
|
20
|
+
return (_jsxs("div", { className: classNames.root, children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Games' }), totalRows <= 0 && (_jsx(Empty, { icon: loading ? SpinnerIcon : GamingPad01Icon, title: loading ? 'Just a moment' : 'No games', message: loading
|
|
18
21
|
? 'Fetching latest games...'
|
|
19
|
-
: 'No game is currently available. Please check back later', className: "mt-lg" })), totalRows >= 1 && (_jsxs(_Fragment, { children: [_jsx("div", { className: "mt-lg grid grid-cols-3 gap-1.5 lg:grid-cols-6 lg:gap-2.5", children: availableRows.map((game) => (_jsx(GameContext, { value: game, children: _jsx(Game, { badge: props.badge,
|
|
22
|
+
: 'No game is currently available. Please check back later', className: "mt-lg" })), totalRows >= 1 && (_jsxs(_Fragment, { children: [_jsx("div", { className: "mt-lg grid grid-cols-3 gap-1.5 lg:grid-cols-6 lg:gap-2.5", children: availableRows.map((game) => (_jsx(GameContext, { value: game, children: _jsx(Game, { badge: props.badge, className: {
|
|
23
|
+
root: classNames.thumbnailRoot,
|
|
24
|
+
title: classNames.thumbnailTitle,
|
|
25
|
+
} }) }, game.id))) }), _jsxs("div", { className: "mt-2xl flex flex-col items-center lg:mt-3xl", children: [_jsx(Progress.Root, { min: 0, max: totalRows, value: totalAvailableRows, onValueChange: noop, className: "w-[12.5rem]", children: _jsx(Progress.Track, { className: "bg-bg-tertiary", children: _jsx(Progress.Range, {}) }) }), _jsx("p", { className: "text-button-tertiary-fg mt-md text-sm", children: `Displaying ${totalAvailableRows} of ${totalRows}` }), hasNextPage && (_jsx(Button, { size: "sm", variant: "outline", fullWidth: false, onClick: next, className: "mt-lg", children: "Load More" }))] })] }))] }));
|
|
20
26
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { GamesInput__Next } from '@opexa/portal-sdk-core';
|
|
2
|
+
export interface ClassNameEntries {
|
|
3
|
+
root?: string;
|
|
4
|
+
thumbnailRoot?: string;
|
|
5
|
+
thumbnailTitle?: string;
|
|
6
|
+
}
|
|
2
7
|
export interface GamesListProps {
|
|
8
|
+
layout: 'list';
|
|
3
9
|
badge?: 'top' | 'new' | 'popular';
|
|
4
10
|
/** @default 24 */
|
|
5
11
|
first?: number;
|
|
@@ -8,7 +14,6 @@ export interface GamesListProps {
|
|
|
8
14
|
search?: string;
|
|
9
15
|
/** @default "Games"*/
|
|
10
16
|
heading?: string;
|
|
11
|
-
className?: string;
|
|
12
|
-
gameNameClass?: string;
|
|
17
|
+
className?: string | ClassNameEntries;
|
|
13
18
|
}
|
|
14
19
|
export declare function GamesList(props: GamesListProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -6,6 +6,7 @@ import Link from 'next/link';
|
|
|
6
6
|
import { useCallback, useEffect, useState } from 'react';
|
|
7
7
|
import { ArrowLeftIcon, ArrowRightIcon } from '../../icons/index.js';
|
|
8
8
|
import { Button } from '../../ui/index.js';
|
|
9
|
+
import { useJackpotsPropsContext } from './JackpotsContext.js';
|
|
9
10
|
export function JackpotGameProviders({ gameProviders, }) {
|
|
10
11
|
const [emblaRef, emblaApi] = useEmblaCarousel({
|
|
11
12
|
align: 'start',
|
|
@@ -34,5 +35,7 @@ export function JackpotGameProviders({ gameProviders, }) {
|
|
|
34
35
|
emblaApi.on('select', onSelect);
|
|
35
36
|
emblaApi.on('reInit', onSelect);
|
|
36
37
|
}, [emblaApi, onSelect]);
|
|
37
|
-
|
|
38
|
+
const jackpotsProps = useJackpotsPropsContext();
|
|
39
|
+
return (_jsxs("div", { className: "p-4 pb-8", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-text-primary-900 text-lg font-semibold", children: "Jackpot Game Providers" }), _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 mt-3 overflow-hidden", ref: emblaRef, children: _jsx("div", { className: "flex gap-3.5", children: gameProviders.map((provider, i) => (_jsx(Link, { href: `/${provider.slug}`, className: "bg-gray-800 lg:bg-bg-primary-900 min-w-27.5 rounded-md", children: _jsx(Image, { src: jackpotsProps.gameProviderImages?.[provider.id] ??
|
|
40
|
+
provider.logo, alt: "provider", className: "size-full" }) }, i))) }) })] }));
|
|
38
41
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { GameProvider } from '@opexa/portal-sdk-core';
|
|
2
|
+
import type { ImageProps } from 'next/image';
|
|
2
3
|
export interface JackpotsProps {
|
|
3
4
|
/** @default "Jackpots" */
|
|
4
5
|
heading?: string;
|
|
5
6
|
className?: string;
|
|
6
7
|
gameProviders: GameProvider[];
|
|
8
|
+
gameProviderImages?: Partial<Record<GameProvider, ImageProps['src']>>;
|
|
7
9
|
}
|
|
8
10
|
export declare function Jackpots(props: JackpotsProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -27,5 +27,5 @@ export function Promo__client(props) {
|
|
|
27
27
|
in: tz(localeInfo.timezone),
|
|
28
28
|
})] }), _jsx(Prose, { className: "mt-2xl lg:mt-6", dangerouslySetInnerHTML: {
|
|
29
29
|
__html: promo.description,
|
|
30
|
-
} })
|
|
30
|
+
} })] }));
|
|
31
31
|
}
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/** @default "/promos" */
|
|
5
|
-
viewAllUrl?: string;
|
|
6
|
-
/** @default "/promos" */
|
|
7
|
-
viewPromoDetailsUrl?: string;
|
|
8
|
-
/** @default "/promos/cashback" */
|
|
9
|
-
viewCashbackDetailsUrl?: string;
|
|
10
|
-
/** @default 1 */
|
|
11
|
-
className?: string;
|
|
12
|
-
/** @default 'carousel' */
|
|
13
|
-
layout?: 'carousel' | 'grid';
|
|
14
|
-
}
|
|
1
|
+
import { type PromosCarouselProps } from './PromosCarousel';
|
|
2
|
+
import { type PromosGridProps } from './PromosGrid';
|
|
3
|
+
export type PromosProps = PromosCarouselProps | PromosGridProps;
|
|
15
4
|
export declare function Promos(props: PromosProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export interface PromosCarouselProps {
|
|
2
|
+
layout: 'carousel';
|
|
3
|
+
/** @default "Promotions" */
|
|
4
|
+
heading?: string;
|
|
5
|
+
/** @default "/promos" */
|
|
6
|
+
viewAllUrl?: string;
|
|
7
|
+
/** @default "/promos" */
|
|
8
|
+
viewPromoDetailsUrl?: string;
|
|
9
|
+
/** @default "/promos/cashback" */
|
|
10
|
+
viewCashbackDetailsUrl?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function PromosCarousel(props: PromosCarouselProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export interface PromosGridProps {
|
|
2
|
+
layout: 'grid';
|
|
3
|
+
/** @default "Promotions" */
|
|
4
|
+
heading?: string;
|
|
5
|
+
/** @default "/promos" */
|
|
6
|
+
viewPromoDetailsUrl?: string;
|
|
7
|
+
/** @default "/promos/cashback" */
|
|
8
|
+
viewCashbackDetailsUrl?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function PromosGrid(props: PromosGridProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -16,6 +16,7 @@ interface SearchProps {
|
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
viewGamesUrl?: string | ((gameProvider: GameProviderData) => string);
|
|
19
|
+
gameProviderImages?: Partial<Record<GameProvider, ImageProps['src']>>;
|
|
19
20
|
}
|
|
20
21
|
export declare function Search(props: SearchProps): import("react/jsx-runtime").JSX.Element;
|
|
21
22
|
export {};
|
|
@@ -56,7 +56,8 @@ export function Search(props) {
|
|
|
56
56
|
}, className: "pl-10 pr-16", placeholder: "Search", autoComplete: "off" }), _jsx(Presence, { present: search.length > 0, asChild: true, lazyMount: true, children: _jsx("button", { type: "button", className: "text-text-secondary-700 absolute right-3.5 top-1/2 -translate-y-1/2 font-semibold", onClick: () => {
|
|
57
57
|
setSearch('');
|
|
58
58
|
inputRef.current?.focus();
|
|
59
|
-
}, children: "Clear" }) })] }) }), _jsx("div", { className: "lg:bg-bg-primary lg:border-border-primary mt-2xl p-xl pb-3xl lg:mt-2 lg:rounded-xl lg:border", children: search.length <= 0 ? (_jsx(Alert, { message: "Search for your favorite game or provider." })) : search.length >= 1 && search.length <= 2 ? (_jsx(Alert, { message: "Search requires at least 3 characters." })) : (_jsxs(_Fragment, { children: [empty && _jsx(Alert, { message: "No results found" }), !empty && (_jsxs(_Fragment, { children: [gameProviders.length > 0 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "text-lg font-semibold", children: "Providers" }), _jsx("div", { className: "mt-3.5 grid grid-cols-3 gap-1.5 lg:grid-cols-9 lg:gap-3.5", children: gameProviders.map((provider) => (_jsx(Link, { href: viewGamesUrl(provider), "aria-label": `View ${provider.name} games`, className: "bg-gray-800 flex h-14 w-full items-center rounded-md", children: _jsx(Image, { src:
|
|
59
|
+
}, children: "Clear" }) })] }) }), _jsx("div", { className: "lg:bg-bg-primary lg:border-border-primary mt-2xl p-xl pb-3xl lg:mt-2 lg:rounded-xl lg:border", children: search.length <= 0 ? (_jsx(Alert, { message: "Search for your favorite game or provider." })) : search.length >= 1 && search.length <= 2 ? (_jsx(Alert, { message: "Search requires at least 3 characters." })) : (_jsxs(_Fragment, { children: [empty && _jsx(Alert, { message: "No results found" }), !empty && (_jsxs(_Fragment, { children: [gameProviders.length > 0 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "text-lg font-semibold", children: "Providers" }), _jsx("div", { className: "mt-3.5 grid grid-cols-3 gap-1.5 lg:grid-cols-9 lg:gap-3.5", children: gameProviders.map((provider) => (_jsx(Link, { href: viewGamesUrl(provider), "aria-label": `View ${provider.name} games`, className: "bg-gray-800 flex h-14 w-full items-center rounded-md", children: _jsx(Image, { src: props.gameProviderImages?.[provider.id] ??
|
|
60
|
+
provider.logo, alt: "", width: 100, height: 50, className: "mx-auto h-auto w-full" }) }, provider.id))) })] })), games.length > 0 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mt-3xl text-lg font-semibold", children: "Games" }), _jsx("div", { className: "mt-3.5 grid grid-cols-3 gap-1.5 lg:grid-cols-9 lg:gap-3.5", children: games.map((game) => (_jsxs(GameLaunchTrigger, { game: game, className: "block w-full shadow-sm", onClick: () => {
|
|
60
61
|
globalStore.search.setOpen(false);
|
|
61
62
|
}, children: [_jsx(Image, { src: game.image, alt: "", width: 200, height: 200, priority: true, className: "aspect-square w-full rounded-t-md object-cover" }), _jsx("span", { className: "bg-bg-tertiary text-text-primary-brand block w-full truncate rounded-b-md px-2 py-2.5 text-center text-xs font-semibold", children: game.name })] }, game.id))) })] })), _jsx(Presence, { present: gamesQuery.hasNextPage, children: _jsx(Button, { variant: "outline", className: "mx-auto mt-12 w-fit", onClick: () => gamesQuery.fetchNextPage(), children: "Load More" }) })] }))] })) })] }) })] }) }));
|
|
62
63
|
}
|
|
@@ -4,5 +4,5 @@ import { DepositRecordsTable } from './DepositRecordsTable.js';
|
|
|
4
4
|
import { TransactionRecordsTable } from './TransactionRecordsTable.js';
|
|
5
5
|
import { WithdrawalRecordsTable } from './WithdrawalRecordsTable.js';
|
|
6
6
|
export function TransactionRecords(props) {
|
|
7
|
-
return (_jsxs("div", { className: props.className, children: [_jsx("h2", { className: "text-sm font-semibold leading-tight lg:text-lg", children: "Transactions" }), _jsx("p", { className: "text-text-tertiary-600 mt-xs text-sm leading-tight", children: "View your transaction records" }), _jsxs(Tabs.Root, { className: "mt-lg lg:mt-2xl", defaultValue: "transactions", lazyMount: true, unmountOnExit: true, children: [_jsxs(Tabs.List, { children: [_jsx(Tabs.Trigger, { value: "transactions", children: "Transactions" }), _jsx(Tabs.Trigger, { value: "deposits", children: "Deposits" }), _jsx(Tabs.Trigger, { value: "withdrawals", children: "Withdrawals" }), _jsx(Tabs.Indicator, {})] }), _jsx("div", { className: "border-border-secondary mt-2xl hidden border-t lg:block" }), _jsx("h3", { className: "text-text-secondary-700 mt-3xl text-sm font-semibold", children: "Table" }), _jsx(Tabs.Content, { value: "transactions", className: "mt-xl", children: _jsx(TransactionRecordsTable, {}) }), _jsx(Tabs.Content, { value: "deposits", className: "mt-xl", children: _jsx(DepositRecordsTable, {}) }), _jsx(Tabs.Content, { value: "withdrawals", className: "mt-xl", children: _jsx(WithdrawalRecordsTable, {}) })] })] }));
|
|
7
|
+
return (_jsxs("div", { className: props.className, children: [_jsx("h2", { className: "text-sm font-semibold leading-tight lg:text-lg", children: "Transactions" }), _jsx("p", { className: "text-text-tertiary-600 mt-xs text-sm leading-tight", children: "View your transaction records" }), _jsxs(Tabs.Root, { className: "mt-lg lg:mt-2xl", defaultValue: "transactions", lazyMount: true, unmountOnExit: true, children: [_jsxs(Tabs.List, { children: [_jsx(Tabs.Trigger, { value: "transactions", children: "All Transactions" }), _jsx(Tabs.Trigger, { value: "deposits", children: "Deposits" }), _jsx(Tabs.Trigger, { value: "withdrawals", children: "Withdrawals" }), _jsx(Tabs.Indicator, {})] }), _jsx("div", { className: "border-border-secondary mt-2xl hidden border-t lg:block" }), _jsx("h3", { className: "text-text-secondary-700 mt-3xl text-sm font-semibold", children: "Table" }), _jsx(Tabs.Content, { value: "transactions", className: "mt-xl", children: _jsx(TransactionRecordsTable, {}) }), _jsx(Tabs.Content, { value: "deposits", className: "mt-xl", children: _jsx(DepositRecordsTable, {}) }), _jsx(Tabs.Content, { value: "withdrawals", className: "mt-xl", children: _jsx(WithdrawalRecordsTable, {}) })] })] }));
|
|
8
8
|
}
|