@opexa/portal-components 0.0.155 → 0.0.159

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 (131) hide show
  1. package/dist/client/hooks/useBonusesQuery.d.ts +2 -1
  2. package/dist/client/hooks/useBonusesQuery.js +3 -3
  3. package/dist/client/hooks/useMarkMessageAsReadMutation.js +5 -1
  4. package/dist/client/hooks/useMessagesQuery.js +1 -0
  5. package/dist/client/hooks/useUnreadMessagesCountQuery.js +1 -0
  6. package/dist/components/Bonuses/Bonuses.client.js +29 -17
  7. package/dist/components/Bonuses/Bonuses.js +2 -1
  8. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
  9. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
  10. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/QRPHDepositContext.d.ts +2 -2
  11. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit/useQRPHDeposit.d.ts +1 -1
  12. package/dist/components/KYC/CaptureSelfie.js +1 -2
  13. package/dist/components/KYC/KYC.js +1 -1
  14. package/dist/components/KYC/utils.d.ts +1 -0
  15. package/dist/components/KYC/utils.js +9 -0
  16. package/dist/components/Messages/Messages.lazy.js +2 -2
  17. package/dist/components/Messages/MessagesPopup.js +19 -14
  18. package/dist/components/News/News.js +1 -1
  19. package/dist/components/NewsFeed/News.d.ts +6 -0
  20. package/dist/components/NewsFeed/News.js +9 -0
  21. package/dist/components/NewsFeed/NewsFeedCarousel.d.ts +2 -2
  22. package/dist/components/NewsFeed/NewsFeedCarousel.js +2 -4
  23. package/dist/components/NewsFeed/NewsFeedList.d.ts +2 -2
  24. package/dist/components/NewsFeed/NewsFeedList.js +2 -6
  25. package/dist/components/PortalProvider/PortalProvider.js +2 -1
  26. package/dist/components/PortalProvider/WebVitals.d.ts +1 -0
  27. package/dist/components/PortalProvider/WebVitals.js +8 -0
  28. package/dist/components/Promos/Cashback.js +1 -1
  29. package/dist/components/Promos/CustomPromo.js +1 -1
  30. package/dist/components/Promos/Promo.js +1 -1
  31. package/dist/components/Search/Search.lazy.js +2 -2
  32. package/dist/constants/EnvVar.d.ts +1 -0
  33. package/dist/constants/EnvVar.js +5 -0
  34. package/dist/handlers.js +1 -4
  35. package/dist/server/utils/prefetchBonusesQuery.d.ts +2 -1
  36. package/dist/server/utils/prefetchBonusesQuery.js +3 -3
  37. package/dist/services/graphqlRequest.js +3 -1
  38. package/dist/services/httpRequest.js +3 -1
  39. package/dist/services/queries.d.ts +1 -1
  40. package/dist/services/queries.js +2 -2
  41. package/dist/services/wallet.d.ts +11 -2
  42. package/dist/services/wallet.js +2 -2
  43. package/dist/ui/AlertDialog/AlertDialog.d.ts +88 -88
  44. package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +8 -8
  45. package/dist/ui/Badge/Badge.d.ts +12 -12
  46. package/dist/ui/Badge/badge.anatomy.d.ts +1 -1
  47. package/dist/ui/Badge/badge.recipe.d.ts +3 -3
  48. package/dist/ui/Carousel/Carousel.d.ts +45 -45
  49. package/dist/ui/Carousel/carousel.recipe.d.ts +5 -5
  50. package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
  51. package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
  52. package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
  53. package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
  54. package/dist/ui/Combobox/Combobox.d.ts +42 -42
  55. package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
  56. package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
  57. package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
  58. package/dist/ui/Dialog/Dialog.d.ts +88 -88
  59. package/dist/ui/Dialog/dialog.recipe.d.ts +8 -8
  60. package/dist/ui/Drawer/Drawer.d.ts +33 -33
  61. package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
  62. package/dist/ui/Menu/Menu.d.ts +90 -90
  63. package/dist/ui/Menu/menu.recipe.d.ts +5 -5
  64. package/dist/ui/PasswordInput/PasswordInput.d.ts +18 -18
  65. package/dist/ui/PasswordInput/passwordInput.recipe.d.ts +3 -3
  66. package/dist/ui/Progress/Progress.d.ts +27 -27
  67. package/dist/ui/Progress/progress.recipe.d.ts +3 -3
  68. package/dist/ui/QrCode/QrCode.d.ts +25 -25
  69. package/dist/ui/QrCode/qrCode.recipe.d.ts +5 -5
  70. package/dist/ui/Select/Select.d.ts +45 -45
  71. package/dist/ui/Select/select.recipe.d.ts +3 -3
  72. package/dist/ui/Table/Table.d.ts +21 -21
  73. package/dist/ui/Table/table.anatomy.d.ts +1 -1
  74. package/dist/ui/Table/table.recipe.d.ts +3 -3
  75. package/dist/ui/Tabs/Tabs.d.ts +15 -15
  76. package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
  77. package/dist/ui/Tooltip/Tooltip.d.ts +30 -30
  78. package/dist/ui/Tooltip/tooltip.recipe.d.ts +5 -5
  79. package/dist/utils/queryKeys.d.ts +2 -2
  80. package/dist/utils/queryKeys.js +1 -1
  81. package/package.json +1 -1
  82. package/dist/components/KYC/backup/Header.d.ts +0 -1
  83. package/dist/components/KYC/backup/Header.js +0 -8
  84. package/dist/components/KYC/backup/Indicator.d.ts +0 -1
  85. package/dist/components/KYC/backup/Indicator.js +0 -9
  86. package/dist/components/KYC/backup/KYC.d.ts +0 -1
  87. package/dist/components/KYC/backup/KYC.js +0 -14
  88. package/dist/components/KYC/backup/KYC.lazy.d.ts +0 -1
  89. package/dist/components/KYC/backup/KYC.lazy.js +0 -26
  90. package/dist/components/KYC/backup/KYCContext.d.ts +0 -6
  91. package/dist/components/KYC/backup/KYCContext.js +0 -2
  92. package/dist/components/KYC/backup/Step1.d.ts +0 -1
  93. package/dist/components/KYC/backup/Step1.js +0 -13
  94. package/dist/components/KYC/backup/Step2.d.ts +0 -1
  95. package/dist/components/KYC/backup/Step2.js +0 -13
  96. package/dist/components/KYC/backup/Step3.d.ts +0 -1
  97. package/dist/components/KYC/backup/Step3.js +0 -13
  98. package/dist/components/KYC/backup/Step4.d.ts +0 -1
  99. package/dist/components/KYC/backup/Step4.js +0 -7
  100. package/dist/components/KYC/backup/useKYC.d.ts +0 -10
  101. package/dist/components/KYC/backup/useKYC.js +0 -8
  102. package/dist/components/KYC/loadModels.d.ts +0 -1
  103. package/dist/components/KYC/loadModels.js +0 -9
  104. package/dist/components/Messages/Message.d.ts +0 -1
  105. package/dist/components/Messages/Message.js +0 -35
  106. package/dist/components/Messages/MessageContext.d.ts +0 -6
  107. package/dist/components/Messages/MessageContext.js +0 -2
  108. package/dist/components/Messages/MessagePopup.d.ts +0 -1
  109. package/dist/components/Messages/MessagePopup.js +0 -20
  110. package/dist/components/Messages/MessageTrigger.d.ts +0 -8
  111. package/dist/components/Messages/MessageTrigger.js +0 -19
  112. package/dist/components/Quests/CountdownTimer.d.ts +0 -15
  113. package/dist/components/Quests/CountdownTimer.js +0 -33
  114. package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuest.d.ts +0 -4
  115. package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuest.js +0 -78
  116. package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestModal.d.ts +0 -8
  117. package/dist/components/Quests/DailyCheckInQuest/DailyCheckInQuestModal.js +0 -9
  118. package/dist/components/Quests/OnboardingQuest/OnboardingQuest.d.ts +0 -4
  119. package/dist/components/Quests/OnboardingQuest/OnboardingQuest.js +0 -4
  120. package/dist/components/Quests/WageringQuest/WageringQuest.d.ts +0 -4
  121. package/dist/components/Quests/WageringQuest/WageringQuest.js +0 -20
  122. package/dist/components/Quests/WageringQuest/WageringQuestModal.d.ts +0 -9
  123. package/dist/components/Quests/WageringQuest/WageringQuestModal.js +0 -9
  124. package/dist/constants/BranchCode.d.ts +0 -4
  125. package/dist/constants/BranchCode.js +0 -42
  126. package/dist/icons/BellRingIcon.d.ts +0 -2
  127. package/dist/icons/BellRingIcon.js +0 -4
  128. package/dist/utils/dataUrlToBlob.d.ts +0 -1
  129. package/dist/utils/dataUrlToBlob.js +0 -11
  130. package/dist/utils/resizeImageSize.d.ts +0 -2
  131. package/dist/utils/resizeImageSize.js +0 -11
@@ -1,2 +1,3 @@
1
+ import { type BonusesInput } from '../../services/wallet';
1
2
  import type { Bonus, Query } from '../../types';
2
- export declare const useBonusesQuery: Query<Bonus[]>;
3
+ export declare const useBonusesQuery: Query<Bonus[], BonusesInput>;
@@ -5,7 +5,7 @@ import { getQueryClient } from '../../utils/getQueryClient.js';
5
5
  import { getBonusesCountQueryKey, getBonusesQueryKey, } from '../../utils/queryKeys.js';
6
6
  import { getSession } from '../services/getSession.js';
7
7
  import { useSessionQuery } from './useSessionQuery.js';
8
- export const useBonusesQuery = (config) => {
8
+ export const useBonusesQuery = (input, config) => {
9
9
  const queryClient = getQueryClient();
10
10
  const sessionQuery = useSessionQuery();
11
11
  const query = useQuery({
@@ -14,11 +14,11 @@ export const useBonusesQuery = (config) => {
14
14
  enabled: config?.enabled === false
15
15
  ? false
16
16
  : sessionQuery.data?.status === 'authenticated',
17
- queryKey: getBonusesQueryKey(),
17
+ queryKey: getBonusesQueryKey(input),
18
18
  queryFn: async ({ signal }) => {
19
19
  const session = await getSession();
20
20
  invariant(session.status === 'authenticated');
21
- const bonuses = await getBonuses({
21
+ const bonuses = await getBonuses(input, {
22
22
  signal,
23
23
  headers: {
24
24
  Authorization: `Bearer ${session.token}`,
@@ -44,7 +44,11 @@ export const useMarkMessageAsReadMutation = (config) => {
44
44
  })),
45
45
  };
46
46
  });
47
- queryClient.setQueryData(getUnreadMessagesCountQueryKey(), (prev) => {
47
+ queryClient.setQueriesData({
48
+ queryKey: getUnreadMessagesCountQueryKey(),
49
+ exact: false,
50
+ type: 'all',
51
+ }, (prev) => {
48
52
  return prev && prev > 0 ? prev - 1 : 0;
49
53
  });
50
54
  return id;
@@ -7,6 +7,7 @@ import { useSessionQuery } from './useSessionQuery.js';
7
7
  export const useMessagesQuery = (input, config) => {
8
8
  const sessionQuery = useSessionQuery();
9
9
  const query = useInfiniteQuery({
10
+ staleTime: 1000 * 2,
10
11
  ...config,
11
12
  enabled: config?.enabled === false
12
13
  ? false
@@ -7,6 +7,7 @@ import { useSessionQuery } from './useSessionQuery.js';
7
7
  export const useUnreadMessagesCountQuery = (input, config) => {
8
8
  const sessionQuery = useSessionQuery();
9
9
  const query = useQuery({
10
+ staleTime: 1000 * 2,
10
11
  ...config,
11
12
  enabled: config?.enabled === false
12
13
  ? false
@@ -1,10 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { isAfter } from 'date-fns';
4
3
  import { clamp } from 'lodash-es';
5
4
  import Image from 'next/image';
6
5
  import Link from 'next/link';
7
- import { useState } from 'react';
6
+ import { usePathname, useRouter, useSearchParams } from 'next/navigation';
8
7
  import { z } from 'zod';
9
8
  import { useShallow } from 'zustand/shallow';
10
9
  import { useBonusesQuery } from '../../client/hooks/useBonusesQuery.js';
@@ -23,32 +22,45 @@ import { Button } from '../../ui/Button/index.js';
23
22
  import { Popover } from '../../ui/Popover/index.js';
24
23
  import { Progress } from '../../ui/Progress/index.js';
25
24
  import { SegmentGroup } from '../../ui/SegmentGroup/index.js';
26
- import { capitalize } from '../../utils/capitalize.js';
27
25
  import { formatNumber } from '../../utils/formatNumber.js';
28
26
  import { parseDecimal } from '../../utils/parseDecimal.js';
29
27
  import { ClaimSpotBonus } from './ClaimSpotBonus.js';
30
- const TABS = ['ALL', 'ACTIVE', 'CASHBACKS'];
28
+ const TabSchema = z
29
+ .enum(['all', 'active', 'cashbacks'])
30
+ .optional()
31
+ .nullable()
32
+ .catch('all')
33
+ .transform((v) => v ?? 'all');
31
34
  export function Bonuses__client(props) {
32
- const [tab, setTab] = useState(TABS[0]);
35
+ const router = useRouter();
36
+ const pathname = usePathname();
37
+ const searchParams = useSearchParams();
38
+ const tab = TabSchema.parse(searchParams.get('tab'));
39
+ const setTab = (tab) => {
40
+ const params = new URLSearchParams(searchParams.toString());
41
+ params.set('tab', tab);
42
+ router.push(`${pathname}?${params.toString()}`);
43
+ };
33
44
  const bonusesQuery = useBonusesQuery({
45
+ ...(tab === 'active' && {
46
+ filter: {
47
+ expiration: {
48
+ greaterThanOrEqual: new Date(),
49
+ },
50
+ },
51
+ }),
52
+ }, {
34
53
  refetchInterval: 5000,
54
+ enabled: tab !== 'cashbacks',
35
55
  });
36
56
  const cashbackBonusesQuery = useCashbackBonusesQuery({
37
57
  refetchInterval: 5000,
38
58
  });
39
- const bonuses = tab === 'CASHBACKS'
40
- ? []
41
- : (bonusesQuery.data ?? []).filter((bonus) => {
42
- return tab === 'ACTIVE' ? (new Date(), bonus.expiration) : true;
43
- });
44
- const cashbackBonuses = (cashbackBonusesQuery.data ?? []).filter((bonus) => {
45
- return tab === 'ACTIVE'
46
- ? isAfter(new Date(), bonus.cashback.activationEndDateTime)
47
- : true;
48
- });
59
+ const bonuses = bonusesQuery.data ?? [];
60
+ const cashbackBonuses = cashbackBonusesQuery.data ?? [];
49
61
  return (_jsxs(_Fragment, { children: [_jsxs("div", { className: props.className, children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Rewards' }), _jsxs(SegmentGroup.Root, { value: tab, onValueChange: (details) => {
50
- setTab(z.enum(TABS).parse(details.value));
51
- }, className: "mt-3", children: [TABS.map((value) => (_jsxs(SegmentGroup.Item, { value: value, children: [_jsx(SegmentGroup.ItemText, { children: capitalize(value) }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }, value))), _jsx(SegmentGroup.Indicator, {})] }), _jsxs("div", { className: "mt-3xl grid gap-3xl lg:mt-lg lg:grid-cols-3", children: [tab === 'ALL' && _jsx(SpotBonus, {}), tab !== 'CASHBACKS' && (_jsx(_Fragment, { children: bonuses.map((bonus) => (_jsx(Bonus, { data: bonus, viewDetailsUrl: props.viewBonusDetailsUrl ?? '/rewards' }, bonus.id))) })), cashbackBonuses.map((cashbackBonus) => (_jsx(CashbackBonus, { data: cashbackBonus }, cashbackBonus.id)))] })] }), _jsx(ClaimSpotBonus, {})] }));
62
+ setTab(TabSchema.parse(details.value));
63
+ }, className: "mt-3", children: [_jsxs(SegmentGroup.Item, { value: "all", children: [_jsx(SegmentGroup.ItemText, { children: "All" }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }), _jsxs(SegmentGroup.Item, { value: "active", children: [_jsx(SegmentGroup.ItemText, { children: "Active" }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }), _jsxs(SegmentGroup.Item, { value: "cashbacks", children: [_jsx(SegmentGroup.ItemText, { children: "Cashbacks" }), _jsx(SegmentGroup.ItemControl, {}), _jsx(SegmentGroup.ItemHiddenInput, {})] }), _jsx(SegmentGroup.Indicator, {})] }), _jsxs("div", { className: "mt-3xl grid gap-3xl lg:mt-lg lg:grid-cols-3", children: [tab === 'all' && _jsx(SpotBonus, {}), bonuses.map((bonus) => (_jsx(Bonus, { data: bonus, viewDetailsUrl: props.viewBonusDetailsUrl ?? '/rewards' }, bonus.id))), cashbackBonuses.map((cashbackBonus) => (_jsx(CashbackBonus, { data: cashbackBonus }, cashbackBonus.id)))] })] }), _jsx(ClaimSpotBonus, {})] }));
52
64
  }
53
65
  function Bonus(props) {
54
66
  const bonus = props.data;
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Suspense } from 'react';
2
3
  import { prefetchBonusesQuery } from '../../server/utils/prefetchBonusesQuery.js';
3
4
  import { prefetchCashbacksQuery } from '../../server/utils/prefetchCashbacksQuery.js';
4
5
  import { Bonuses__client } from './Bonuses.client.js';
5
6
  export async function Bonuses(props) {
6
7
  await Promise.allSettled([prefetchBonusesQuery(), prefetchCashbacksQuery()]);
7
- return _jsx(Bonuses__client, { ...props });
8
+ return (_jsx(Suspense, { fallback: null, children: _jsx(Bonuses__client, { ...props }) }));
8
9
  }
@@ -1,6 +1,6 @@
1
1
  export declare const OnlineBankDepositContext: (props: {
2
2
  value: {
3
- view: "form" | "vca";
3
+ view: "vca" | "form";
4
4
  status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
5
5
  verify: () => void;
6
6
  reset: () => void;
@@ -13,7 +13,7 @@ export declare const OnlineBankDepositContext: (props: {
13
13
  } & {
14
14
  children?: import("react").ReactNode | undefined;
15
15
  }) => React.ReactNode, useOnlineBankDepositContext: () => {
16
- view: "form" | "vca";
16
+ view: "vca" | "form";
17
17
  status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
18
18
  verify: () => void;
19
19
  reset: () => void;
@@ -1,7 +1,7 @@
1
1
  import type { Deposit } from '../../../../types';
2
2
  export type UseOnlineBankDepositReturn = ReturnType<typeof useOnlineBankDeposit>;
3
3
  export declare function useOnlineBankDeposit(): {
4
- view: "form" | "vca";
4
+ view: "vca" | "form";
5
5
  status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
6
6
  verify: () => void;
7
7
  reset: () => void;
@@ -1,6 +1,6 @@
1
1
  export declare const QRPHDepositContext: (props: {
2
2
  value: {
3
- view: "form" | "qrCode";
3
+ view: "qrCode" | "form";
4
4
  status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
5
5
  verify: () => void;
6
6
  reset: () => void;
@@ -13,7 +13,7 @@ export declare const QRPHDepositContext: (props: {
13
13
  } & {
14
14
  children?: import("react").ReactNode | undefined;
15
15
  }) => React.ReactNode, useQRPHDepositContext: () => {
16
- view: "form" | "qrCode";
16
+ view: "qrCode" | "form";
17
17
  status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
18
18
  verify: () => void;
19
19
  reset: () => void;
@@ -1,7 +1,7 @@
1
1
  import type { Deposit } from '../../../../types';
2
2
  export type UseQRPHDepositReturn = ReturnType<typeof useQRPHDeposit>;
3
3
  export declare function useQRPHDeposit(): {
4
- view: "form" | "qrCode";
4
+ view: "qrCode" | "form";
5
5
  status: "waiting" | "processing" | "failed" | "verification-waiting" | "verification-processing" | "verification-failed" | "verification-success";
6
6
  verify: () => void;
7
7
  reset: () => void;
@@ -10,9 +10,8 @@ import { Button } from '../../ui/Button/index.js';
10
10
  import { Dialog } from '../../ui/Dialog/index.js';
11
11
  import { onMobileDevice } from '../../utils/onMobileDevice.js';
12
12
  import { useKYCContext } from './KYCContext.js';
13
- import { loadFaceApiModels } from './loadModels.js';
14
13
  import PersonOverlayDesktop from './PersonOverlayDesktop.js';
15
- import { dataURLtoBlob, resizeFile } from './utils.js';
14
+ import { dataURLtoBlob, loadFaceApiModels, resizeFile } from './utils.js';
16
15
  export function CaptureSelfie() {
17
16
  const kyc = useKYCContext();
18
17
  const { mutate, isPending } = useUploadImageFileMutation();
@@ -11,5 +11,5 @@ const Component = dynamic(() => import('./KYC.lazy.js').then((m) => m.KYC), {
11
11
  });
12
12
  export function KYC(props) {
13
13
  const touched = useGlobalStore(useShallow((ctx) => ctx.kyc['~touched']));
14
- return (_jsxs(_Fragment, { children: [touched && _jsx(Component, { ...props }), _jsx(AutoOpen, {}), _jsx(Script, { src: "https://docs.opencv.org/4.7.0/opencv.js", async: true }), _jsx(Script, { src: "https://cdn.jsdelivr.net/gh/ColonelParrot/jscanify@master/src/jscanify.min.js", strategy: "afterInteractive" })] }));
14
+ return (_jsxs(_Fragment, { children: [touched && _jsx(Component, { ...props }), _jsx(AutoOpen, {}), _jsx(Script, { src: "https://docs.opencv.org/4.7.0/opencv.js", defer: true }), _jsx(Script, { src: "https://cdn.jsdelivr.net/gh/ColonelParrot/jscanify@master/src/jscanify.min.js", defer: true })] }));
15
15
  }
@@ -1,3 +1,4 @@
1
+ export declare function loadFaceApiModels(): Promise<void>;
1
2
  export declare function dataURLtoBlob(dataURL: string): Blob;
2
3
  export declare const resizeFile: (file: File) => Promise<unknown>;
3
4
  export declare const MAX_FILE_SIZE = 10;
@@ -1,4 +1,13 @@
1
+ import * as faceapi from 'face-api.js';
1
2
  import Resizer from 'react-image-file-resizer';
3
+ export async function loadFaceApiModels() {
4
+ const MODEL_URL = '/models';
5
+ await Promise.all([
6
+ faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL),
7
+ faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
8
+ faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
9
+ ]);
10
+ }
2
11
  export function dataURLtoBlob(dataURL) {
3
12
  const parts = dataURL.split(';base64,');
4
13
  const contentType = parts[0].split(':')[1];
@@ -27,7 +27,7 @@ const TABS = ['ALL', 'UNREAD'];
27
27
  export function Messages(props) {
28
28
  const globalStore = useGlobalStore(useShallow((ctx) => ({ messages: ctx.messages })));
29
29
  const unreadMessagesCountQuery = useUnreadMessagesCountQuery({}, {
30
- refetchInterval: globalStore.messages.open ? 5_000 : 10_000,
30
+ refetchInterval: globalStore.messages.open ? 5000 : 10000,
31
31
  });
32
32
  const unreadMessagesCount = unreadMessagesCountQuery.data ?? 0;
33
33
  const messagesQuery = useMessagesQuery({
@@ -41,7 +41,7 @@ export function Messages(props) {
41
41
  }),
42
42
  }, {
43
43
  enabled: globalStore.messages.open,
44
- refetchInterval: 5_000,
44
+ refetchInterval: 10000,
45
45
  });
46
46
  const messages = messagesQuery.data?.pages.flatMap((page) => page.edges.map((e) => e.node)) ?? [];
47
47
  const [mobileOffsetTop, desktopOffsetTop] = Array.isArray(props.offsetTop)
@@ -29,22 +29,24 @@ export function MessagesPopup() {
29
29
  depositWithdrawal: ctx.depositWithdrawal,
30
30
  })));
31
31
  const markMessageAsReadMutation = useMarkMessageAsReadMutation();
32
- const [paused, setPaused] = useState(false);
33
- useInterval(() => setPaused(false), paused ? 1000 * 30 : null);
34
32
  const disclosure = useDisclosure({
35
33
  onOpenChange(open) {
36
34
  if (open) {
37
35
  const message = messages.at(0);
38
- if (!message || message.markedAsRead)
36
+ if (!message)
37
+ return;
38
+ if (message.markedAsRead)
39
39
  return;
40
40
  markMessageAsReadMutation.mutate(message.id);
41
41
  }
42
42
  else {
43
43
  setPaused(true);
44
- setPage(1);
44
+ setIndex_(0);
45
45
  }
46
46
  },
47
47
  });
48
+ const [paused, setPaused] = useState(false);
49
+ useInterval(() => setPaused(false), paused ? 1000 * 30 : null);
48
50
  const messagesQuery = useMessagesQuery({
49
51
  first: 10,
50
52
  filter: {
@@ -62,10 +64,19 @@ export function MessagesPopup() {
62
64
  !globalStore.message.open &&
63
65
  !globalStore.kyc.open &&
64
66
  !paused,
65
- refetchInterval: disclosure.open ? undefined : 10_000,
67
+ refetchInterval: disclosure.open ? undefined : 10000,
66
68
  });
67
69
  const messages = messagesQuery.data?.pages.flatMap((page) => page.edges.map((edge) => edge.node)) ?? [];
68
- const [page, setPage] = useState(1);
70
+ const [index, setIndex_] = useState(0);
71
+ const setIndex = (newIndex) => {
72
+ setIndex_(newIndex);
73
+ const message = messages.at(newIndex);
74
+ if (!message)
75
+ return;
76
+ if (message.markedAsRead)
77
+ return;
78
+ markMessageAsReadMutation.mutate(message.id);
79
+ };
69
80
  useEffect(() => {
70
81
  if (messages.length > 0) {
71
82
  disclosure.setOpen(true);
@@ -73,14 +84,8 @@ export function MessagesPopup() {
73
84
  }, [disclosure, messages.length, paused]);
74
85
  return (_jsx(Dialog.Root, { open: disclosure.open, onOpenChange: (details) => {
75
86
  disclosure.setOpen(details.open);
76
- }, lazyMount: true, unmountOnExit: true, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+3)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+4)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "min-h-auto mx-auto min-w-[21.438rem] max-w-[21.438rem] rounded-xl p-3xl lg:min-w-[25rem] lg:max-w-[25rem]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs(Carousel.Root, { page: page, onPageChange: (details) => {
77
- setPage(details.page);
78
- const message = messages.at(details.page - 1);
79
- if (!message)
80
- return;
81
- if (message.markedAsRead)
82
- return;
83
- markMessageAsReadMutation.mutate(message.id);
87
+ }, lazyMount: true, unmountOnExit: true, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+3)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+4)] flex items-center justify-center", children: _jsxs(Dialog.Content, { className: "min-h-auto mx-auto min-w-[21.438rem] max-w-[21.438rem] rounded-xl p-3xl lg:min-w-[25rem] lg:max-w-[25rem]", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsxs(Carousel.Root, { page: index, onPageChange: (details) => {
88
+ setIndex(details.page);
84
89
  }, slideCount: messages.length, allowMouseDrag: true, children: [_jsx(Carousel.ItemGroup, { children: messages.map((message, index) => (_jsxs(Carousel.Item, { index: index, className: "select-none", children: [_jsx("div", { className: "bg-bg-brand-secondary text-text-brand mx-auto flex size-12 items-center justify-center rounded-full", children: _jsx(MessageIcon, { type: message.icon, className: "size-6" }) }), _jsx("h2", { className: "mt-lg text-center text-lg font-semibold xl:mt-xl", children: message.title }), message.content && (_jsx("div", { dangerouslySetInnerHTML: { __html: message.content }, className: "text-text-secondary-700 mt-xs pb-5 text-center text-sm" })), message.image && (_jsx("div", { className: "mt-5 pb-5", children: _jsx(Image, { src: message.image, alt: "", width: 400, height: 250, loading: "lazy", unoptimized: true, className: "h-auto w-full rounded-sm" }) })), message.actions.length ? (_jsx("div", { className: "mt-3xl flex flex-col gap-2 text-center lg:mt-4xl", children: message.actions.map((action, index) => (_jsx(Button, { asChild: true, children: _jsx(Link, { href: normalizeActionUrl(transactionsPageUrl, action.url), onClick: () => {
85
90
  disclosure.setOpen(false);
86
91
  }, children: action.name }) }, index))) })) : null] }, message.id))) }), _jsxs(Carousel.Control, { className: "mt-5 flex items-center lg:mt-3xl", children: [_jsxs(Carousel.PrevTrigger, { className: "text-text-quarterary-500 hidden items-center gap-md font-semibold disabled:invisible lg:flex", children: [_jsx(ChevronLeftIcon, { className: "size-5" }), "Back"] }), _jsx(Carousel.IndicatorGroup, { className: "flex grow justify-center gap-xs", children: messages.map((message, index) => (_jsx(Carousel.Indicator, { index: index, className: "bg-bg-quaternary ui-current:bg-brand-400 size-2.5 rounded-full transition-all duration-150 ui-current:w-5" }, message.id))) }), _jsxs(Carousel.NextTrigger, { className: "text-text-quarterary-500 hidden items-center gap-md font-semibold disabled:invisible lg:flex", children: ["Next", _jsx(ChevronRightIcon, { className: "size-5" })] })] })] })] }) })] }) }));
@@ -4,7 +4,7 @@ import Link from 'next/link';
4
4
  import { ChevronLeftIcon } from '../../icons/ChevronLeftIcon.js';
5
5
  import { Prose } from '../../ui/Prose/index.js';
6
6
  export function News(props) {
7
- return (_jsxs("div", { style: props.style, className: props.className, children: [_jsxs(Link, { href: props.viewAllUrl ?? '/news', className: "text-button-secondary-fg flex items-center gap-lg text-lg font-semibold", children: [_jsx(ChevronLeftIcon, { className: "size-6" }), "Back to all News"] }), _jsx(Image, { src: props.news.image, alt: "", width: 1024, height: 600, priority: true, className: "mt-3xl block h-auto w-full rounded-xl lg:mt-6" }), _jsx("p", { className: "text-brand-400 mt-xl text-sm font-semibold lg:mt-6", children: props.news.category }), _jsx("h2", { className: "mt-xl text-2xl font-semibold lg:mt-6", children: props.news.title }), _jsx(Prose, { className: "mt-xl lg:mt-6", dangerouslySetInnerHTML: {
7
+ return (_jsxs("div", { style: props.style, className: props.className, children: [_jsxs(Link, { href: props.viewAllUrl ?? '/news', className: "text-button-secondary-fg flex items-center gap-lg text-lg font-semibold", children: [_jsx(ChevronLeftIcon, { className: "size-6" }), "Back to all News"] }), _jsx(Image, { src: props.news.image, alt: "", width: 1024, height: 600, priority: true, unoptimized: true, className: "mt-3xl block h-auto w-full rounded-xl lg:mt-6" }), _jsx("p", { className: "text-brand-400 mt-xl text-sm font-semibold lg:mt-6", children: props.news.category }), _jsx("h2", { className: "mt-xl text-2xl font-semibold lg:mt-6", children: props.news.title }), _jsx(Prose, { className: "mt-xl lg:mt-6", dangerouslySetInnerHTML: {
8
8
  __html: props.news.content,
9
9
  } })] }));
10
10
  }
@@ -0,0 +1,6 @@
1
+ import type { News } from '../../types';
2
+ export interface NewsProps {
3
+ news: News;
4
+ viewDetailsUrl: string;
5
+ }
6
+ export declare function News({ news, viewDetailsUrl }: NewsProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Image from 'next/image';
3
+ import Link from 'next/link';
4
+ import { Button } from '../../ui/Button/index.js';
5
+ export function News({ news, viewDetailsUrl }) {
6
+ return (_jsxs("div", { className: "bg-bg-primary-alt border-border-primary flex flex-col overflow-hidden rounded-2xl border shadow-md", children: [_jsx(Image, { src: news.image, alt: "", width: 400, height: 274, loading: "lazy", unoptimized: true, className: "block h-[15.25rem] w-full object-cover" }), _jsxs("div", { className: "flex grow flex-col p-3xl", children: [_jsxs("div", { className: "grow", children: [_jsx("p", { className: "text-brand-400 text-sm font-semibold", children: news.category }), _jsx("h2", { className: "mt-2 line-clamp-1 text-lg font-semibold", children: news.title }), _jsx("p", { className: "text-text-tertiary-600 mt-xs line-clamp-3", dangerouslySetInnerHTML: {
7
+ __html: news.content,
8
+ } })] }), _jsx(Button, { asChild: true, className: "mt-2xl", children: _jsx(Link, { href: `${viewDetailsUrl}/${news.id}`, "aria-label": `Read more about ${news.title}`, children: "Read More" }) })] })] }, news.id));
9
+ }
@@ -1,8 +1,8 @@
1
1
  import { type CSSProperties } from 'react';
2
- import type { News } from '../../types';
2
+ import type { News as TNews } from '../../types';
3
3
  export interface NewsFeedCarouselProps {
4
4
  layout: 'carousel';
5
- newsFeed: News[];
5
+ newsFeed: TNews[];
6
6
  /** @default 'News' */
7
7
  heading?: string;
8
8
  /** @default '/news' */
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import useEmblaCarousel, {} from 'embla-carousel-react';
4
- import Image from 'next/image';
5
4
  import Link from 'next/link';
6
5
  import { useCallback, useEffect, useState } from 'react';
7
6
  import { twMerge } from 'tailwind-merge';
@@ -11,6 +10,7 @@ import { ChevronRightIcon } from '../../icons/ChevronRightIcon.js';
11
10
  import { Tv03Icon } from '../../icons/Tv03Icon.js';
12
11
  import { Button } from '../../ui/Button/index.js';
13
12
  import { Empty } from '../shared/Empty.js';
13
+ import { News } from './News.js';
14
14
  export function NewsFeedCarousel(props) {
15
15
  const empty = props.newsFeed.length <= 0;
16
16
  const heading = props.heading ?? 'News';
@@ -41,7 +41,5 @@ export function NewsFeedCarousel(props) {
41
41
  onSelect(emblaApi);
42
42
  emblaApi.on('reInit', onSelect).on('select', onSelect);
43
43
  }, [emblaApi, onSelect]);
44
- return (_jsxs("div", { style: props.style, className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: heading }), _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" }) })] })] })] }), empty && (_jsx(Empty, { icon: Tv03Icon, title: "No News", message: "No news is currently available.", className: "mt-8" })), !empty && (_jsx(_Fragment, { children: _jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsx("div", { className: twMerge('grid auto-cols-[100%] grid-flow-col gap-1.5 lg:auto-cols-[calc((100%-(1.25rem*2))/3)] lg:gap-2xl'), children: props.newsFeed.map((news) => (_jsxs("div", { className: "bg-bg-primary-alt border-border-primary flex flex-col overflow-hidden rounded-2xl border shadow-md", children: [_jsx(Image, { src: news.image, alt: "", width: 400, height: 274, loading: "lazy", unoptimized: true, className: "block h-[15.25rem] w-full object-cover" }), _jsxs("div", { className: "flex grow flex-col p-3xl", children: [_jsxs("div", { className: "grow", children: [_jsx("p", { className: "text-brand-400 text-sm font-semibold", children: news.category }), _jsx("h2", { className: "mt-2 line-clamp-1 text-lg font-semibold", children: news.title }), _jsx("p", { className: "text-text-tertiary-600 mt-xs line-clamp-3", dangerouslySetInnerHTML: {
45
- __html: news.content,
46
- } })] }), _jsx(Button, { asChild: true, className: "mt-2xl", children: _jsx(Link, { href: `${viewDetailsUrl}/${news.id}`, children: "Read More" }) })] })] }, news.id))) }) }) }))] }));
44
+ return (_jsxs("div", { style: props.style, className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: heading }), _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" }) })] })] })] }), empty && (_jsx(Empty, { icon: Tv03Icon, title: "No News", message: "No news is currently available.", className: "mt-8" })), !empty && (_jsx(_Fragment, { children: _jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsx("div", { className: twMerge('grid auto-cols-[100%] grid-flow-col gap-1.5 lg:auto-cols-[calc((100%-(1.25rem*2))/3)] lg:gap-2xl'), children: props.newsFeed.map((news) => (_jsx(News, { news: news, viewDetailsUrl: viewDetailsUrl }, news.id))) }) }) }))] }));
47
45
  }
@@ -1,8 +1,8 @@
1
1
  import type { CSSProperties } from 'react';
2
- import type { News } from '../../types';
2
+ import type { News as TNews } from '../../types';
3
3
  export interface NewsFeedListProps {
4
4
  layout: 'list';
5
- newsFeed: News[];
5
+ newsFeed: TNews[];
6
6
  /** @default 'News' */
7
7
  heading?: string;
8
8
  /**
@@ -1,14 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import Image from 'next/image';
3
- import Link from 'next/link';
4
2
  import { Tv03Icon } from '../../icons/Tv03Icon.js';
5
- import { Button } from '../../ui/Button/index.js';
6
3
  import { Empty } from '../shared/Empty.js';
4
+ import { News } from './News.js';
7
5
  export function NewsFeedList(props) {
8
6
  const empty = props.newsFeed.length <= 0;
9
7
  const heading = props.heading ?? 'News';
10
8
  const viewDetailsUrl = props.viewDetailsUrl ?? '/news';
11
- return (_jsxs("div", { style: props.style, className: props.className, children: [_jsx("h2", { className: "text-lg font-semibold", children: heading }), empty && (_jsx(Empty, { icon: Tv03Icon, title: "No News", message: "No news is currently available.", className: "mt-8" })), !empty && (_jsx("div", { className: "mt-lg grid gap-3xl lg:grid-cols-3 lg:gap-2xl", children: props.newsFeed.map((news) => (_jsxs("div", { className: "bg-bg-primary-alt border-border-primary flex flex-col overflow-hidden rounded-2xl border shadow-md", children: [_jsx(Image, { src: news.image, alt: "", width: 400, height: 274, className: "block h-[15.25rem] w-full object-cover" }), _jsxs("div", { className: "flex grow flex-col p-3xl", children: [_jsxs("div", { className: "grow", children: [_jsx("p", { className: "text-brand-400 text-sm font-semibold", children: news.category }), _jsx("h2", { className: "mt-2 line-clamp-1 text-lg font-semibold", children: news.title }), _jsx("p", { className: "text-text-tertiary-600 mt-xs line-clamp-3", dangerouslySetInnerHTML: {
12
- __html: news.content,
13
- } })] }), _jsx(Button, { asChild: true, className: "mt-2xl", children: _jsx(Link, { href: `${viewDetailsUrl}/${news.id}`, children: "Read More" }) })] })] }, news.id))) }))] }));
9
+ return (_jsxs("div", { style: props.style, className: props.className, children: [_jsx("h2", { className: "text-lg font-semibold", children: heading }), empty && (_jsx(Empty, { icon: Tv03Icon, title: "No News", message: "No news is currently available.", className: "mt-8" })), !empty && (_jsx("div", { className: "mt-lg grid gap-3xl lg:grid-cols-3 lg:gap-2xl", children: props.newsFeed.map((news) => (_jsx(News, { news: news, viewDetailsUrl: viewDetailsUrl }, news.id))) }))] }));
14
10
  }
@@ -9,6 +9,7 @@ import { FacebookPixel, GoogleRecaptcha } from '../../third-parties/index.js';
9
9
  import { getQueryClient } from '../../utils/getQueryClient.js';
10
10
  import { Providers } from './Providers.js';
11
11
  import { Snackbar } from './Snackbar.js';
12
+ import { WebVitals } from './WebVitals.js';
12
13
  export async function PortalProvider({ children, facebookPixelId, googleAnalyticsId, googleTagManagerId, googleRecaptchaSiteKey, }) {
13
14
  const queryClient = getQueryClient();
14
15
  await Promise.allSettled([
@@ -17,5 +18,5 @@ export async function PortalProvider({ children, facebookPixelId, googleAnalytic
17
18
  prefetchAccountQuery(),
18
19
  prefetchWalletQuery(),
19
20
  ]);
20
- return (_jsxs(_Fragment, { children: [_jsx(Providers, { children: _jsx(HydrationBoundary, { state: dehydrate(queryClient), children: children }) }), _jsx(Snackbar, {}), facebookPixelId && _jsx(FacebookPixel, { fbId: facebookPixelId }), googleAnalyticsId && _jsx(GoogleAnalytics, { gaId: googleAnalyticsId }), googleTagManagerId && _jsx(GoogleTagManager, { gtmId: googleTagManagerId }), googleRecaptchaSiteKey && (_jsx(GoogleRecaptcha, { siteKey: googleRecaptchaSiteKey }))] }));
21
+ return (_jsxs(_Fragment, { children: [_jsx(WebVitals, {}), _jsx(Providers, { children: _jsx(HydrationBoundary, { state: dehydrate(queryClient), children: children }) }), _jsx(Snackbar, {}), facebookPixelId && _jsx(FacebookPixel, { fbId: facebookPixelId }), googleAnalyticsId && _jsx(GoogleAnalytics, { gaId: googleAnalyticsId }), googleTagManagerId && _jsx(GoogleTagManager, { gtmId: googleTagManagerId }), googleRecaptchaSiteKey && (_jsx(GoogleRecaptcha, { siteKey: googleRecaptchaSiteKey }))] }));
21
22
  }
@@ -0,0 +1 @@
1
+ export declare function WebVitals(): null;
@@ -0,0 +1,8 @@
1
+ 'use client';
2
+ import { useReportWebVitals } from 'next/web-vitals';
3
+ export function WebVitals() {
4
+ useReportWebVitals((metric) => {
5
+ console.log(metric);
6
+ });
7
+ return null;
8
+ }
@@ -14,5 +14,5 @@ export function Cashback({ data, viewDetailsUrl }) {
14
14
  return (_jsxs("div", { className: "border-border-secondary bg-accent-50 bg-bg-primary-alt relative flex h-full flex-col overflow-hidden rounded-2xl border", children: [data.banner.url && (_jsx(Image, { src: data.banner.url, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" })), _jsxs("div", { className: "flex flex-grow flex-col px-4 pb-3xl pt-2xl", children: [_jsx("div", { className: "w-full grow text-center text-xl font-semibold", children: data.name }), _jsxs("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: [claimable && (_jsx(Button, { size: "sm", onClick: () => {
15
15
  globalStore.depositWithdrawal.setOpen(true);
16
16
  globalStore.depositWithdrawal.setPromo(data.id);
17
- }, children: "Get bonus" })), _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, children: "Read more" }) })] })] })] }));
17
+ }, children: "Get bonus" })), _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, "aria-label": `Read more about ${data.name}`, children: "Read more" }) })] })] })] }));
18
18
  }
@@ -3,5 +3,5 @@ import Image from 'next/image';
3
3
  import Link from 'next/link';
4
4
  import { Button } from '../../ui/Button/index.js';
5
5
  export function CustomPromo({ data, viewDetailsUrl }) {
6
- return (_jsxs("div", { className: "border-border-secondary bg-accent-50 bg-bg-primary-alt relative flex h-full flex-col overflow-hidden rounded-2xl border", children: [_jsx(Image, { src: data.banner, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" }), _jsxs("div", { className: "flex flex-grow flex-col px-4 pb-3xl pt-2xl", children: [_jsx("div", { className: "w-full grow text-center text-xl font-semibold", children: data.name }), _jsx("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, children: "Read more" }) }) })] })] }));
6
+ return (_jsxs("div", { className: "border-border-secondary bg-accent-50 bg-bg-primary-alt relative flex h-full flex-col overflow-hidden rounded-2xl border", children: [_jsx(Image, { src: data.banner, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" }), _jsxs("div", { className: "flex flex-grow flex-col px-4 pb-3xl pt-2xl", children: [_jsx("div", { className: "w-full grow text-center text-xl font-semibold", children: data.name }), _jsx("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, "aria-label": `Read more about ${data.name}`, children: "Read more" }) }) })] })] }));
7
7
  }
@@ -14,5 +14,5 @@ export function Promo({ data, viewDetailsUrl }) {
14
14
  return (_jsxs("div", { className: "border-border-secondary bg-accent-50 bg-bg-primary-alt relative flex h-full flex-col overflow-hidden rounded-2xl border", children: [data.banner.url && (_jsx(Image, { src: data.banner.url, alt: data.name, width: 400, height: 202, loading: "lazy", unoptimized: true, className: "block aspect-[365/180] w-full object-cover" })), _jsxs("div", { className: "flex flex-grow flex-col px-4 pb-3xl pt-2xl", children: [_jsx("div", { className: "w-full grow text-center text-xl font-semibold", children: data.name }), _jsxs("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: [claimable && (_jsx(Button, { size: "sm", onClick: () => {
15
15
  globalStore.depositWithdrawal.setOpen(true);
16
16
  globalStore.depositWithdrawal.setPromo(data.id);
17
- }, children: "Get bonus" })), _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, children: "Read more" }) })] })] })] }));
17
+ }, children: "Get bonus" })), _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, "aria-label": `Read more about ${data.name}`, children: "Read more" }) })] })] })] }));
18
18
  }
@@ -70,10 +70,10 @@ export function Search(props) {
70
70
  }, lazyMount: true, unmountOnExit: true, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { children: _jsxs(Dialog.Content, { className: "bg-bg-primary lg:min-h-auto mx-auto min-h-full w-full pt-xl lg:mt-[132px] lg:max-w-[1136px] lg:bg-unset lg:pt-0", children: [_jsx(Dialog.Context, { children: (api) => (_jsxs("div", { className: "flex items-center justify-between px-4 lg:hidden", children: [_jsx(Image, { src: props.logo, alt: "", width: 200, height: 40, className: "h-8 w-auto" }), _jsx(IconButton, { size: "sm", colorScheme: "gray", onClick: () => api.setOpen(false), children: _jsx(XIcon, { className: "text-text-quinary size-6" }) })] })) }), _jsx("div", { className: "flex justify-end", children: _jsx(Dialog.Context, { children: (api) => (_jsx("button", { type: "button", onClick: () => api.setOpen(false), className: "hidden size-9 items-center justify-center rounded-md bg-white/20 lg:flex", children: _jsx(XIcon, { className: "size-5 text-white" }) })) }) }), _jsx("div", { className: "mt-2xl px-4 lg:mt-xl lg:px-0", children: _jsxs("div", { className: "relative", children: [_jsx(SearchLgIcon, { className: "text-text-quinary pointer-events-none absolute left-3.5 top-1/2 size-5 -translate-y-1/2" }), _jsx(DebouncedInput, { ref: inputRef, value: search, onChange: setSearch }), _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: () => {
71
71
  setSearch('');
72
72
  inputRef.current?.focus();
73
- }, children: "Clear" }) })] }) }), _jsx("div", { className: "lg:bg-bg-primary lg:border-border-primary mt-2xl p-xl pb-3xl lg:mt-2 lg:max-h-[41rem] lg:overflow-y-auto 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: twMerge('bg-gray-800 flex h-14 w-full items-center rounded-md', classNames.providerThumbnailRoot), onClick: () => {
73
+ }, children: "Clear" }) })] }) }), _jsx("div", { className: "lg:bg-bg-primary lg:border-border-primary mt-2xl p-xl pb-3xl lg:mt-2 lg:max-h-[41rem] lg:overflow-y-auto 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: "mb-3xl 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: twMerge('bg-gray-800 flex h-14 w-full items-center rounded-md', classNames.providerThumbnailRoot), onClick: () => {
74
74
  globalStore.search.setOpen(false);
75
75
  }, children: _jsx(Image, { src: props.gameProviderImages?.[provider.id] ??
76
- provider.logo, alt: "", width: 100, height: 50, className: twMerge('mx-auto h-auto w-full', classNames.providerThumbnailImage) }) }, 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: twMerge('block w-full shadow-sm', classNames.gameThumbnailRoot), onClick: () => {
76
+ provider.logo, alt: "", width: 100, height: 50, className: twMerge('mx-auto h-auto w-full', classNames.providerThumbnailImage) }) }, provider.id))) })] })), games.length > 0 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "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: twMerge('block w-full shadow-sm', classNames.gameThumbnailRoot), onClick: () => {
77
77
  globalStore.search.setOpen(false);
78
78
  }, children: [_jsx(Image, { src: getGameImageUrl({
79
79
  reference: game.reference,
@@ -3,3 +3,4 @@ export declare const PLATFORM_ID: string;
3
3
  export declare const PLATFORM_CODE: string;
4
4
  export declare const ENVIRONMENT: "production" | "development";
5
5
  export declare const BYPASS_RECAPTCHA: boolean;
6
+ export declare const DOMAIN: string;
@@ -26,3 +26,8 @@ export const BYPASS_RECAPTCHA = z
26
26
  .transform(Boolean)
27
27
  .catch(false)
28
28
  .parse(process.env.NEXT_PUBLIC_BYPASS_RECAPTCHA);
29
+ export const DOMAIN = z
30
+ .string()
31
+ .url('Environment variable "NEXT_PUBLIC_DOMAIN" must be a valid URL')
32
+ .catch('http://localhost')
33
+ .parse(process.env.NEXT_PUBLIC_DOMAIN);
package/dist/handlers.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { addDays, addMinutes, subMinutes } from 'date-fns';
2
2
  import { NextResponse } from 'next/server';
3
3
  import { z } from 'zod';
4
- import { ACCESS_TOKEN_COOKIE_NAME, BYPASS_RECAPTCHA, PLATFORM_CODE, RECAPTCHA_HEADER_KEY, REFRESH_TOKEN_COOKIE_NAME, } from './constants/index.js';
4
+ import { ACCESS_TOKEN_COOKIE_NAME, PLATFORM_CODE, RECAPTCHA_HEADER_KEY, REFRESH_TOKEN_COOKIE_NAME, } from './constants/index.js';
5
5
  import { authenticate, createSession, destroySession, refreshSession, } from './services/auth.js';
6
6
  const CreateSessionDefinition = z.union([
7
7
  z.object({
@@ -172,9 +172,6 @@ export const POST = async (request, { params }) => {
172
172
  ...(recaptcha && {
173
173
  [RECAPTCHA_HEADER_KEY]: recaptcha,
174
174
  }),
175
- ...(BYPASS_RECAPTCHA && {
176
- 'Test-Pass': '',
177
- }),
178
175
  },
179
176
  });
180
177
  if (res.authenticator) {
@@ -1 +1,2 @@
1
- export declare const prefetchBonusesQuery: () => Promise<void>;
1
+ import { type BonusesInput } from '../../services/wallet';
2
+ export declare const prefetchBonusesQuery: (input?: BonusesInput) => Promise<void>;
@@ -3,15 +3,15 @@ import { getQueryClient } from '../../utils/getQueryClient.js';
3
3
  import { log } from '../../utils/log.js';
4
4
  import { getBonusesQueryKey } from '../../utils/queryKeys.js';
5
5
  import { getSession } from '../services/getSession.js';
6
- export const prefetchBonusesQuery = async () => {
6
+ export const prefetchBonusesQuery = async (input) => {
7
7
  const session = await getSession();
8
8
  if (session.status === 'unauthenticated')
9
9
  return;
10
10
  await getQueryClient()
11
11
  .prefetchQuery({
12
- queryKey: getBonusesQueryKey(),
12
+ queryKey: getBonusesQueryKey(input),
13
13
  queryFn: async ({ signal }) => {
14
- return await getBonuses({
14
+ return await getBonuses(input, {
15
15
  signal,
16
16
  headers: {
17
17
  Authorization: `Bearer ${session.token}`,