@opexa/portal-components 0.1.56 → 0.1.57
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/useAddFavoriteGameMutation.d.ts +2 -0
- package/dist/client/hooks/useAddFavoriteGameMutation.js +39 -0
- package/dist/client/hooks/useCreateGameSessionMutation.js +2 -2
- package/dist/client/hooks/useEndGameSessionMutation.js +1 -1
- package/dist/client/hooks/useFavoriteGamesQuery.d.ts +2 -2
- package/dist/client/hooks/useFavoriteGamesQuery.js +10 -3
- package/dist/client/hooks/useMarkGameAsFavoriteMutation.js +1 -9
- package/dist/client/hooks/useRecentGamesQuery.js +3 -11
- package/dist/client/hooks/useRemoveFavoriteGameMutation.d.ts +2 -0
- package/dist/client/hooks/useRemoveFavoriteGameMutation.js +27 -0
- package/dist/client/hooks/useUnmarkGameAsFavoriteMutation.js +1 -1
- package/dist/components/FavoriteGames/FavoriteGames.client.js +9 -8
- package/dist/components/GameLaunch/GameLaunch.lazy.js +11 -14
- package/dist/components/GameLaunch/GameLaunchTrigger.js +1 -1
- package/dist/components/Games/Game.js +13 -13
- package/dist/handlers/v4Cookies.d.ts +9 -0
- package/dist/handlers/v4Cookies.js +49 -0
- package/dist/server/utils/prefetchFavoriteGamesQuery.js +9 -2
- package/dist/services/portal.d.ts +23 -1
- package/dist/services/portal.js +25 -1
- package/dist/services/queries.d.ts +3 -3
- package/dist/services/queries.js +7 -12
- package/dist/services/wallet.d.ts +1 -23
- package/dist/services/wallet.js +1 -25
- package/dist/types/index.d.ts +0 -3
- package/dist/ui/AlertDialog/AlertDialog.d.ts +154 -154
- package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +14 -14
- package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
- package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
- package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
- package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
- package/dist/ui/Collapsible/Collapsible.d.ts +20 -20
- package/dist/ui/Collapsible/collapsible.recipe.d.ts +5 -5
- package/dist/ui/Combobox/Combobox.d.ts +42 -42
- package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
- package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
- package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
- package/dist/ui/Dialog/Dialog.d.ts +33 -33
- package/dist/ui/Dialog/dialog.recipe.d.ts +3 -3
- package/dist/ui/Drawer/Drawer.d.ts +33 -33
- package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
- package/dist/ui/Menu/Menu.d.ts +90 -90
- package/dist/ui/Menu/menu.recipe.d.ts +5 -5
- package/dist/ui/Popover/Popover.d.ts +88 -88
- package/dist/ui/Popover/popover.recipe.d.ts +8 -8
- package/dist/ui/Select/Select.d.ts +45 -45
- package/dist/ui/Select/select.recipe.d.ts +3 -3
- package/dist/ui/Table/Table.d.ts +21 -21
- package/dist/ui/Table/table.anatomy.d.ts +1 -1
- package/dist/ui/Table/table.recipe.d.ts +3 -3
- package/dist/ui/Tabs/Tabs.d.ts +15 -15
- package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
- package/dist/utils/get-fingerprint.d.ts +8 -0
- package/dist/utils/get-fingerprint.js +37 -0
- package/dist/utils/mutationKeys.d.ts +2 -2
- package/dist/utils/mutationKeys.js +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useMutation } from '@tanstack/react-query';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { getSession } from '../../client/services/getSession.js';
|
|
4
|
+
import { addFavoriteGame } from '../../services/portal.js';
|
|
5
|
+
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
6
|
+
import { getAddFavoriteGameMutationKey } from '../../utils/mutationKeys.js';
|
|
7
|
+
import { getFavoriteGamesQueryKey, getGamesQueryKey, } from '../../utils/queryKeys.js';
|
|
8
|
+
export const useAddFavoriteGameMutation = (config) => {
|
|
9
|
+
const queryClient = getQueryClient();
|
|
10
|
+
const mutation = useMutation({
|
|
11
|
+
...config,
|
|
12
|
+
mutationKey: getAddFavoriteGameMutationKey(),
|
|
13
|
+
mutationFn: async (id) => {
|
|
14
|
+
const session = await getSession();
|
|
15
|
+
invariant(session.status === 'authenticated');
|
|
16
|
+
await addFavoriteGame(id, {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${session.token}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
const games = queryClient
|
|
22
|
+
.getQueriesData({
|
|
23
|
+
queryKey: getGamesQueryKey({}),
|
|
24
|
+
})
|
|
25
|
+
.map(([, arr]) => arr)
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.flatMap((obj) => obj.pages.flatMap((q) => q.edges.map((edge) => edge.node)));
|
|
28
|
+
const game = games.find((game) => game.id === id);
|
|
29
|
+
queryClient.setQueryData(getFavoriteGamesQueryKey(), (prev = []) => {
|
|
30
|
+
if (game) {
|
|
31
|
+
return [...prev, game];
|
|
32
|
+
}
|
|
33
|
+
return prev;
|
|
34
|
+
});
|
|
35
|
+
return id;
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
return mutation;
|
|
39
|
+
};
|
|
@@ -16,10 +16,10 @@ export const useCreateGameSessionMutation = (config) => {
|
|
|
16
16
|
const id = ObjectId.generate(ObjectType.GameSession).toString();
|
|
17
17
|
const session = await getSession();
|
|
18
18
|
invariant(session.status === 'authenticated');
|
|
19
|
-
if (LEGACY_GAME_PROVIDERS.includes(game.provider)) {
|
|
19
|
+
if ('provider' in game && LEGACY_GAME_PROVIDERS.includes(game.provider)) {
|
|
20
20
|
await createGameSession__legacy({
|
|
21
21
|
id,
|
|
22
|
-
game:
|
|
22
|
+
game: game.reference,
|
|
23
23
|
homepageUrl: window.location.origin.includes('local')
|
|
24
24
|
? undefined
|
|
25
25
|
: window.location.origin,
|
|
@@ -12,7 +12,7 @@ export const useEndGameSessionMutation = (config) => {
|
|
|
12
12
|
mutationFn: async (input) => {
|
|
13
13
|
const session = await getSession();
|
|
14
14
|
invariant(session.status === 'authenticated');
|
|
15
|
-
if (LEGACY_GAME_PROVIDERS.includes(input.game.provider)) {
|
|
15
|
+
if ('provider' in input.game && LEGACY_GAME_PROVIDERS.includes(input.game.provider)) {
|
|
16
16
|
await endGameSession__legacy(input.session.id, {
|
|
17
17
|
headers: {
|
|
18
18
|
Authorization: `Bearer ${session.token}`,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const useFavoriteGamesQuery: Query<
|
|
1
|
+
import type { Game, Query } from '../../types';
|
|
2
|
+
export declare const useFavoriteGamesQuery: Query<Game[]>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useQuery } from '@tanstack/react-query';
|
|
2
2
|
import invariant from 'tiny-invariant';
|
|
3
|
-
import {
|
|
3
|
+
import { getGamesv2__next } from '../../services/cmsPortal.js';
|
|
4
|
+
import { getFavoriteGames } from '../../services/portal.js';
|
|
4
5
|
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
5
6
|
import { getFavoriteGamesQueryKey, getSessionQueryKey, } from '../../utils/queryKeys.js';
|
|
6
7
|
import { getSession } from '../services/getSession.js';
|
|
@@ -22,13 +23,19 @@ export const useFavoriteGamesQuery = (config) => {
|
|
|
22
23
|
queryFn: async () => getSession(),
|
|
23
24
|
});
|
|
24
25
|
invariant(session.status === 'authenticated');
|
|
25
|
-
const favoriteGames = getFavoriteGames({
|
|
26
|
+
const favoriteGames = await getFavoriteGames({
|
|
26
27
|
signal,
|
|
27
28
|
headers: {
|
|
28
29
|
Authorization: `Bearer ${session.token}`,
|
|
29
30
|
},
|
|
30
31
|
});
|
|
31
|
-
|
|
32
|
+
const ids = favoriteGames?.length
|
|
33
|
+
? [...new Set(favoriteGames.map((g) => g.id))]
|
|
34
|
+
: [];
|
|
35
|
+
if (ids.length <= 0)
|
|
36
|
+
return [];
|
|
37
|
+
const results = await Promise.all(ids.map((id) => getGamesv2__next(id, { signal })));
|
|
38
|
+
return results.flatMap((res) => res.edges.map((edge) => edge.node));
|
|
32
39
|
},
|
|
33
40
|
});
|
|
34
41
|
};
|
|
@@ -28,15 +28,7 @@ export const useMarkGameAsFavoriteMutation = (config) => {
|
|
|
28
28
|
const game = games.find((game) => game.reference === id);
|
|
29
29
|
queryClient.setQueryData(getFavoriteGamesQueryKey(), (prev = []) => {
|
|
30
30
|
if (game) {
|
|
31
|
-
return [
|
|
32
|
-
...prev,
|
|
33
|
-
{
|
|
34
|
-
id: game.reference,
|
|
35
|
-
name: game.name,
|
|
36
|
-
type: game.type,
|
|
37
|
-
provider: game.provider,
|
|
38
|
-
},
|
|
39
|
-
];
|
|
31
|
+
return [...prev, game];
|
|
40
32
|
}
|
|
41
33
|
});
|
|
42
34
|
return id;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useQuery } from '@tanstack/react-query';
|
|
2
2
|
import invariant from 'tiny-invariant';
|
|
3
|
-
import {
|
|
3
|
+
import { getGamesv2__next } from '../../services/cmsPortal.js';
|
|
4
4
|
import { getRecentGames } from '../../services/portal.js';
|
|
5
5
|
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
6
6
|
import { getRecentGamesQueryKey, getSessionQueryKey, } from '../../utils/queryKeys.js';
|
|
@@ -34,16 +34,8 @@ export const useRecentGamesQuery = (config) => {
|
|
|
34
34
|
: [];
|
|
35
35
|
if (ids.length <= 0)
|
|
36
36
|
return [];
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
reference: {
|
|
40
|
-
in: ids,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
}, { signal });
|
|
44
|
-
return ids
|
|
45
|
-
.map((id) => res.edges.find((e) => id === e.node.reference)?.node ?? null)
|
|
46
|
-
.filter((g) => g !== null);
|
|
37
|
+
const results = await Promise.all(ids.map((id) => getGamesv2__next(id, { signal })));
|
|
38
|
+
return results.flatMap((res) => res.edges.map((edge) => edge.node));
|
|
47
39
|
},
|
|
48
40
|
});
|
|
49
41
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useMutation } from '@tanstack/react-query';
|
|
2
|
+
import invariant from 'tiny-invariant';
|
|
3
|
+
import { removeFavoriteGame } from '../../services/portal.js';
|
|
4
|
+
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
5
|
+
import { getRemoveFavoriteGameMutationKey } from '../../utils/mutationKeys.js';
|
|
6
|
+
import { getFavoriteGamesQueryKey } from '../../utils/queryKeys.js';
|
|
7
|
+
import { getSession } from '../services/getSession.js';
|
|
8
|
+
export const useRemoveFavoriteGameMutation = (config) => {
|
|
9
|
+
const queryClient = getQueryClient();
|
|
10
|
+
const mutation = useMutation({
|
|
11
|
+
...config,
|
|
12
|
+
mutationKey: getRemoveFavoriteGameMutationKey(),
|
|
13
|
+
mutationFn: async (id) => {
|
|
14
|
+
const session = await getSession();
|
|
15
|
+
invariant(session.status === 'authenticated');
|
|
16
|
+
await removeFavoriteGame(id, {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${session.token}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
queryClient.setQueryData(getFavoriteGamesQueryKey(), (prev) => {
|
|
22
|
+
return prev?.filter((game) => game.id !== id);
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
return mutation;
|
|
27
|
+
};
|
|
@@ -19,7 +19,7 @@ export const useUnmarkGameAsFavoriteMutation = (config) => {
|
|
|
19
19
|
},
|
|
20
20
|
});
|
|
21
21
|
queryClient.setQueryData(getFavoriteGamesQueryKey(), (prev) => {
|
|
22
|
-
return prev?.filter((game) => game.
|
|
22
|
+
return prev?.filter((game) => game.reference !== id);
|
|
23
23
|
});
|
|
24
24
|
},
|
|
25
25
|
});
|
|
@@ -9,8 +9,8 @@ import { useAccountQuery } from '../../client/hooks/useAccountQuery.js';
|
|
|
9
9
|
import { useBypassKycChecker, } from '../../client/hooks/useBypassKycChecker.js';
|
|
10
10
|
import { useFavoriteGamesQuery } from '../../client/hooks/useFavoriteGamesQuery.js';
|
|
11
11
|
import { useFeatureFlag } from '../../client/hooks/useFeatureFlag.js';
|
|
12
|
+
import { useRemoveFavoriteGameMutation } from '../../client/hooks/useRemoveFavoriteGameMutation.js';
|
|
12
13
|
import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
|
|
13
|
-
import { useUnmarkGameAsFavoriteMutation } from '../../client/hooks/useUnmarkGameAsFavoriteMutation.js';
|
|
14
14
|
import { toaster } from '../../client/utils/toaster.js';
|
|
15
15
|
import { ArrowLeftIcon } from '../../icons/ArrowLeftIcon.js';
|
|
16
16
|
import { ArrowRightIcon } from '../../icons/ArrowRightIcon.js';
|
|
@@ -63,7 +63,7 @@ function Item({ game, bypassKycCheck, className, }) {
|
|
|
63
63
|
const session = sessionQuery.data;
|
|
64
64
|
const accountQuery = useAccountQuery();
|
|
65
65
|
const account = accountQuery.data;
|
|
66
|
-
const
|
|
66
|
+
const removeFavoriteGameMutation = useRemoveFavoriteGameMutation({
|
|
67
67
|
onSuccess() {
|
|
68
68
|
toaster.success({
|
|
69
69
|
description: 'Game removed from favorites',
|
|
@@ -75,19 +75,20 @@ function Item({ game, bypassKycCheck, className, }) {
|
|
|
75
75
|
});
|
|
76
76
|
},
|
|
77
77
|
});
|
|
78
|
-
const
|
|
78
|
+
const addRemoveFavoriteGameEnabled = session?.status !== 'authenticated'
|
|
79
79
|
? false
|
|
80
80
|
: featureFlag.enabled
|
|
81
81
|
? account?.status !== 'VERIFICATION_LOCKED'
|
|
82
82
|
: true;
|
|
83
|
-
return (_jsxs(GameLaunchTrigger, { bypassKycCheck: bypassKycCheck, game: game, className: twMerge('hover:-translate-y-1 relative block w-full animate-scale-in shadow-sm transition-transform duration-200', className?.thumbnailRoot), children: [
|
|
83
|
+
return (_jsxs(GameLaunchTrigger, { bypassKycCheck: bypassKycCheck, game: game, className: twMerge('hover:-translate-y-1 relative block w-full animate-scale-in shadow-sm transition-transform duration-200', className?.thumbnailRoot), children: [addRemoveFavoriteGameEnabled && (_jsx("div", { role: "button", tabIndex: 0, onClick: (e) => {
|
|
84
84
|
e.preventDefault();
|
|
85
85
|
e.stopPropagation();
|
|
86
|
-
if (
|
|
86
|
+
if (removeFavoriteGameMutation.isPending)
|
|
87
87
|
return;
|
|
88
|
-
|
|
89
|
-
}, "aria-disabled":
|
|
90
|
-
|
|
88
|
+
removeFavoriteGameMutation.mutate(game.id);
|
|
89
|
+
}, "aria-disabled": removeFavoriteGameMutation.isPending, className: "absolute top-2 right-2 flex size-9 items-center justify-center rounded-xs bg-black/65 blur-[0.5px]", children: _jsx(Star01Icon, { className: "size-5 fill-yellow-400 text-yellow-400" }) })), _jsx(Image, { src: getGameImageUrl({
|
|
90
|
+
reference: game.reference,
|
|
91
91
|
provider: game.provider,
|
|
92
|
+
image: game.image,
|
|
92
93
|
}), alt: "", width: 200, height: 200, loading: "lazy", unoptimized: true, className: "aspect-square w-full rounded-t-md object-cover" }), _jsx("span", { className: twMerge('block w-full truncate rounded-b-md bg-bg-tertiary px-2 py-3.5 text-center font-semibold text-text-primary-brand text-xs', className?.thumbnailTitle), children: game.name })] }));
|
|
93
94
|
}
|
|
@@ -3,12 +3,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { Dialog } from '@ark-ui/react/dialog';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import { useShallow } from 'zustand/shallow';
|
|
6
|
+
import { useAddFavoriteGameMutation } from '../../client/hooks/useAddFavoriteGameMutation.js';
|
|
6
7
|
import { useDisclosure } from '../../client/hooks/useDisclosure.js';
|
|
7
8
|
import { useEndGameSessionMutation } from '../../client/hooks/useEndGameSessionMutation.js';
|
|
8
9
|
import { useFavoriteGamesQuery } from '../../client/hooks/useFavoriteGamesQuery.js';
|
|
9
10
|
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
10
|
-
import {
|
|
11
|
-
import { useUnmarkGameAsFavoriteMutation } from '../../client/hooks/useUnmarkGameAsFavoriteMutation.js';
|
|
11
|
+
import { useRemoveFavoriteGameMutation } from '../../client/hooks/useRemoveFavoriteGameMutation.js';
|
|
12
12
|
import { toaster } from '../../client/utils/toaster.js';
|
|
13
13
|
import { AlertCircleIcon } from '../../icons/AlertCircleIcon.js';
|
|
14
14
|
import { ChevronDownIcon } from '../../icons/ChevronDownIcon.js';
|
|
@@ -48,7 +48,7 @@ export function GameLaunch({ locale = 'local' }) {
|
|
|
48
48
|
const favoriteGamesQuery = useFavoriteGamesQuery();
|
|
49
49
|
const favoriteGames = favoriteGamesQuery.data ?? [];
|
|
50
50
|
const endGameSessionMutation = useEndGameSessionMutation();
|
|
51
|
-
const
|
|
51
|
+
const addFavoriteGameMutation = useAddFavoriteGameMutation({
|
|
52
52
|
onSuccess() {
|
|
53
53
|
toaster.success({
|
|
54
54
|
description: 'Game added to favorites',
|
|
@@ -60,7 +60,7 @@ export function GameLaunch({ locale = 'local' }) {
|
|
|
60
60
|
});
|
|
61
61
|
},
|
|
62
62
|
});
|
|
63
|
-
const
|
|
63
|
+
const removeFavoriteGameMutation = useRemoveFavoriteGameMutation({
|
|
64
64
|
onSuccess() {
|
|
65
65
|
toaster.success({
|
|
66
66
|
description: 'Game removed from favorites',
|
|
@@ -76,8 +76,9 @@ export function GameLaunch({ locale = 'local' }) {
|
|
|
76
76
|
return !globalStore.gameLaunch.details.game
|
|
77
77
|
? false
|
|
78
78
|
: 'reference' in globalStore.gameLaunch.details.game
|
|
79
|
-
? favoriteGame.
|
|
80
|
-
|
|
79
|
+
? favoriteGame.reference ===
|
|
80
|
+
globalStore.gameLaunch.details.game.reference
|
|
81
|
+
: favoriteGame.reference === globalStore.gameLaunch.details.game.id;
|
|
81
82
|
});
|
|
82
83
|
return (_jsxs(_Fragment, { children: [_jsx(Dialog.Root, { open: globalStore.gameLaunch.details.status !== 'WAITING' &&
|
|
83
84
|
!cancelDisclosure.open, lazyMount: true, closeOnEscape: false, closeOnInteractOutside: false, children: _jsx(Portal, { children: _jsx(Dialog.Positioner, { className: "fixed inset-0 z-dialog", children: _jsxs(Dialog.Content, { className: "relative size-full ui-closed:animate-dialog-out ui-open:animate-dialog-in overflow-y-auto bg-bg-primary-alt", children: [_jsx(Presence, { asChild: true, lazyMount: true, unmountOnExit: true, present: !maximizeDisclosure.open, children: _jsxs("section", { className: "absolute top-safe-area-inset-top left-0 z-1 flex h-[3.25rem] w-full ui-closed:animate-slide-out-down ui-open:animate-slide-in-down items-center gap-2 bg-bg-primary-alt px-4 py-2", children: [_jsx(IconButton, { size: "xs", variant: "outline", onClick: () => {
|
|
@@ -86,19 +87,15 @@ export function GameLaunch({ locale = 'local' }) {
|
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
89
|
cancelDisclosure.setOpen(true);
|
|
89
|
-
}, disabled: globalStore.gameLaunch.details.status === 'LOADING', children: _jsx(ChevronLeftIcon, { className: "size-5" }) }), _jsx("div", { className: "grow" }), _jsx(IconButton, { size: "xs", variant: "outline", disabled:
|
|
90
|
-
|
|
90
|
+
}, disabled: globalStore.gameLaunch.details.status === 'LOADING', children: _jsx(ChevronLeftIcon, { className: "size-5" }) }), _jsx("div", { className: "grow" }), _jsx(IconButton, { size: "xs", variant: "outline", disabled: removeFavoriteGameMutation.isPending ||
|
|
91
|
+
addFavoriteGameMutation.isPending, onClick: () => {
|
|
91
92
|
if (!globalStore.gameLaunch.details.game)
|
|
92
93
|
return;
|
|
93
94
|
if (markedAsFavorite) {
|
|
94
|
-
|
|
95
|
-
? globalStore.gameLaunch.details.game.reference
|
|
96
|
-
: globalStore.gameLaunch.details.game.id);
|
|
95
|
+
removeFavoriteGameMutation.mutate(globalStore.gameLaunch.details.game.id);
|
|
97
96
|
}
|
|
98
97
|
else {
|
|
99
|
-
|
|
100
|
-
? globalStore.gameLaunch.details.game.reference
|
|
101
|
-
: globalStore.gameLaunch.details.game.id);
|
|
98
|
+
addFavoriteGameMutation.mutate(globalStore.gameLaunch.details.game.id);
|
|
102
99
|
}
|
|
103
100
|
}, children: _jsx(Star01Icon, { className: twMerge('size-5', markedAsFavorite
|
|
104
101
|
? 'fill-yellow-400 text-yellow-400'
|
|
@@ -51,7 +51,7 @@ export function GameLaunchTrigger(props) {
|
|
|
51
51
|
: globalStore.gameLaunch.details.status !== 'WAITING'
|
|
52
52
|
? true
|
|
53
53
|
: props.disabled;
|
|
54
|
-
return (_jsx(ark.button, { type: "button", "aria-label": `Play ${game.name}`, "data-state": sessionQuery.data?.status === 'unauthenticated'
|
|
54
|
+
return (_jsx(ark.button, { type: "button", "aria-label": `Play ${'name' in game ? game.name : game.id}`, "data-state": sessionQuery.data?.status === 'unauthenticated'
|
|
55
55
|
? globalStore.signIn.open
|
|
56
56
|
? 'open'
|
|
57
57
|
: 'closed'
|
|
@@ -4,11 +4,11 @@ import Image, {} from 'next/image';
|
|
|
4
4
|
import { useMemo, useState } from 'react';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { useAccountQuery } from '../../client/hooks/useAccountQuery.js';
|
|
7
|
+
import { useAddFavoriteGameMutation } from '../../client/hooks/useAddFavoriteGameMutation.js';
|
|
7
8
|
import { useFavoriteGamesQuery } from '../../client/hooks/useFavoriteGamesQuery.js';
|
|
8
9
|
import { useFeatureFlag } from '../../client/hooks/useFeatureFlag.js';
|
|
9
|
-
import {
|
|
10
|
+
import { useRemoveFavoriteGameMutation } from '../../client/hooks/useRemoveFavoriteGameMutation.js';
|
|
10
11
|
import { useSessionQuery } from '../../client/hooks/useSessionQuery.js';
|
|
11
|
-
import { useUnmarkGameAsFavoriteMutation } from '../../client/hooks/useUnmarkGameAsFavoriteMutation.js';
|
|
12
12
|
import { toaster } from '../../client/utils/toaster.js';
|
|
13
13
|
import { Star01Icon } from '../../icons/Star01Icon.js';
|
|
14
14
|
import RainbowballImg from '../../images/rainbow-ball-online.webp';
|
|
@@ -27,7 +27,7 @@ export function Game(props) {
|
|
|
27
27
|
const account = accountQuery.data;
|
|
28
28
|
const favoriteGamesQuery = useFavoriteGamesQuery();
|
|
29
29
|
const favoriteGames = favoriteGamesQuery.data ?? [];
|
|
30
|
-
const
|
|
30
|
+
const addFavoriteGameMutation = useAddFavoriteGameMutation({
|
|
31
31
|
onSuccess() {
|
|
32
32
|
toaster.success({
|
|
33
33
|
description: 'Game added to favorites',
|
|
@@ -39,7 +39,7 @@ export function Game(props) {
|
|
|
39
39
|
});
|
|
40
40
|
},
|
|
41
41
|
});
|
|
42
|
-
const
|
|
42
|
+
const removeFavoriteGameMutation = useRemoveFavoriteGameMutation({
|
|
43
43
|
onSuccess() {
|
|
44
44
|
toaster.success({
|
|
45
45
|
description: 'Game removed from favorites',
|
|
@@ -51,32 +51,32 @@ export function Game(props) {
|
|
|
51
51
|
});
|
|
52
52
|
},
|
|
53
53
|
});
|
|
54
|
-
const markedAsFavorite = favoriteGames.some((favoriteGame) => favoriteGame.
|
|
54
|
+
const markedAsFavorite = favoriteGames.some((favoriteGame) => favoriteGame.reference === game.reference);
|
|
55
55
|
const classNames = isString(props.className)
|
|
56
56
|
? { root: props.className }
|
|
57
57
|
: (props.className ?? {});
|
|
58
|
-
const
|
|
58
|
+
const addRemoveFavoriteGameEnabled = session?.status !== 'authenticated'
|
|
59
59
|
? false
|
|
60
60
|
: featureFlag.enabled
|
|
61
61
|
? account?.status !== 'VERIFICATION_LOCKED'
|
|
62
62
|
: true;
|
|
63
|
-
return (_jsxs(GameLaunchTrigger, { bypassKycCheck: props.bypassKycCheck, game: game, className: twMerge('group md:hover:-translate-y-1 relative flex h-full w-full flex-col shadow-sm transition-transform duration-200', classNames.root), "aria-label": `Play ${game.name} game`, children: [props.badge === 'new' && (_jsx(BadgeNew, { className: "absolute top-0 left-0 size-[3.75rem]" })), props.badge === 'top' && (_jsx(BadgeTop, { className: "absolute top-0 left-0 size-[3.75rem]" })), props.badge === 'popular' && (_jsx(BadgePopular, { className: "absolute top-0 left-0 size-[3.75rem]" })),
|
|
63
|
+
return (_jsxs(GameLaunchTrigger, { bypassKycCheck: props.bypassKycCheck, game: game, className: twMerge('group md:hover:-translate-y-1 relative flex h-full w-full flex-col shadow-sm transition-transform duration-200', classNames.root), "aria-label": `Play ${game.name} game`, children: [props.badge === 'new' && (_jsx(BadgeNew, { className: "absolute top-0 left-0 size-[3.75rem]" })), props.badge === 'top' && (_jsx(BadgeTop, { className: "absolute top-0 left-0 size-[3.75rem]" })), props.badge === 'popular' && (_jsx(BadgePopular, { className: "absolute top-0 left-0 size-[3.75rem]" })), addRemoveFavoriteGameEnabled && (_jsx("div", { role: "button", tabIndex: 0, onClick: (e) => {
|
|
64
64
|
e.preventDefault();
|
|
65
65
|
e.stopPropagation();
|
|
66
|
-
if (
|
|
66
|
+
if (addFavoriteGameMutation.isPending)
|
|
67
67
|
return;
|
|
68
|
-
if (
|
|
68
|
+
if (removeFavoriteGameMutation.isPending)
|
|
69
69
|
return;
|
|
70
70
|
if (markedAsFavorite) {
|
|
71
|
-
|
|
71
|
+
removeFavoriteGameMutation.mutate(game.id);
|
|
72
72
|
}
|
|
73
73
|
else {
|
|
74
|
-
|
|
74
|
+
addFavoriteGameMutation.mutate(game.id);
|
|
75
75
|
}
|
|
76
76
|
}, "aria-label": markedAsFavorite
|
|
77
77
|
? 'Unmark as favorite game'
|
|
78
|
-
: 'Mark as favorite game', "aria-disabled":
|
|
79
|
-
|
|
78
|
+
: 'Mark as favorite game', "aria-disabled": addFavoriteGameMutation.isPending ||
|
|
79
|
+
removeFavoriteGameMutation.isPending, className: "absolute top-2 right-2 flex size-9 items-center justify-center rounded-xs bg-black/65 opacity-100 blur-[0.5px] transition-opacity duration-200 md:opacity-0 md:group-hover:opacity-100", children: _jsx(Star01Icon, { className: twMerge('size-5 text-white transition-colors duration-200 hover:text-yellow-400', markedAsFavorite
|
|
80
80
|
? 'fill-yellow-400 text-yellow-400'
|
|
81
81
|
: 'text-white') }) })), _jsx(GameImage, { priority: props.priority }), _jsx("span", { className: twMerge('flex w-full flex-1 items-center justify-center break-words rounded-b-md bg-bg-tertiary px-2 py-3.5 text-center font-semibold text-text-primary-brand text-xs', classNames.title), children: game.name })] }));
|
|
82
82
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NextResponse } from 'next/server';
|
|
2
|
+
/**
|
|
3
|
+
* Proxies AUTH `Set-Cookie` headers (the v4 refresh cookie) onto the outgoing
|
|
4
|
+
* Next.js response. In the proxy model the browser never talks to AUTH
|
|
5
|
+
* directly, so the cookie is re-scoped to the app domain (the `Domain`
|
|
6
|
+
* attribute from AUTH is dropped) and the route handler forwards it back to
|
|
7
|
+
* AUTH on subsequent requests via the `Cookie` header.
|
|
8
|
+
*/
|
|
9
|
+
export declare function applyV4SetCookie(response: NextResponse, setCookie: string[]): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proxies AUTH `Set-Cookie` headers (the v4 refresh cookie) onto the outgoing
|
|
3
|
+
* Next.js response. In the proxy model the browser never talks to AUTH
|
|
4
|
+
* directly, so the cookie is re-scoped to the app domain (the `Domain`
|
|
5
|
+
* attribute from AUTH is dropped) and the route handler forwards it back to
|
|
6
|
+
* AUTH on subsequent requests via the `Cookie` header.
|
|
7
|
+
*/
|
|
8
|
+
export function applyV4SetCookie(response, setCookie) {
|
|
9
|
+
for (const raw of setCookie) {
|
|
10
|
+
const parsed = parseSetCookie(raw);
|
|
11
|
+
if (!parsed)
|
|
12
|
+
continue;
|
|
13
|
+
response.cookies.set(parsed.name, parsed.value, parsed.options);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function parseSetCookie(raw) {
|
|
17
|
+
const [pair, ...attrs] = raw.split(';');
|
|
18
|
+
const eq = pair.indexOf('=');
|
|
19
|
+
if (eq < 0)
|
|
20
|
+
return null;
|
|
21
|
+
const name = pair.slice(0, eq).trim();
|
|
22
|
+
const value = pair.slice(eq + 1).trim();
|
|
23
|
+
const options = {};
|
|
24
|
+
for (const attr of attrs) {
|
|
25
|
+
const [k, v] = attr.split('=').map((s) => s.trim());
|
|
26
|
+
const key = k.toLowerCase();
|
|
27
|
+
if (key === 'path')
|
|
28
|
+
options.path = v;
|
|
29
|
+
else if (key === 'max-age')
|
|
30
|
+
options.maxAge = Number(v);
|
|
31
|
+
else if (key === 'expires') {
|
|
32
|
+
const d = new Date(v);
|
|
33
|
+
if (!Number.isNaN(d.getTime()))
|
|
34
|
+
options.expires = d;
|
|
35
|
+
}
|
|
36
|
+
else if (key === 'httponly')
|
|
37
|
+
options.httpOnly = true;
|
|
38
|
+
else if (key === 'secure')
|
|
39
|
+
options.secure = true;
|
|
40
|
+
else if (key === 'samesite') {
|
|
41
|
+
const lv = (v ?? '').toLowerCase();
|
|
42
|
+
if (lv === 'strict' || lv === 'lax' || lv === 'none') {
|
|
43
|
+
options.sameSite = lv;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// `Domain` is intentionally dropped so the cookie scopes to the app.
|
|
47
|
+
}
|
|
48
|
+
return { name, value, options };
|
|
49
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cache } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { getGamesv2__next } from '../../services/cmsPortal.js';
|
|
3
|
+
import { getFavoriteGames } from '../../services/portal.js';
|
|
3
4
|
import { getQueryClient } from '../../utils/getQueryClient.js';
|
|
4
5
|
import { log } from '../../utils/log.js';
|
|
5
6
|
import { getFavoriteGamesQueryKey } from '../../utils/queryKeys.js';
|
|
@@ -18,7 +19,13 @@ export const prefetchFavoriteGamesQuery = cache(async () => {
|
|
|
18
19
|
Authorization: `Bearer ${session.token}`,
|
|
19
20
|
},
|
|
20
21
|
});
|
|
21
|
-
|
|
22
|
+
const ids = favoriteGames?.length
|
|
23
|
+
? [...new Set(favoriteGames.map((g) => g.id))]
|
|
24
|
+
: [];
|
|
25
|
+
if (ids.length <= 0)
|
|
26
|
+
return [];
|
|
27
|
+
const results = await Promise.all(ids.map((id) => getGamesv2__next(id, { signal })));
|
|
28
|
+
return results.flatMap((res) => res.edges.map((edge) => edge.node));
|
|
22
29
|
},
|
|
23
30
|
})
|
|
24
31
|
.catch(() => log.text("'prefetchFavoriteGamesQuery' failed", 'error'));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Simplify } from 'type-fest';
|
|
2
|
-
import type { GameType, OnboardingPlayerExperience, OnboardingStatus, Platform, RecentGame, RecommendedGame, TopWin } from '../types';
|
|
2
|
+
import type { FavoriteGame, GameType, OnboardingPlayerExperience, OnboardingStatus, Platform, RecentGame, RecommendedGame, TopWin } from '../types';
|
|
3
3
|
import { type GraphQLRequestOptions } from './graphqlRequest';
|
|
4
4
|
export interface PlatformQuery extends Platform {
|
|
5
5
|
}
|
|
@@ -12,6 +12,28 @@ export interface RecentGamesQuery {
|
|
|
12
12
|
recentGames: RecentGame[];
|
|
13
13
|
}
|
|
14
14
|
export declare const getRecentGames: (options?: GraphQLRequestOptions) => Promise<RecentGame[]>;
|
|
15
|
+
export interface FavoriteGamesQuery {
|
|
16
|
+
favoriteGames: FavoriteGame[];
|
|
17
|
+
}
|
|
18
|
+
export declare const getFavoriteGames: (options?: GraphQLRequestOptions) => Promise<FavoriteGame[]>;
|
|
19
|
+
export interface AddFavoriteGameMutation {
|
|
20
|
+
addFavoriteGame: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface AddFavoriteGameMutationVariables {
|
|
23
|
+
input: {
|
|
24
|
+
game: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare const addFavoriteGame: (id: string, options?: GraphQLRequestOptions) => Promise<void>;
|
|
28
|
+
export interface RemoveFavoriteGameMutation {
|
|
29
|
+
removeFavoriteGame: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface RemoveFavoriteGameMutationVariables {
|
|
32
|
+
input: {
|
|
33
|
+
game: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export declare const removeFavoriteGame: (id: string, options?: GraphQLRequestOptions) => Promise<void>;
|
|
15
37
|
export interface OnboardingStatusQuery {
|
|
16
38
|
onboardingStatus?: OnboardingStatus | null;
|
|
17
39
|
}
|
package/dist/services/portal.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cache } from 'react';
|
|
2
2
|
import { PORTAL_GRAPHQL_ENDPOINT } from '../constants/index.js';
|
|
3
3
|
import { graphqlRequest } from './graphqlRequest.js';
|
|
4
|
-
import { COMPLETE_ONBOARDING, ONBOARDING_STATUS, PLATFORM, RECENT_GAMES, RECOMMENDED_GAMES, SKIP_ONBOARDING, TOP_WINS, } from './queries.js';
|
|
4
|
+
import { ADD_FAVORITE_GAME, COMPLETE_ONBOARDING, FAVORITE_GAMES, ONBOARDING_STATUS, PLATFORM, RECENT_GAMES, RECOMMENDED_GAMES, REMOVE_FAVORITE_GAME, SKIP_ONBOARDING, TOP_WINS, } from './queries.js';
|
|
5
5
|
export const getPlatform = cache(async (options) => {
|
|
6
6
|
const res = await graphqlRequest(PORTAL_GRAPHQL_ENDPOINT, PLATFORM, undefined, {
|
|
7
7
|
cache: 'force-cache',
|
|
@@ -22,6 +22,30 @@ export const getRecentGames = cache(async (options) => {
|
|
|
22
22
|
const res = await graphqlRequest(PORTAL_GRAPHQL_ENDPOINT, RECENT_GAMES, undefined, options);
|
|
23
23
|
return res.recentGames;
|
|
24
24
|
});
|
|
25
|
+
export const getFavoriteGames = cache(async (options) => {
|
|
26
|
+
const res = await graphqlRequest(PORTAL_GRAPHQL_ENDPOINT, FAVORITE_GAMES, undefined, options);
|
|
27
|
+
return res.favoriteGames;
|
|
28
|
+
});
|
|
29
|
+
export const addFavoriteGame = async (id, options) => {
|
|
30
|
+
const res = await graphqlRequest(PORTAL_GRAPHQL_ENDPOINT, ADD_FAVORITE_GAME, { input: { game: id } }, options);
|
|
31
|
+
if (!res.addFavoriteGame) {
|
|
32
|
+
const error = new Error();
|
|
33
|
+
error.name = 'UnknownError';
|
|
34
|
+
error.message = 'Something went wrong';
|
|
35
|
+
Error.captureStackTrace?.(error, addFavoriteGame);
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
export const removeFavoriteGame = async (id, options) => {
|
|
40
|
+
const res = await graphqlRequest(PORTAL_GRAPHQL_ENDPOINT, REMOVE_FAVORITE_GAME, { input: { game: id } }, options);
|
|
41
|
+
if (!res.removeFavoriteGame) {
|
|
42
|
+
const error = new Error();
|
|
43
|
+
error.name = 'UnknownError';
|
|
44
|
+
error.message = 'Something went wrong';
|
|
45
|
+
Error.captureStackTrace?.(error, removeFavoriteGame);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
25
49
|
export const getOnboardingStatus = cache(async (options) => {
|
|
26
50
|
const res = await graphqlRequest(PORTAL_GRAPHQL_ENDPOINT, ONBOARDING_STATUS, undefined, options);
|
|
27
51
|
return res.onboardingStatus ?? null;
|
|
@@ -138,9 +138,9 @@ export declare const REGISTER_FCM_DEVICE = "\n mutation RegisterFCMDevice($inpu
|
|
|
138
138
|
export declare const UNREGISTER_FCM_DEVICE = "\n mutation UnregisterFCMDevice($input: UnregisterFCMDeviceInput!) {\n unregisterFCMDevice(input: $input)\n }\n";
|
|
139
139
|
export declare const LINK_FIREBASE_CLOUD_MESSAGING_DEVICE = "\n mutation LinkFirebaseCloudMessagingDevice(\n $input: LinkFirebaseCloudMessagingDeviceInput!\n ) {\n linkFirebaseCloudMessagingDevice(input: $input)\n }\n";
|
|
140
140
|
export declare const UNLINK_FIREBASE_CLOUD_MESSAGING_DEVICE = "\n mutation UnlinkFirebaseCloudMessagingDevice(\n $input: UnlinkFirebaseCloudMessagingDeviceInput!\n ) {\n unlinkFirebaseCloudMessagingDevice(input: $input)\n }\n";
|
|
141
|
-
export declare const
|
|
142
|
-
export declare const
|
|
143
|
-
export declare const FAVORITE_GAMES = "\n query FavoriteGames {\n favoriteGames {\n
|
|
141
|
+
export declare const ADD_FAVORITE_GAME = "\n mutation AddFavoriteGame($input: AddFavoriteGameInput!) {\n addFavoriteGame(input: $input)\n }\n";
|
|
142
|
+
export declare const REMOVE_FAVORITE_GAME = "\n mutation RemoveFavoriteGame($input: RemoveFavoriteGameInput!) {\n removeFavoriteGame(input: $input)\n }\n";
|
|
143
|
+
export declare const FAVORITE_GAMES = "\n query FavoriteGames {\n favoriteGames {\n id\n }\n }\n";
|
|
144
144
|
export declare const PLATFORM_GAMES = "\n query PlatformGames($first: Int, $after: Cursor, $filter: _GameFilterInput) {\n _games(first: $first, after: $after, filter: $filter) {\n totalCount\n pageInfo {\n hasNextPage\n endCursor\n }\n edges {\n cursor\n node {\n ... on _Game {\n id\n reference\n name\n displayName\n type\n provider\n status\n hidden\n hasFreeBet\n hasJackpot\n }\n }\n }\n }\n }\n";
|
|
145
145
|
export declare const GOOGLE_CLIENT_ID = "\n query GoogleClientId {\n googleClientId\n }\n";
|
|
146
146
|
export declare const FACEBOOK_CLIENT_ID = "\n query FacebookClientId {\n facebookClientId\n }\n";
|
package/dist/services/queries.js
CHANGED
|
@@ -3378,25 +3378,20 @@ export const UNLINK_FIREBASE_CLOUD_MESSAGING_DEVICE = /* GraphQL */ `
|
|
|
3378
3378
|
unlinkFirebaseCloudMessagingDevice(input: $input)
|
|
3379
3379
|
}
|
|
3380
3380
|
`;
|
|
3381
|
-
export const
|
|
3382
|
-
mutation
|
|
3383
|
-
|
|
3381
|
+
export const ADD_FAVORITE_GAME = /* GraphQL */ `
|
|
3382
|
+
mutation AddFavoriteGame($input: AddFavoriteGameInput!) {
|
|
3383
|
+
addFavoriteGame(input: $input)
|
|
3384
3384
|
}
|
|
3385
3385
|
`;
|
|
3386
|
-
export const
|
|
3387
|
-
mutation
|
|
3388
|
-
|
|
3386
|
+
export const REMOVE_FAVORITE_GAME = /* GraphQL */ `
|
|
3387
|
+
mutation RemoveFavoriteGame($input: RemoveFavoriteGameInput!) {
|
|
3388
|
+
removeFavoriteGame(input: $input)
|
|
3389
3389
|
}
|
|
3390
3390
|
`;
|
|
3391
3391
|
export const FAVORITE_GAMES = /* GraphQL */ `
|
|
3392
3392
|
query FavoriteGames {
|
|
3393
3393
|
favoriteGames {
|
|
3394
|
-
|
|
3395
|
-
id
|
|
3396
|
-
name
|
|
3397
|
-
type
|
|
3398
|
-
provider
|
|
3399
|
-
}
|
|
3394
|
+
id
|
|
3400
3395
|
}
|
|
3401
3396
|
}
|
|
3402
3397
|
`;
|