@opexa/portal-components 0.0.864 → 0.0.866

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 (134) hide show
  1. package/dist/components/Banner/Banner.client.d.ts +12 -0
  2. package/dist/components/Banner/Banner.client.js +49 -0
  3. package/dist/components/DateOfBirthField.d.ts +10 -0
  4. package/dist/components/DateOfBirthField.js +65 -0
  5. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
  6. package/dist/components/DepositWithdrawal/Deposit/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
  7. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__legacy/QRPHDepositContext.d.ts +2 -2
  8. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__legacy/useQRPHDeposit.d.ts +1 -1
  9. package/dist/components/DepositWithdrawal/Deposit__legacy/OnlineBankDeposit/OnlineBankDepositContext.d.ts +2 -2
  10. package/dist/components/DepositWithdrawal/Deposit__legacy/OnlineBankDeposit/useOnlineBankDeposit.d.ts +1 -1
  11. package/dist/components/DepositWithdrawal/Deposit__legacy/QRPHDeposit/QRPHDepositContext.d.ts +2 -2
  12. package/dist/components/DepositWithdrawal/Deposit__legacy/QRPHDeposit/useQRPHDeposit.d.ts +1 -1
  13. package/dist/components/KYC/KYC.d.ts +2 -1
  14. package/dist/components/KYC/KYC.js +7 -0
  15. package/dist/components/KYC/KYCNonPagCor/IdentityVerification.d.ts +1 -0
  16. package/dist/components/KYC/KYCNonPagCor/IdentityVerification.js +166 -0
  17. package/dist/components/KYC/KYCNonPagCor/Indicator.d.ts +1 -0
  18. package/dist/components/KYC/KYCNonPagCor/Indicator.js +8 -0
  19. package/dist/components/KYC/KYCNonPagCor/KYCNonPagcor.d.ts +8 -0
  20. package/dist/components/KYC/KYCNonPagCor/KYCNonPagcor.js +26 -0
  21. package/dist/components/KYC/KYCNonPagCor/KYCNonPagcorContext.d.ts +6 -0
  22. package/dist/components/KYC/KYCNonPagCor/KYCNonPagcorContext.js +2 -0
  23. package/dist/components/KYC/KYCNonPagCor/KYCVerificationStatus.d.ts +1 -0
  24. package/dist/components/KYC/KYCNonPagCor/KYCVerificationStatus.js +10 -0
  25. package/dist/components/KYC/KYCNonPagCor/KYCVerificationStatus.lazy.d.ts +1 -0
  26. package/dist/components/KYC/KYCNonPagCor/KYCVerificationStatus.lazy.js +38 -0
  27. package/dist/components/KYC/KYCNonPagCor/PersonalInformation.d.ts +1 -0
  28. package/dist/components/KYC/KYCNonPagCor/PersonalInformation.js +141 -0
  29. package/dist/components/KYC/KYCNonPagCor/index.d.ts +1 -0
  30. package/dist/components/KYC/KYCNonPagCor/index.js +1 -0
  31. package/dist/components/KYC/KYCNonPagCor/useKYCNonPagCor.d.ts +26 -0
  32. package/dist/components/KYC/KYCNonPagCor/useKYCNonPagCor.js +45 -0
  33. package/dist/components/KYC/KYCVerificationStatus.lazy.js +7 -4
  34. package/dist/components/PortalProvider/AndroidOnlyComponents.d.ts +1 -0
  35. package/dist/components/PortalProvider/AndroidOnlyComponents.js +12 -0
  36. package/dist/components/PortalProvider/CXDTokenObserver.js +11 -11
  37. package/dist/components/SignIn/CrazyWin/MobileNumberSignIn.d.ts +1 -0
  38. package/dist/components/SignIn/CrazyWin/MobileNumberSignIn.js +259 -0
  39. package/dist/components/SignIn/CrazyWin/NameAndPasswordSignIn.d.ts +1 -0
  40. package/dist/components/SignIn/CrazyWin/NameAndPasswordSignIn.js +301 -0
  41. package/dist/components/SignIn/CrazyWin/SignInForm.d.ts +1 -0
  42. package/dist/components/SignIn/CrazyWin/SignInForm.js +10 -0
  43. package/dist/components/SignIn/CrazyWin/SignInMethod.d.ts +1 -0
  44. package/dist/components/SignIn/CrazyWin/SignInMethod.js +28 -0
  45. package/dist/components/SignIn/HappyBingo/MobileNumberSignIn.d.ts +1 -0
  46. package/dist/components/SignIn/HappyBingo/MobileNumberSignIn.js +256 -0
  47. package/dist/components/SignIn/HappyBingo/NameAndPasswordSignIn.d.ts +1 -0
  48. package/dist/components/SignIn/HappyBingo/NameAndPasswordSignIn.js +295 -0
  49. package/dist/components/SignIn/HappyBingo/SignInForm.d.ts +1 -0
  50. package/dist/components/SignIn/HappyBingo/SignInForm.js +30 -0
  51. package/dist/components/SignIn/SignIn.lazy.d.ts +1 -0
  52. package/dist/components/SignIn/SignIn.lazy.js +3 -1
  53. package/dist/components/SignIn/utils.d.ts +8 -0
  54. package/dist/components/SignIn/utils.js +26 -0
  55. package/dist/components/SignUp/SignUpDefault/SignUpDefault.lazy.d.ts +1 -0
  56. package/dist/components/SignUp/SignUpDefault/SignUpDefaultForm.js +83 -132
  57. package/dist/constants/Branches.d.ts +2 -0
  58. package/dist/constants/Branches.js +42 -0
  59. package/dist/images/phone-icon.svg +10 -0
  60. package/dist/third-parties/FacebookPixel/FacebookPixel.d.ts +4 -0
  61. package/dist/third-parties/FacebookPixel/FacebookPixel.js +4 -0
  62. package/dist/third-parties/FacebookPixel/api.d.ts +0 -0
  63. package/dist/third-parties/FacebookPixel/api.js +1 -0
  64. package/dist/third-parties/FacebookPixel/index.d.ts +1 -0
  65. package/dist/third-parties/FacebookPixel/index.js +1 -0
  66. package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.d.ts +4 -0
  67. package/dist/third-parties/GoogleRecaptcha/GoogleRecaptcha.js +4 -0
  68. package/dist/third-parties/GoogleRecaptcha/api.d.ts +0 -0
  69. package/dist/third-parties/GoogleRecaptcha/api.js +1 -0
  70. package/dist/third-parties/GoogleRecaptcha/index.d.ts +1 -0
  71. package/dist/third-parties/GoogleRecaptcha/index.js +1 -0
  72. package/dist/third-parties/index.d.ts +2 -0
  73. package/dist/third-parties/index.js +2 -0
  74. package/dist/ui/AlertDialog/AlertDialog.d.ts +88 -88
  75. package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +8 -8
  76. package/dist/ui/Badge/Badge.d.ts +12 -12
  77. package/dist/ui/Badge/badge.anatomy.d.ts +1 -1
  78. package/dist/ui/Badge/badge.recipe.d.ts +3 -3
  79. package/dist/ui/Carousel/Carousel.d.ts +72 -72
  80. package/dist/ui/Carousel/carousel.recipe.d.ts +8 -8
  81. package/dist/ui/Checkbox/Checkbox.d.ts +23 -23
  82. package/dist/ui/Checkbox/checkbox.recipe.d.ts +3 -3
  83. package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
  84. package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
  85. package/dist/ui/Collapsible/Collapsible.d.ts +20 -20
  86. package/dist/ui/Collapsible/collapsible.recipe.d.ts +5 -5
  87. package/dist/ui/Combobox/Combobox.d.ts +42 -42
  88. package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
  89. package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
  90. package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
  91. package/dist/ui/Dialog/Dialog.d.ts +33 -33
  92. package/dist/ui/Dialog/dialog.recipe.d.ts +3 -3
  93. package/dist/ui/Drawer/Drawer.d.ts +33 -33
  94. package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
  95. package/dist/ui/Menu/Menu.d.ts +306 -306
  96. package/dist/ui/Menu/menu.recipe.d.ts +17 -17
  97. package/dist/ui/Popover/Popover.d.ts +121 -121
  98. package/dist/ui/Popover/popover.recipe.d.ts +11 -11
  99. package/dist/ui/Progress/Progress.d.ts +27 -27
  100. package/dist/ui/Progress/progress.recipe.d.ts +3 -3
  101. package/dist/ui/QrCode/QrCode.d.ts +40 -40
  102. package/dist/ui/QrCode/qrCode.recipe.d.ts +8 -8
  103. package/dist/ui/Select/Select.d.ts +45 -45
  104. package/dist/ui/Select/select.recipe.d.ts +3 -3
  105. package/dist/ui/Table/Table.d.ts +21 -21
  106. package/dist/ui/Table/table.anatomy.d.ts +1 -1
  107. package/dist/ui/Table/table.recipe.d.ts +3 -3
  108. package/dist/ui/Tabs/Tabs.d.ts +15 -15
  109. package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
  110. package/dist/ui/Tooltip/Tooltip.d.ts +30 -30
  111. package/dist/ui/Tooltip/tooltip.recipe.d.ts +5 -5
  112. package/package.json +1 -1
  113. package/dist/components/AccountInfo/GoogleDisconnect.d.ts +0 -7
  114. package/dist/components/AccountInfo/GoogleDisconnect.js +0 -11
  115. package/dist/components/DepositWithdrawal/Deposit/GCashWebpayDeposit /GCashWebpayDeposit .d.ts +0 -1
  116. package/dist/components/DepositWithdrawal/Deposit/GCashWebpayDeposit /GCashWebpayDeposit .js +0 -191
  117. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/Confirmed.d.ts +0 -1
  118. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/Confirmed.js +0 -11
  119. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/Failed.d.ts +0 -1
  120. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/Failed.js +0 -11
  121. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/Form.d.ts +0 -1
  122. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/Form.js +0 -126
  123. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/GeneratingQrCode.d.ts +0 -1
  124. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/GeneratingQrCode.js +0 -10
  125. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/QRPHDeposit.d.ts +0 -1
  126. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/QRPHDeposit.js +0 -12
  127. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/QRPHDepositContext.d.ts +0 -17
  128. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/QRPHDepositContext.js +0 -2
  129. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/QrCodeGenerated.d.ts +0 -1
  130. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/QrCodeGenerated.js +0 -41
  131. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/useQRPHDeposit.d.ts +0 -13
  132. package/dist/components/DepositWithdrawal/Deposit/QRPHDeposit__next/useQRPHDeposit.js +0 -91
  133. package/dist/icons/LinkBrokenIcon.d.ts +0 -2
  134. package/dist/icons/LinkBrokenIcon.js +0 -4
@@ -0,0 +1,141 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Capacitor } from '@capacitor/core';
3
+ import { zodResolver } from '@hookform/resolvers/zod';
4
+ import { differenceInYears } from 'date-fns';
5
+ import { useRouter } from 'next/navigation';
6
+ import { useForm } from 'react-hook-form';
7
+ import invariant from 'tiny-invariant';
8
+ import { z } from 'zod';
9
+ import { useShallow } from 'zustand/shallow';
10
+ import { useGlobalStore } from '../../../client/hooks/useGlobalStore.js';
11
+ import { useSignOutMutation } from '../../../client/hooks/useSignOutMutation.js';
12
+ import { useUpdateAccountMutation } from '../../../client/hooks/useUpdateAccountMutation.js';
13
+ import { getSession } from '../../../client/services/getSession.js';
14
+ import { BIOMETRIC_STORAGE_KEY } from '../../../client/utils/biometric.js';
15
+ import { toaster } from '../../../client/utils/toaster.js';
16
+ import { unregisterFCMDevice } from '../../../services/trigger.js';
17
+ import { Button } from '../../../ui/Button/index.js';
18
+ import { Dialog } from '../../../ui/Dialog/index.js';
19
+ import { Field } from '../../../ui/Field/index.js';
20
+ import { getQueryClient } from '../../../utils/getQueryClient.js';
21
+ import { getSessionQueryKey } from '../../../utils/queryKeys.js';
22
+ import DateOfBirthField from '../../DateOfBirthField.js';
23
+ import { useKYCNonPagcorContext } from './KYCNonPagcorContext.js';
24
+ const firstNameBaseSchema = z
25
+ .string()
26
+ .regex(/^[a-z ]+$/gi, 'First name must contain only letters')
27
+ .transform((val) => val.trim())
28
+ .refine((val) => val.length >= 2, {
29
+ message: 'First name must be 2 or more characters',
30
+ })
31
+ .refine((val) => val.length <= 50, {
32
+ message: 'First name must not be more than 50 characters',
33
+ });
34
+ const lastNameBaseSchema = z
35
+ .string()
36
+ .regex(/^[a-z ]+$/gi, 'Last name must contain only letters')
37
+ .transform((val) => val.trim())
38
+ .refine((val) => val.length >= 2, {
39
+ message: 'Last name must be 2 or more characters',
40
+ })
41
+ .refine((val) => val.length <= 50, {
42
+ message: 'Last name must not be more than 50 characters',
43
+ });
44
+ const birthdateBaseSchema = z
45
+ .date({
46
+ invalid_type_error: 'Date of birth is required',
47
+ required_error: 'Date of birth is required',
48
+ })
49
+ .superRefine((val, ctx) => {
50
+ const now = new Date();
51
+ const age = differenceInYears(now, val);
52
+ if (age < 21) {
53
+ return ctx.addIssue({
54
+ code: z.ZodIssueCode.custom,
55
+ message: 'You must be at least 21 years old',
56
+ });
57
+ }
58
+ });
59
+ const definition = z.object({
60
+ firstName: firstNameBaseSchema,
61
+ lastName: lastNameBaseSchema,
62
+ birthday: birthdateBaseSchema,
63
+ });
64
+ export function PersonalInformation() {
65
+ const kyc = useKYCNonPagcorContext();
66
+ const globalStore = useGlobalStore(useShallow((ctx) => ({
67
+ kyc: ctx.kyc,
68
+ kycReminder: ctx.kycReminder,
69
+ })));
70
+ const router = useRouter();
71
+ const updateAccountMutation = useUpdateAccountMutation({
72
+ onError(error) {
73
+ toaster.error({
74
+ description: error.message,
75
+ });
76
+ },
77
+ });
78
+ const signOutMutation = useSignOutMutation({
79
+ async onSuccess() {
80
+ const keep = new Set([BIOMETRIC_STORAGE_KEY]);
81
+ for (let i = 0; i < localStorage.length;) {
82
+ const key = localStorage.key(i);
83
+ if (key && !keep.has(key)) {
84
+ localStorage.removeItem(key);
85
+ }
86
+ else {
87
+ i++;
88
+ }
89
+ }
90
+ sessionStorage.clear();
91
+ router.replace('/');
92
+ },
93
+ });
94
+ const form = useForm({
95
+ resolver: zodResolver(definition),
96
+ defaultValues: {
97
+ firstName: '',
98
+ lastName: '',
99
+ birthday: undefined,
100
+ },
101
+ mode: 'all',
102
+ });
103
+ async function onSubmit(values) {
104
+ await updateAccountMutation.mutateAsync({
105
+ realName: `${values.firstName} ${values.lastName}`,
106
+ birthDay: values.birthday.toISOString().split('T')[0],
107
+ });
108
+ }
109
+ const birthDay = form.watch('birthday');
110
+ return (_jsxs("div", { children: [_jsx(Dialog.Title, { className: "text-center font-semibold text-lg", children: "Personal Information" }), _jsx(Dialog.Description, { className: "mt-xs text-center text-sm text-text-secondary-700", children: "Provide your basic details and work info." }), _jsxs("form", { className: "mt-7", onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(Field.Root, { className: "mt-2xl", invalid: !!form.formState.errors.firstName, children: [_jsx(Field.Label, { children: "First Name" }), _jsx(Field.Input, { placeholder: "Enter your first name", ...form.register('firstName') }), _jsx(Field.ErrorText, { children: form.formState.errors.firstName?.message })] }), _jsxs(Field.Root, { className: "mt-2xl", invalid: !!form.formState.errors.lastName, children: [_jsx(Field.Label, { children: "Last Name" }), _jsx(Field.Input, { placeholder: "Enter your last name", ...form.register('lastName') }), _jsx(Field.ErrorText, { children: form.formState.errors.lastName?.message })] }), _jsxs(Field.Root, { invalid: !!form.formState.errors.birthday, className: "mt-xl", children: [_jsx(DateOfBirthField, { value: birthDay, onChange: (value) => {
111
+ if (!value)
112
+ return;
113
+ form.setValue('birthday', value, {
114
+ shouldDirty: true,
115
+ shouldTouch: true,
116
+ shouldValidate: true,
117
+ });
118
+ }, onBlur: () => {
119
+ form.trigger('birthday');
120
+ } }), _jsx(Field.ErrorText, { children: form.formState.errors.birthday?.message })] }), _jsx(Button, { type: "submit", className: "mt-4xl", disabled: updateAccountMutation.isPending, children: "Continue" }), kyc.isSkippable && (_jsx(Button, { variant: "outline", colorScheme: "gray", className: "mt-lg", type: "button", onClick: () => {
121
+ globalStore.kyc.setOpen(false);
122
+ globalStore.kycReminder.setOpen(true);
123
+ }, disabled: updateAccountMutation.isPending, children: "Skip for now" })), ' ', _jsx(Button, { className: "bg-transparent text-text-brand-primary-600", onClick: async () => {
124
+ if (Capacitor.isNativePlatform()) {
125
+ const session = await getQueryClient().fetchQuery({
126
+ queryKey: getSessionQueryKey(),
127
+ queryFn: async () => getSession(),
128
+ });
129
+ invariant(session.status === 'authenticated');
130
+ await unregisterFCMDevice({
131
+ type: ['IOS', 'ANDROID'],
132
+ }, {
133
+ headers: {
134
+ Authorization: `Bearer ${session.token}`,
135
+ },
136
+ });
137
+ }
138
+ signOutMutation.mutate();
139
+ router.push('/');
140
+ }, children: "Log Out" })] })] }));
141
+ }
@@ -0,0 +1 @@
1
+ export * from './KYCNonPagcor';
@@ -0,0 +1 @@
1
+ export * from './KYCNonPagcor.js';
@@ -0,0 +1,26 @@
1
+ type EventDetail = {
2
+ type: 'SELFIE_CAPTURED';
3
+ data: string;
4
+ } | {
5
+ type: 'ID_DOCUMENT_CAPTURED';
6
+ data: string;
7
+ };
8
+ type UnsubscribeFn = () => void;
9
+ type Subscriber = (detail: EventDetail) => UnsubscribeFn;
10
+ export type CaptureSubject = 'SELFIE' | 'ID_DOCUMENT';
11
+ export interface UseKycNonPagcorReturn {
12
+ step: number;
13
+ setStep: (step: number) => void;
14
+ done: boolean;
15
+ setDone: (done: boolean) => void;
16
+ subscribe: (subscriber: Subscriber) => UnsubscribeFn;
17
+ triggerEvent: (detail: EventDetail) => void;
18
+ idFrontImageId: string | null;
19
+ setFrontImageId: (id: string | null) => void;
20
+ selfieImageId: string | null;
21
+ setSelfieImageId: (id: string | null) => void;
22
+ reset: () => void;
23
+ isSkippable: boolean;
24
+ }
25
+ export declare function useKYCNonPagCor(isSkippable: boolean): UseKycNonPagcorReturn;
26
+ export {};
@@ -0,0 +1,45 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { useAccountQuery } from '../../../client/hooks/useAccountQuery.js';
3
+ export function useKYCNonPagCor(isSkippable) {
4
+ const account = useAccountQuery();
5
+ const [step, setStep] = useState(1);
6
+ const [done, setDone] = useState(false);
7
+ const [idFrontImageId, setFrontImageId] = useState(null);
8
+ const [selfieImageId, setSelfieImageId] = useState(null);
9
+ const subscribers = useRef([]);
10
+ const subscribe = (subscriber) => {
11
+ subscribers.current.push(subscriber);
12
+ return () => {
13
+ subscribers.current = subscribers.current.filter((item) => item !== subscriber);
14
+ };
15
+ };
16
+ useEffect(() => {
17
+ setStep(account.data?.realName ? 2 : 1);
18
+ }, [account.data]);
19
+ const triggerEvent = (detail) => {
20
+ subscribers.current.forEach((subscriber) => {
21
+ subscriber(detail);
22
+ });
23
+ };
24
+ const reset = () => {
25
+ console.log('KYC NON PAGCOR RESET', account.data);
26
+ setStep(account.data?.realName ? 2 : 1);
27
+ setDone(false);
28
+ setFrontImageId(null);
29
+ setSelfieImageId(null);
30
+ };
31
+ return {
32
+ step,
33
+ setStep,
34
+ done,
35
+ setDone,
36
+ idFrontImageId,
37
+ setFrontImageId,
38
+ selfieImageId,
39
+ setSelfieImageId,
40
+ subscribe,
41
+ triggerEvent,
42
+ reset,
43
+ isSkippable,
44
+ };
45
+ }
@@ -19,15 +19,18 @@ export function KYCVerificationStatus() {
19
19
  const icons = status === 'PENDING' ? bellIcon : alertIcon;
20
20
  return (_jsx(Dialog.Root, { open: globalStore.kycVerificationStatus.open, onOpenChange: (details) => {
21
21
  globalStore.kycVerificationStatus.setOpen(details.open);
22
- }, closeOnEscape: false, closeOnInteractOutside: false, 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: _jsx(Dialog.Content, { className: "mx-auto h-fit w-[450px] overflow-y-auto rounded-lg bg-bg-primary", children: _jsxs("div", { className: "p-3xl text-center", children: [_jsx("div", { className: "mb-3xl grid h-[200px] w-full place-items-center rounded-xl bg-radial from-40% from-button-primary-bg to-bg-brand-solid", children: _jsx(Image, { src: icons, alt: "icon", className: "w-60 object-contain", draggable: false, width: 120, height: 120 }) }), _jsxs("h1", { className: "font-semibold text-lg text-white", children: [status === 'PENDING' && 'Verification in Progress', status === 'REJECTED' && 'Verification Rejected', status === 'UNVERIFIED' && 'Verification Required'] }), _jsxs("p", { className: "mb-4xl text-[#94969C] text-base", children: [status === 'PENDING' &&
22
+ }, closeOnEscape: false, closeOnInteractOutside: false, 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: _jsx(Dialog.Content, { className: "mx-auto h-fit w-[450px] overflow-y-auto rounded-lg bg-bg-primary", children: _jsxs("div", { className: "p-3xl text-center", children: [_jsx("div", { className: "mb-3xl grid h-[200px] w-full place-items-center rounded-xl bg-radial from-40% from-button-primary-bg to-bg-brand-solid", children: _jsx(Image, { src: icons, alt: "icon", className: "w-60 object-contain", draggable: false, width: 120, height: 120 }) }), _jsxs("h1", { className: "font-semibold text-lg text-white", children: [status === 'PENDING' && 'Verification in Progress', status === 'REJECTED' && 'Verification Rejected', status === 'UNVERIFIED' ||
23
+ (status === 'CREATED' && 'Verification Required')] }), _jsxs("p", { className: "mb-4xl text-[#94969C] text-base", children: [status === 'PENDING' &&
23
24
  `Your account verification is still under review. Please wait
24
25
  until it's approved before you can continue playing or
25
26
  depositing.`, status === 'REJECTED' &&
26
- 'Your account verification was not approved. Please resubmit your verification to regain full access.', status === 'UNVERIFIED' &&
27
- 'Your account is not yet verified. Please complete the verification process to continue playing or depositing.'] }), _jsxs(Button, { variant: "solid", className: twMerge('mb-2 w-full', status === 'PENDING' && 'hidden'), onClick: () => {
27
+ 'Your account verification was not approved. Please resubmit your verification to regain full access.', status === 'UNVERIFIED' ||
28
+ (status === 'CREATED' &&
29
+ 'Your account is not yet verified. Please complete the verification process to continue playing or depositing.')] }), _jsxs(Button, { variant: "solid", className: twMerge('mb-2 w-full', status === 'PENDING' && 'hidden'), onClick: () => {
28
30
  globalStore.kycVerificationStatus.setOpen(false);
29
31
  globalStore.kyc.setOpen(true);
30
- }, children: [status === 'REJECTED' && 'Resubmit Verification', status === 'UNVERIFIED' && 'Verify Now'] }), _jsx(Button, { type: "button", variant: "outline", onClick: () => {
32
+ }, children: [status === 'REJECTED' && 'Resubmit Verification', status === 'UNVERIFIED' ||
33
+ (status === 'CREATED' && 'Verify Now')] }), _jsx(Button, { type: "button", variant: "outline", onClick: () => {
31
34
  globalStore.kycVerificationStatus.setOpen(false);
32
35
  }, children: "Close" })] }) }) })] }) }));
33
36
  }
@@ -0,0 +1 @@
1
+ export declare function AndroidOnlyComponents(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Capacitor } from '@capacitor/core';
4
+ import { AndroidRoutingHandler } from './AndroidRoutingHandler.js';
5
+ import PushNotification from './PushNotifications.js';
6
+ export function AndroidOnlyComponents() {
7
+ const platform = Capacitor.getPlatform();
8
+ const isNative = platform === 'android' || platform === 'ios';
9
+ if (!isNative)
10
+ return null;
11
+ return (_jsxs(_Fragment, { children: [_jsx(PushNotification, {}), _jsx(AndroidRoutingHandler, {})] }));
12
+ }
@@ -1,30 +1,30 @@
1
1
  'use client';
2
2
  import { addHours } from 'date-fns';
3
3
  import { clamp } from 'lodash-es';
4
- import { useSearchParams } from 'next/navigation';
5
4
  import { useLocalStorage, useTimeout } from 'usehooks-ts';
6
5
  import { useAccountQuery } from '../../client/hooks/useAccountQuery.js';
7
6
  export function CXDTokenObserver() {
8
- const searchParams = useSearchParams();
9
- const cxdToken = searchParams.get('cxd');
10
- const accountQuery = useAccountQuery();
11
- const account = accountQuery.data;
12
- const [cxd, setCxd, removeCxd] = useLocalStorage('WebPortalCellxpertCxd', null);
7
+ const { data: account } = useAccountQuery();
8
+ const accountCxd = {
9
+ cxd: account?.cellxpertDetails?.cxd,
10
+ };
11
+ const [cxd, setCxd, removeCxd] = useLocalStorage('cxd', null);
13
12
  const now = new Date();
14
- const shouldTimeoutRun = cxdToken && account;
15
13
  const removeCxdUntilInMs = cxd?.timestamp
16
14
  ? clamp(cxd.timestamp - now.getTime(), 0, Infinity)
17
15
  : 0;
18
16
  useTimeout(() => {
19
- const isSame = cxd?.cxd === cxdToken;
17
+ const isSame = cxd?.cxd === accountCxd.cxd;
20
18
  if (!isSame) {
21
19
  const extendedTimestamp = addHours(new Date(), 6).getTime();
22
20
  setCxd({
23
- cxd: cxdToken,
21
+ cxd: accountCxd.cxd,
24
22
  timestamp: extendedTimestamp,
25
23
  });
26
24
  }
27
- }, shouldTimeoutRun ? 100 : null);
28
- useTimeout(() => removeCxd(), shouldTimeoutRun ? removeCxdUntilInMs : null);
25
+ }, account ? 100 : null);
26
+ useTimeout(() => {
27
+ removeCxd();
28
+ }, account ? removeCxdUntilInMs : null);
29
29
  return null;
30
30
  }
@@ -0,0 +1 @@
1
+ export declare function MobileNumberSignIn(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,259 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Capacitor } from '@capacitor/core';
3
+ import { zodResolver } from '@hookform/resolvers/zod';
4
+ import Image from 'next/image';
5
+ import { useRouter } from 'next/navigation';
6
+ import { useRef } from 'react';
7
+ import { Controller, useForm } from 'react-hook-form';
8
+ import { twJoin } from 'tailwind-merge';
9
+ import invariant from 'tiny-invariant';
10
+ import { z } from 'zod';
11
+ import { useShallow } from 'zustand/shallow';
12
+ import { useCooldown } from '../../../client/hooks/useCooldown.js';
13
+ import { useGlobalStore } from '../../../client/hooks/useGlobalStore.js';
14
+ import { useLocaleInfo } from '../../../client/hooks/useLocaleInfo.js';
15
+ import { useMobileNumberParser } from '../../../client/hooks/useMobileNumberParser.js';
16
+ import { useSendVerificationCodeMutation } from '../../../client/hooks/useSendVerificationCodeMutation.js';
17
+ import { useSignInMutation } from '../../../client/hooks/useSignInMutation.js';
18
+ import { getSession } from '../../../client/services/getSession.js';
19
+ import { deleteBiometricCredentials, getBiometricCredentials, hasSavedBiometry, saveBiometricCredentials, } from '../../../client/utils/biometric.js';
20
+ import { toaster } from '../../../client/utils/toaster.js';
21
+ import { ArrowLeftIcon } from '../../../icons/ArrowLeftIcon.js';
22
+ import { CheckIcon } from '../../../icons/CheckIcon.js';
23
+ import phoneIcon from '../../../images/phone-icon.svg';
24
+ import { createSingleUseToken } from '../../../services/auth.js';
25
+ import { registerFCMDevice, unregisterFCMDevice, } from '../../../services/trigger.js';
26
+ import { Button } from '../../../ui/Button/index.js';
27
+ import { Checkbox } from '../../../ui/Checkbox/index.js';
28
+ import { Field } from '../../../ui/Field/index.js';
29
+ import { PinInput } from '../../../ui/PinInput/index.js';
30
+ import { LOCALSTORAGE_PUSH_NOTIFICATION_TOKEN_KEY } from '../../PortalProvider/PushNotifications.js';
31
+ import { useSignInContext, useSignInPropsContext } from './../SignInContext.js';
32
+ export function MobileNumberSignIn() {
33
+ const signInProps = useSignInPropsContext();
34
+ const router = useRouter();
35
+ const context = useSignInContext();
36
+ const globalStore = useGlobalStore(useShallow((ctx) => ({
37
+ signIn: ctx.signIn,
38
+ signUp: ctx.signUp,
39
+ kycReminder: ctx.kycReminder,
40
+ responsibleGaming: ctx.responsibleGaming,
41
+ termsAndConditions: ctx.termsAndConditions,
42
+ responsibleGamingReminder: ctx.responsibleGamingReminder,
43
+ kyc: ctx.kyc,
44
+ registerBiometrics: ctx.registerBiometrics,
45
+ disclaimer: ctx.disclaimer,
46
+ })));
47
+ const signInMutation = useSignInMutation({
48
+ onSuccess: async () => {
49
+ step1Form.reset();
50
+ step2Form.reset();
51
+ context.setStep(1);
52
+ globalStore.signIn.setOpen(false);
53
+ const session = await getSession();
54
+ await unregisterFCMDevice({
55
+ type: ['IOS', 'ANDROID'],
56
+ }, {
57
+ headers: {
58
+ Authorization: `Bearer ${session.token}`,
59
+ },
60
+ });
61
+ invariant(session.status === 'authenticated');
62
+ if (Capacitor.isNativePlatform()) {
63
+ const pushToken = localStorage.getItem(LOCALSTORAGE_PUSH_NOTIFICATION_TOKEN_KEY);
64
+ if (pushToken) {
65
+ await registerFCMDevice({
66
+ type: Capacitor.getPlatform() === 'android' ? 'ANDROID' : 'IOS',
67
+ token: pushToken,
68
+ }, {
69
+ headers: {
70
+ Authorization: `Bearer ${session.token}`,
71
+ },
72
+ });
73
+ }
74
+ }
75
+ if (signInProps.shouldShowResponsibleGamingReminder) {
76
+ globalStore.responsibleGamingReminder.setOpen(true);
77
+ }
78
+ if (signInProps.shouldShowDisclaimer) {
79
+ globalStore.disclaimer.setOpen(true);
80
+ }
81
+ if (Capacitor.isNativePlatform()) {
82
+ if (!hasSavedBiometry()) {
83
+ globalStore.registerBiometrics.setOpen(true);
84
+ }
85
+ else {
86
+ const r = await createSingleUseToken({
87
+ headers: {
88
+ Authorization: `Bearer ${session.token}`,
89
+ },
90
+ });
91
+ if (r.token) {
92
+ const credentials = await getBiometricCredentials();
93
+ if (!credentials) {
94
+ console.error({ description: 'Biometric verification failed' });
95
+ deleteBiometricCredentials();
96
+ return;
97
+ }
98
+ const saved = await saveBiometricCredentials({
99
+ username: credentials.username,
100
+ password: r.token,
101
+ });
102
+ if (saved) {
103
+ console.info('Biometric credentials has been updated');
104
+ }
105
+ else {
106
+ console.warn('Failed to updated biometric credentials');
107
+ globalStore.signIn.setOpen(!globalStore.signIn.open);
108
+ }
109
+ }
110
+ else {
111
+ console.error('Failed to create token');
112
+ globalStore.signIn.setOpen(!globalStore.signIn.open);
113
+ }
114
+ }
115
+ }
116
+ },
117
+ onError: (err) => {
118
+ const errorMessage = err.name === 'Forbidden'
119
+ ? 'Please enter the correct verification code'
120
+ : err.message;
121
+ toaster.error({
122
+ title: 'Sign In Failed',
123
+ description: errorMessage,
124
+ });
125
+ },
126
+ });
127
+ const sendVerificationCodeMutation = useSendVerificationCodeMutation({
128
+ onSuccess: () => {
129
+ context.setStep(2);
130
+ cooldown.start();
131
+ },
132
+ onError: (err) => {
133
+ toaster.error({
134
+ title: 'Sign In Failed',
135
+ description: err.message,
136
+ });
137
+ },
138
+ });
139
+ const localeInfo = useLocaleInfo();
140
+ const mobileNumberParser = useMobileNumberParser();
141
+ const Step1Definition = z.object({
142
+ mobileNumber: z
143
+ .string()
144
+ .min(1, 'Mobile number is required')
145
+ .superRefine((v, ctx) => {
146
+ if (!mobileNumberParser.validate(v)) {
147
+ ctx.addIssue({
148
+ code: z.ZodIssueCode.custom,
149
+ message: 'Invalid mobile number',
150
+ });
151
+ }
152
+ }),
153
+ termsAccepted: z.boolean().superRefine((v, ctx) => {
154
+ if (!v) {
155
+ ctx.addIssue({
156
+ code: z.ZodIssueCode.custom,
157
+ message: 'You must accept the terms and conditions and the responsible gaming guidelines',
158
+ });
159
+ }
160
+ }),
161
+ });
162
+ const Step2Definition = z.object({
163
+ verificationCode: z.array(z.string()).superRefine((val, ctx) => {
164
+ if (val.length !== 6 || val.some((v) => v.length !== 1)) {
165
+ ctx.addIssue({
166
+ code: z.ZodIssueCode.custom,
167
+ message: 'Please enter your 6-digit verification code.',
168
+ });
169
+ }
170
+ }),
171
+ });
172
+ const step1Form = useForm({
173
+ resolver: zodResolver(Step1Definition),
174
+ defaultValues: {
175
+ mobileNumber: '',
176
+ termsAccepted: globalStore.responsibleGaming.accepted &&
177
+ globalStore.termsAndConditions.accepted
178
+ ? true
179
+ : false,
180
+ },
181
+ });
182
+ const step2Form = useForm({
183
+ resolver: zodResolver(Step2Definition),
184
+ defaultValues: {
185
+ verificationCode: Array.from({ length: 6 }).fill(''),
186
+ },
187
+ });
188
+ const cooldown = useCooldown({
189
+ max: 60,
190
+ duration: 1000 * 60,
191
+ });
192
+ const form2Ref = useRef(null);
193
+ const pinInputClass = twJoin('aspect-[9/12]', 'rounded', 'bg-black/40', 'text-center', 'shadow-[-4px_4px_12.6px_0px_rgba(0,0,0,0.15)_inset]', 'outline-none', 'border-none');
194
+ return (_jsxs(_Fragment, { children: [context.step === 1 && (_jsxs("form", { className: "mt-md", onSubmit: step1Form.handleSubmit(async (data) => {
195
+ sendVerificationCodeMutation.mutateAsync({
196
+ channel: 'SMS',
197
+ recipient: mobileNumberParser.format(data.mobileNumber),
198
+ strict: true,
199
+ });
200
+ }), children: [_jsxs(Field.Root, { invalid: !!step1Form.formState.errors.mobileNumber, children: [_jsx(Field.Label, { className: "text-xs", children: "Phone Number" }), _jsxs("div", { className: "relative flex h-10 gap-3", children: [_jsxs("div", { className: "flex h-full items-center gap-2 rounded-full bg-black/40 px-3.5 text-xs", children: [_jsx(localeInfo.country.flag, { className: "size-5" }), _jsx("span", { className: "text-text-placeholder", children: localeInfo.mobileNumber.areaCode })] }), _jsx(Field.Input, { className: "h-10 rounded-full border-none bg-black/40 text-xs", placeholder: "Enter Phone Number", ...step1Form.register('mobileNumber') })] }), _jsx(Field.ErrorText, { className: "text-[#ff2525b3] text-xs", children: step1Form.formState.errors.mobileNumber?.message })] }), _jsx(Button, { type: "submit", className: "mt-3xl h-10 rounded-full text-sm", disabled: step1Form.formState.isSubmitting, style: {
201
+ boxShadow: 'inset 0px -1px 2px 1px #fff7e1',
202
+ backgroundImage: 'linear-gradient(89deg, #c7802d -15.91%, #ffe585 28.75%, #ffeca6 49.46%, #c7802d 112.69%)',
203
+ }, children: "Login" }), _jsx(Controller, { control: step1Form.control, name: "termsAccepted", render: (o) => (_jsxs(Field.Root, { invalid: o.fieldState.invalid, className: "mt-xl", children: [_jsxs(Checkbox.Root, { checked: o.field.value, onCheckedChange: (details) => {
204
+ if (details.checked === 'indeterminate')
205
+ return;
206
+ o.field.onChange(details.checked);
207
+ globalStore.termsAndConditions.setAccepted(details.checked);
208
+ globalStore.responsibleGaming.setAccepted(details.checked);
209
+ }, children: [_jsx(Checkbox.Control, { className: "border-none bg-white", children: _jsx(Checkbox.Indicator, { asChild: true, className: "bg-white", children: _jsx(CheckIcon, {}) }) }), _jsxs(Checkbox.Label, { children: ["I confirm that I am at least 21 years old, not listed in the PAGCOR NDRP, not a GEL license holder, government employee, or member of the Armed Forces of the Philippines. I am not playing in a public space and agree to", _jsx("button", { type: "button", className: "font-semibold text-[#FFE595]", onClick: () => {
210
+ if (signInProps.termsAndConditionsUrl) {
211
+ globalStore.signIn.setOpen(false);
212
+ router.push(signInProps.termsAndConditionsUrl);
213
+ }
214
+ else {
215
+ globalStore.termsAndConditions.setOpen(true);
216
+ globalStore.termsAndConditions.setNext('SIGN_IN');
217
+ }
218
+ }, children: "Terms of Use" }), ' ', "and", ' ', _jsx("button", { type: "button", className: "font-semibold text-[#FFE595]", onClick: () => {
219
+ if (signInProps.termsAndConditionsUrl) {
220
+ globalStore.signIn.setOpen(false);
221
+ router.push(signInProps.termsAndConditionsUrl);
222
+ }
223
+ else {
224
+ globalStore.termsAndConditions.setOpen(true);
225
+ globalStore.termsAndConditions.setNext('SIGN_IN');
226
+ }
227
+ }, children: "Privacy Policy" }), ' ', ". Ineligible accounts will have their funds forfeited to the government."] }), _jsx(Checkbox.HiddenInput, {})] }), _jsx(Field.ErrorText, { className: "ml-6 text-[#ff2525b3] text-xs", children: o.fieldState.error?.message })] })) })] })), context.step === 2 && (_jsxs(_Fragment, { children: [_jsx(Image, { src: phoneIcon, alt: "phone icon", width: 300, height: 75, className: "mx-auto mt-sm h-12 w-12" }), _jsx("h2", { className: "mt-xl text-center text-2xl", children: "Check your Phone" }), _jsxs("p", { className: "mt-4 text-center text-[#999]", children: ["We\u2019ve sent a verification code to your mobile number", ' ', _jsx("span", { className: "font-semibold text-[#efc806]", children: mobileNumberParser.format(step1Form.getValues('mobileNumber')) }), ' ', "via text."] }), _jsxs("form", { ref: form2Ref, className: "mt-5", onSubmit: step2Form.handleSubmit(async ({ verificationCode }) => {
228
+ const { mobileNumber } = step1Form.getValues();
229
+ signInMutation.mutateAsync({
230
+ type: 'MOBILE_NUMBER',
231
+ mobileNumber: mobileNumberParser.format(mobileNumber),
232
+ verificationCode: verificationCode.join(''),
233
+ });
234
+ }), children: [_jsx(Controller, { name: "verificationCode", control: step2Form.control, render: (o) => (_jsxs(Field.Root, { invalid: o.fieldState.invalid, children: [_jsxs(PinInput.Root, { placeholder: "0", onKeyDown: (e) => {
235
+ if (e.key === 'Backspace') {
236
+ step2Form.reset();
237
+ }
238
+ }, value: o.field.value, onValueChange: (details) => {
239
+ o.field.onChange(details.value);
240
+ o.field.onBlur();
241
+ }, otp: true, onValueComplete: () => {
242
+ form2Ref.current?.requestSubmit();
243
+ }, blurOnComplete: true, readOnly: step2Form.formState.isSubmitting, type: "numeric", children: [_jsxs(PinInput.Control, { className: "grid-cols-[1fr_1fr_1fr_1fr_1fr_1fr] items-center gap-md", children: [_jsx(PinInput.Input, { index: 0, className: pinInputClass }), _jsx(PinInput.Input, { index: 1, className: pinInputClass }), _jsx(PinInput.Input, { index: 2, className: pinInputClass }), _jsx(PinInput.Input, { index: 3, className: pinInputClass }), _jsx(PinInput.Input, { index: 4, className: pinInputClass }), _jsx(PinInput.Input, { index: 5, className: pinInputClass })] }), _jsx(PinInput.HiddenInput, {})] }), _jsx(Field.ErrorText, { children: o.fieldState.error?.message })] })) }), _jsx(Button, { type: "submit", className: "mt-3xl h-10 rounded-full text-sm", disabled: step2Form.formState.isSubmitting || signInMutation.isPending, style: {
244
+ boxShadow: 'inset 0px -1px 2px 1px #fff7e1',
245
+ backgroundImage: 'linear-gradient(89deg, #c7802d -15.91%, #ffe585 28.75%, #ffeca6 49.46%, #c7802d 112.69%)',
246
+ }, children: "Verify" }), _jsxs("div", { className: "mt-3 flex w-full items-center justify-center gap-xs text-sm", children: [_jsx("span", { className: "text-text-secondary-700", children: "Didn't receive the code?" }), _jsx("button", { type: "button", className: "font-semibold text-[#efc806]", disabled: cooldown.cooling, onClick: async () => {
247
+ await sendVerificationCodeMutation.mutateAsync({
248
+ channel: 'SMS',
249
+ recipient: mobileNumberParser.format(step1Form.getValues('mobileNumber')),
250
+ });
251
+ cooldown.start();
252
+ }, children: cooldown.cooling
253
+ ? `Resend in ${cooldown.countdown}s`
254
+ : 'Resend' })] }), _jsxs("button", { type: "button", className: "mx-auto mt-3xl flex w-fit items-center gap-1 font-semibold text-sm text-text-tertiary-600", onClick: () => {
255
+ context.setStep(1);
256
+ step2Form.reset();
257
+ cooldown.stop();
258
+ }, children: [_jsx(ArrowLeftIcon, { className: "size-5" }), "Back"] })] })] }))] }));
259
+ }
@@ -0,0 +1 @@
1
+ export declare function NameAndPasswordSignIn(): import("react/jsx-runtime").JSX.Element;