@opexa/portal-components 0.0.680 → 0.0.682

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 (67) hide show
  1. package/dist/client/hooks/useCamera.d.ts +2 -1
  2. package/dist/client/hooks/useCamera.js +128 -21
  3. package/dist/client/hooks/useSignOutMutation.js +15 -0
  4. package/dist/client/utils/biometric.js +1 -1
  5. package/dist/components/AccountInfo/GoogleDisconnect.d.ts +7 -0
  6. package/dist/components/AccountInfo/GoogleDisconnect.js +11 -0
  7. package/dist/components/DepositWithdrawal/AiOPaymentMethods.js +4 -4
  8. package/dist/components/DepositWithdrawal/PaymentMethods.js +4 -3
  9. package/dist/components/GameLaunch/GameLaunchTrigger.js +64 -11
  10. package/dist/components/KYC/KYCDefault/PersonalInformation.js +11 -1
  11. package/dist/components/KYC/KYCReminder.lazy.js +8 -10
  12. package/dist/components/KYC/KYCVerificationStatus.lazy.js +4 -7
  13. package/dist/components/KYC/KycOpenOnHomeMount.js +1 -0
  14. package/dist/components/PortalProvider/CXDTokenObserver.js +11 -11
  15. package/dist/components/RegisterBiometrics/RegisterBiometrics.js +3 -1
  16. package/dist/components/SignIn/MobileNumberSignIn.js +13 -1
  17. package/dist/components/SignIn/NameAndPasswordSignIn.js +23 -3
  18. package/dist/components/SignIn/SignInTrigger.d.ts +1 -1
  19. package/dist/components/SignIn/SignInTrigger.js +62 -7
  20. package/dist/components/TopWins/TopWins.client.js +1 -1
  21. package/dist/components/shared/IdFrontImageField/IdFrontImageField.client.js +12 -2
  22. package/dist/components/shared/SelfieImageField/SelfieImageField.client.js +11 -2
  23. package/dist/icons/LinkBrokenIcon.d.ts +2 -0
  24. package/dist/icons/LinkBrokenIcon.js +4 -0
  25. package/dist/ui/AlertDialog/AlertDialog.d.ts +88 -88
  26. package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +8 -8
  27. package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
  28. package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
  29. package/dist/ui/Combobox/Combobox.d.ts +42 -42
  30. package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
  31. package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
  32. package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
  33. package/dist/ui/Dialog/Dialog.d.ts +33 -33
  34. package/dist/ui/Dialog/dialog.recipe.d.ts +3 -3
  35. package/dist/ui/Drawer/Drawer.d.ts +33 -33
  36. package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
  37. package/dist/ui/Menu/Menu.d.ts +252 -252
  38. package/dist/ui/Menu/menu.recipe.d.ts +14 -14
  39. package/dist/ui/Popover/Popover.d.ts +88 -88
  40. package/dist/ui/Popover/popover.recipe.d.ts +8 -8
  41. package/dist/ui/Select/Select.d.ts +45 -45
  42. package/dist/ui/Select/select.recipe.d.ts +3 -3
  43. package/dist/ui/Tooltip/Tooltip.d.ts +30 -30
  44. package/dist/ui/Tooltip/tooltip.recipe.d.ts +5 -5
  45. package/package.json +2 -1
  46. package/dist/components/Banner/Banner.client.d.ts +0 -12
  47. package/dist/components/Banner/Banner.client.js +0 -49
  48. package/dist/components/PortalProvider/AndroidOnlyComponents.d.ts +0 -1
  49. package/dist/components/PortalProvider/AndroidOnlyComponents.js +0 -12
  50. package/dist/components/SignIn/utils.d.ts +0 -8
  51. package/dist/components/SignIn/utils.js +0 -26
  52. package/dist/constants/Branches.d.ts +0 -2
  53. package/dist/constants/Branches.js +0 -42
  54. package/dist/third-parties/FacebookPixel/FacebookPixel.d.ts +0 -4
  55. package/dist/third-parties/FacebookPixel/FacebookPixel.js +0 -4
  56. package/dist/third-parties/FacebookPixel/api.d.ts +0 -0
  57. package/dist/third-parties/FacebookPixel/api.js +0 -1
  58. package/dist/third-parties/FacebookPixel/index.d.ts +0 -1
  59. package/dist/third-parties/FacebookPixel/index.js +0 -1
  60. package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.d.ts +0 -4
  61. package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.js +0 -4
  62. package/dist/third-parties/GoogleRecaptcha/api.d.ts +0 -0
  63. package/dist/third-parties/GoogleRecaptcha/api.js +0 -1
  64. package/dist/third-parties/GoogleRecaptcha/index.d.ts +0 -1
  65. package/dist/third-parties/GoogleRecaptcha/index.js +0 -1
  66. package/dist/third-parties/index.d.ts +0 -2
  67. package/dist/third-parties/index.js +0 -2
@@ -6,11 +6,13 @@ import Image from 'next/image';
6
6
  import { useRouter } from 'next/navigation';
7
7
  import { Controller, useForm } from 'react-hook-form';
8
8
  import { twMerge } from 'tailwind-merge';
9
+ import invariant from 'tiny-invariant';
9
10
  import { z } from 'zod';
10
11
  import { useShallow } from 'zustand/shallow';
11
12
  import { useAuthenticateMutation } from '../../client/hooks/useAuthenticateMutation.js';
12
13
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
13
14
  import { useSignInMutation } from '../../client/hooks/useSignInMutation.js';
15
+ import { getSession } from '../../client/services/getSession.js';
14
16
  import { hasSavedBiometry } from '../../client/utils/biometric.js';
15
17
  import { toaster } from '../../client/utils/toaster.js';
16
18
  import { SECRET_QUESTIONS, SECRET_QUESTIONS_MAP } from '../../constants/index.js';
@@ -19,6 +21,7 @@ import { EyeIcon } from '../../icons/EyeIcon.js';
19
21
  import { EyeOffIcon } from '../../icons/EyeOffIcon.js';
20
22
  import pagcorLogo from '../../images/pagcor-round-icon.png';
21
23
  import responsibleGamingLogo from '../../images/responsible-gaming-gold.png';
24
+ import { unregisterFCMDevice } from '../../services/trigger.js';
22
25
  import { Button } from '../../ui/Button/index.js';
23
26
  import { Checkbox } from '../../ui/Checkbox/index.js';
24
27
  import { Field } from '../../ui/Field/index.js';
@@ -45,12 +48,20 @@ export function NameAndPasswordSignIn() {
45
48
  registerBiometrics: ctx.registerBiometrics,
46
49
  })));
47
50
  const signInMutation = useSignInMutation({
48
- onSuccess(authenticator) {
51
+ onSuccess: async (authenticator) => {
49
52
  if (authenticator) {
50
53
  context.setStep(2);
51
54
  }
52
55
  else {
53
- console.log('hasSavedBiometry', hasSavedBiometry());
56
+ const session = await getSession();
57
+ invariant(session.status === 'authenticated');
58
+ await unregisterFCMDevice({
59
+ type: ['IOS', 'ANDROID'],
60
+ }, {
61
+ headers: {
62
+ Authorization: `Bearer ${session.token}`,
63
+ },
64
+ });
54
65
  if (!hasSavedBiometry()) {
55
66
  globalStore.registerBiometrics.setOpen(true);
56
67
  }
@@ -72,12 +83,21 @@ export function NameAndPasswordSignIn() {
72
83
  },
73
84
  });
74
85
  const authenticateMutation = useAuthenticateMutation({
75
- onSuccess() {
86
+ onSuccess: async () => {
76
87
  globalStore.signIn.setOpen(false);
77
88
  authenticateMutation.reset();
78
89
  signInMutation.reset();
79
90
  context.setStep(0);
80
91
  form.reset();
92
+ const session = await getSession();
93
+ invariant(session.status === 'authenticated');
94
+ await unregisterFCMDevice({
95
+ type: ['IOS', 'ANDROID'],
96
+ }, {
97
+ headers: {
98
+ Authorization: `Bearer ${session.token}`,
99
+ },
100
+ });
81
101
  if (signInProps.shouldShowResponsibleGamingReminder) {
82
102
  globalStore.responsibleGamingReminder.setOpen(true);
83
103
  }
@@ -1,4 +1,4 @@
1
- import type { ComponentPropsWithRef } from 'react';
1
+ import { type ComponentPropsWithRef } from 'react';
2
2
  interface SignInTriggerProps extends ComponentPropsWithRef<'button'> {
3
3
  asChild?: boolean;
4
4
  }
@@ -1,22 +1,24 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { ark } from '@ark-ui/react/factory';
4
+ import { useState } from 'react';
4
5
  import { useShallow } from 'zustand/shallow';
5
6
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
6
7
  import { getSession } from '../../client/services/getSession.js';
7
8
  import { signIn } from '../../client/services/signIn.js';
8
- import { BiometricAuthError, getBiometricCredentials, getBiometricInfo, hasSavedBiometry, performBiometricVerification, saveBiometricCredentials, } from '../../client/utils/biometric.js';
9
+ import { BiometricAuthError, deleteBiometricCredentials, getBiometricCredentials, getBiometricInfo, hasSavedBiometry, performBiometricVerification, saveBiometricCredentials, } from '../../client/utils/biometric.js';
9
10
  import { toaster } from '../../client/utils/toaster.js';
10
11
  import { createSingleUseToken } from '../../services/auth.js';
11
12
  import { getQueryClient } from '../../utils/getQueryClient.js';
12
13
  import { getSessionQueryKey } from '../../utils/queryKeys.js';
13
14
  export function SignInTrigger(props) {
15
+ const [hasCancelledBiometric, setHasCancelledBiometric] = useState(false);
14
16
  const globalStore = useGlobalStore(useShallow((ctx) => ({
15
17
  signIn: ctx.signIn,
16
18
  registerBiometrics: ctx.registerBiometrics,
17
19
  })));
18
20
  return (_jsx(ark.button, { type: "button", "aria-label": "Sign in", "data-state": globalStore.signIn.open ? 'open' : 'closed', ...props, onClick: async (e) => {
19
- if (hasSavedBiometry()) {
21
+ if (hasSavedBiometry() && !hasCancelledBiometric) {
20
22
  const ok = await performBiometricVerification({
21
23
  reason: 'Login to your account',
22
24
  title: 'Login',
@@ -28,7 +30,10 @@ export function SignInTrigger(props) {
28
30
  const info = await getBiometricInfo();
29
31
  if (info.errorCode === BiometricAuthError.APP_CANCEL ||
30
32
  info.errorCode === BiometricAuthError.USER_CANCEL ||
31
- info.errorCode === BiometricAuthError.SYSTEM_CANCEL) {
33
+ info.errorCode === BiometricAuthError.SYSTEM_CANCEL ||
34
+ info.errorCode === undefined ||
35
+ info.errorCode === null) {
36
+ setHasCancelledBiometric(true);
32
37
  console.log('Biometric verification cancelled');
33
38
  }
34
39
  else {
@@ -43,10 +48,21 @@ export function SignInTrigger(props) {
43
48
  globalStore.signIn.setOpen(!globalStore.signIn.open);
44
49
  return;
45
50
  }
46
- await signIn({
47
- type: 'SINGLE_USE_TOKEN',
48
- token: credentials.password,
49
- });
51
+ try {
52
+ await signIn({
53
+ type: 'SINGLE_USE_TOKEN',
54
+ token: credentials.password,
55
+ });
56
+ }
57
+ catch (err) {
58
+ console.log(err);
59
+ toaster.error({
60
+ title: 'Biometric removed or token expired.',
61
+ description: 'Please sign in with your mobile number or username to re-enable biometric login.',
62
+ });
63
+ deleteBiometricCredentials();
64
+ globalStore.signIn.setOpen(!globalStore.signIn.open);
65
+ }
50
66
  getQueryClient().invalidateQueries({
51
67
  queryKey: getSessionQueryKey(),
52
68
  });
@@ -75,6 +91,45 @@ export function SignInTrigger(props) {
75
91
  }
76
92
  }
77
93
  else {
94
+ // still update biometric credentials if user has cancelled biometric once
95
+ if (hasCancelledBiometric) {
96
+ const credentials = await getBiometricCredentials();
97
+ if (!credentials) {
98
+ toaster.error({ description: 'Biometric verification failed' });
99
+ globalStore.signIn.setOpen(!globalStore.signIn.open);
100
+ return;
101
+ }
102
+ await signIn({
103
+ type: 'SINGLE_USE_TOKEN',
104
+ token: credentials.password,
105
+ });
106
+ getQueryClient().invalidateQueries({
107
+ queryKey: getSessionQueryKey(),
108
+ });
109
+ const session = await getSession();
110
+ const r = await createSingleUseToken({
111
+ headers: {
112
+ Authorization: `Bearer ${session.token}`,
113
+ },
114
+ });
115
+ if (r.token) {
116
+ const saved = await saveBiometricCredentials({
117
+ username: credentials.username,
118
+ password: r.token,
119
+ });
120
+ if (saved) {
121
+ console.info('Biometric credentials has been updated');
122
+ }
123
+ else {
124
+ console.warn('Failed to updated biometric credentials');
125
+ globalStore.signIn.setOpen(!globalStore.signIn.open);
126
+ }
127
+ }
128
+ else {
129
+ console.error('Failed to create token');
130
+ globalStore.signIn.setOpen(!globalStore.signIn.open);
131
+ }
132
+ }
78
133
  globalStore.signIn.setOpen(!globalStore.signIn.open);
79
134
  }
80
135
  return props.onClick?.(e);
@@ -24,7 +24,7 @@ export function TopWins__client(props) {
24
24
  return (_jsxs("div", { className: twMerge('w-full', classNames.root), children: [_jsx("div", { className: twMerge('mb-3 font-semibold text-lg md:mb-4'), children: props.heading ?? 'Recent Big Wins' }), _jsx("div", { ref: emblaRef, className: twMerge('relative lg:overflow-hidden'), children: _jsx("div", { className: twMerge('flex gap-sm lg:gap-md'), children: topWins.map((topWin) => (_jsxs("div", { className: twMerge('flex w-[calc((100%-(0.375rem*2))/3)] shrink-0 flex-col space-y-2 rounded-sm border border-border-primary bg-bg-tertiary p-2 text-center lg:w-[calc((100%-(0.5rem*5))/6)] xl:w-[calc((100%-(0.5rem*9))/10)]', classNames.card), children: [_jsx("div", { className: twMerge('mx-auto aspect-square w-full', classNames.image), children: topWin.game && (_jsx(Image, { src: getGameImageUrl({
25
25
  id: topWin.game.id,
26
26
  provider: topWin.game.provider,
27
- }), alt: "", width: 120, height: 120, loading: "lazy", unoptimized: true, className: twMerge('size-full rounded-sm object-cover', classNames.image) })) }), _jsxs("div", { className: twMerge('space-y-0.5'), children: [_jsx("div", { className: twMerge('text-text-secondary-700 text-xs', classNames.playerName), children: topWin.member.name }), _jsx("div", { className: twMerge('break-words font-semibold text-sm text-text-primary-brand', classNames.amount), children: formatNumber(topWin.payout, {
27
+ }), alt: topWin.game.name, width: 120, height: 120, loading: "lazy", unoptimized: true, className: twMerge('size-full rounded-sm object-cover', classNames.image) })) }), _jsxs("div", { className: twMerge('space-y-0.5'), children: [_jsx("div", { className: twMerge('text-text-secondary-700 text-xs', classNames.playerName), children: topWin.member.name }), _jsx("div", { className: twMerge('break-words font-semibold text-sm text-text-primary-brand', classNames.amount), children: formatNumber(topWin.payout, {
28
28
  currency: localeInfo.currency.code,
29
29
  minDecimalPlaces: 2,
30
30
  }) }), _jsxs("div", { className: twMerge('break-words text-text-secondary-700 text-xs', classNames.multiplier), children: [formatNumber(topWin.multiplier, {
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Capacitor } from '@capacitor/core';
2
3
  import Image from 'next/image';
3
4
  import { useRef } from 'react';
4
5
  import { twMerge } from 'tailwind-merge';
@@ -52,8 +53,16 @@ export function IdFrontImageField__client(props) {
52
53
  context.query.isLoading ||
53
54
  context.mutation.isPending ||
54
55
  localProps.disabled ||
55
- localProps.readOnly, className: "font-semibold text-button-secondary-fg disabled:opacity-60", children: "Click to upload" }), ' ', "or drag and drop"] }), _jsx("span", { className: "mt-xs block text-center text-xs", children: "PNG, JPG or JPEG (max. 10mb)" }), _jsx("span", { className: "m-txs block text-center text-xs", children: "or" })] }), _jsx(Button, { size: "sm", variant: "outline", className: "mx-auto mt-md w-auto", onClick: () => {
56
- context.disclosure.setOpen(true);
56
+ localProps.readOnly, className: "font-semibold text-button-secondary-fg disabled:opacity-60", children: "Click to upload" }), ' ', "or drag and drop"] }), _jsx("span", { className: "mt-xs block text-center text-xs", children: "PNG, JPG or JPEG (max. 10mb)" }), _jsx("span", { className: "m-txs block text-center text-xs", children: "or" })] }), _jsx(Button, { size: "sm", variant: "outline", className: "mx-auto mt-md w-auto", onClick: async () => {
57
+ if (Capacitor.isNativePlatform()) {
58
+ const data = await context.camera.openNativeCamera();
59
+ if (!data?.file)
60
+ return;
61
+ context.mutation.mutate({ file: data.file });
62
+ }
63
+ else {
64
+ context.disclosure.setOpen(true);
65
+ }
57
66
  }, disabled: context.field?.disabled ||
58
67
  context.field?.readOnly ||
59
68
  context.query.isLoading ||
@@ -70,6 +79,7 @@ export function IdFrontImageField__client(props) {
70
79
  */
71
80
  function Camera() {
72
81
  const context = useIdFrontImageFieldContext();
82
+ console.log(context.camera, 'context.camera');
73
83
  return (_jsx(Dialog.Root, { open: context.disclosure.open, onOpenChange: (details) => {
74
84
  context.disclosure.setOpen(details.open);
75
85
  }, closeOnEscape: false, closeOnInteractOutside: false, onExitComplete: context.camera.close, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "!z-[calc(var(--z-dialog)+1)]" }), _jsx(Dialog.Positioner, { className: "!z-[calc(var(--z-dialog)+2)] flex items-center justify-center overflow-y-auto py-4", children: _jsxs(Dialog.Content, { className: "mx-auto w-[calc(100dvw-1rem)] max-w-[calc(100dvw-1rem)] overflow-y-auto rounded-lg bg-bg-primary-alt px-4 py-5 lg:w-[747px] lg:max-w-[747px] lg:px-3xl lg:py-4xl", children: [_jsx(Dialog.CloseTrigger, { children: _jsx(XIcon, {}) }), _jsx(Dialog.Title, { className: "text-center font-semibold lg:text-xl", children: "Take a Picture of Your Front ID" }), _jsxs(Dialog.Description, { className: "mt-md text-center text-text-tertiary-600 text-xs lg:text-base", children: ["Make sure your ID is clearly visible, well-lit, and not blurry.", ' ', _jsx("br", { className: "hidden lg:block" }), "Avoid glare or reflections, and ensure all corners are within\u00A0the\u00A0frame."] }), _jsxs("div", { className: "relative mt-5 lg:mt-10 lg:px-3xl", children: [_jsx(Video, {}), context.camera.error && (_jsxs("div", { className: "flex aspect-[4/3] flex-col items-center justify-center rounded-md border border-border-disabled bg-black px-4 lg:aspect-video", children: [_jsx(CameraOffIcon, { className: "size-10 text-center text-text-placeholder-subtle lg:size-12" }), _jsx("h2", { className: "mt-3 font-semibold text-sm lg:mt-4 lg:text-base", children: context.camera.error.name }), _jsx("p", { className: "mt-0.5 text-center text-text-tertiary-600 text-xs lg:mt-1 lg:text-sm", children: context.camera.error.message }), _jsx(Button, { size: "xs", variant: "outline", colorScheme: "gray", fullWidth: false, className: "mt-4 lg:mt-5", onClick: () => {
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Capacitor } from '@capacitor/core';
2
3
  import Image from 'next/image';
3
4
  import { useRef } from 'react';
4
5
  import { twMerge } from 'tailwind-merge';
@@ -52,8 +53,16 @@ export function SelfieImageField__client(props) {
52
53
  context.query.isLoading ||
53
54
  context.mutation.isPending ||
54
55
  localProps.disabled ||
55
- localProps.readOnly, className: "font-semibold text-button-secondary-fg disabled:opacity-60", children: "Click to upload" }), ' ', "or drag and drop"] }), _jsx("span", { className: "mt-xs block text-center text-xs", children: "PNG, JPG or JPEG (max. 10mb)" }), _jsx("span", { className: "m-txs block text-center text-xs", children: "or" })] }), _jsx(Button, { size: "sm", variant: "outline", className: "mx-auto mt-md w-auto", onClick: () => {
56
- context.disclosure.setOpen(true);
56
+ localProps.readOnly, className: "font-semibold text-button-secondary-fg disabled:opacity-60", children: "Click to upload" }), ' ', "or drag and drop"] }), _jsx("span", { className: "mt-xs block text-center text-xs", children: "PNG, JPG or JPEG (max. 10mb)" }), _jsx("span", { className: "m-txs block text-center text-xs", children: "or" })] }), _jsx(Button, { size: "sm", variant: "outline", className: "mx-auto mt-md w-auto", onClick: async () => {
57
+ if (Capacitor.isNativePlatform()) {
58
+ const data = await context.camera.openNativeCamera();
59
+ if (!data?.file)
60
+ return;
61
+ context.mutation.mutate({ file: data.file });
62
+ }
63
+ else {
64
+ context.disclosure.setOpen(true);
65
+ }
57
66
  }, disabled: context.field?.disabled ||
58
67
  context.field?.readOnly ||
59
68
  context.query.isLoading ||
@@ -0,0 +1,2 @@
1
+ import type { ComponentPropsWithRef } from 'react';
2
+ export declare function LinkBrokenIcon(props: ComponentPropsWithRef<'svg'>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function LinkBrokenIcon(props) {
3
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", ...props, children: _jsx("path", { d: "M8.5 15.5L15.5 8.49998M9 4V2M15 20V22M4 9H2M20 15H22M4.91421 4.91421L3.5 3.5M19.0858 19.0857L20.5 20.4999M12 17.6568L9.87871 19.7781C8.31662 21.3402 5.78396 21.3402 4.22186 19.7781C2.65976 18.216 2.65976 15.6833 4.22186 14.1212L6.34318 11.9999M17.6569 11.9999L19.7782 9.87859C21.3403 8.31649 21.3403 5.78383 19.7782 4.22174C18.2161 2.65964 15.6835 2.65964 14.1214 4.22174L12 6.34306", stroke: "#FEDF89", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }) }));
4
+ }