@opexa/portal-components 0.0.967 → 0.0.969
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/utils/mocks.d.ts +1 -1
- package/dist/client/hooks/useCamera.js +13 -7
- package/dist/components/AccountSecurity/AccountSecurity.js +1 -1
- package/dist/components/UpdateMobileNumber/UpdateMobileNumber.d.ts +3 -0
- package/dist/components/UpdateMobileNumber/UpdateMobileNumber.js +141 -0
- package/dist/components/UpdateMobileNumber/index.d.ts +1 -0
- package/dist/components/UpdateMobileNumber/index.js +1 -0
- package/dist/components/shared/SelfieImageField/useSelfieImageField.js +103 -56
- package/dist/lib/components/UpdateMobileNumber/UpdateMobileNumber.d.ts +1 -0
- package/dist/lib/components/{UpdateMobilePhoneNumber/UpdateMobilePhoneNumber.js → UpdateMobileNumber/UpdateMobileNumber.js} +5 -3
- package/dist/lib/components/UpdateMobileNumber/index.d.ts +1 -0
- package/dist/lib/components/UpdateMobileNumber/index.js +1 -0
- package/dist/schemas/forgotPasswordSchema.d.ts +8 -8
- package/dist/ui/AlertDialog/AlertDialog.d.ts +220 -220
- package/dist/ui/AlertDialog/alertDialog.recipe.d.ts +20 -20
- package/dist/ui/Carousel/Carousel.d.ts +45 -45
- package/dist/ui/Carousel/carousel.recipe.d.ts +5 -5
- package/dist/ui/Clipboard/Clipboard.d.ts +18 -18
- package/dist/ui/Clipboard/clipboard.recipe.d.ts +3 -3
- package/dist/ui/Collapsible/Collapsible.d.ts +20 -20
- package/dist/ui/Collapsible/collapsible.recipe.d.ts +5 -5
- package/dist/ui/Combobox/Combobox.d.ts +42 -42
- package/dist/ui/Combobox/combobox.recipe.d.ts +3 -3
- package/dist/ui/DatePicker/DatePicker.d.ts +72 -72
- package/dist/ui/DatePicker/datePicker.recipe.d.ts +3 -3
- package/dist/ui/Dialog/Dialog.d.ts +33 -33
- package/dist/ui/Dialog/dialog.recipe.d.ts +3 -3
- package/dist/ui/Drawer/Drawer.d.ts +33 -33
- package/dist/ui/Drawer/drawer.recipe.d.ts +3 -3
- package/dist/ui/Field/Field.d.ts +21 -21
- package/dist/ui/Field/field.recipe.d.ts +3 -3
- package/dist/ui/Menu/Menu.d.ts +90 -90
- package/dist/ui/Menu/menu.recipe.d.ts +5 -5
- package/dist/ui/Popover/Popover.d.ts +154 -154
- package/dist/ui/Popover/popover.recipe.d.ts +14 -14
- package/dist/ui/SegmentGroup/SegmentGroup.d.ts +18 -18
- package/dist/ui/SegmentGroup/segmentGroup.recipe.d.ts +3 -3
- package/dist/ui/Select/Select.d.ts +45 -45
- package/dist/ui/Select/select.recipe.d.ts +3 -3
- package/dist/ui/Table/Table.d.ts +21 -21
- package/dist/ui/Table/table.anatomy.d.ts +1 -1
- package/dist/ui/Table/table.recipe.d.ts +3 -3
- package/dist/ui/Tabs/Tabs.d.ts +15 -15
- package/dist/ui/Tabs/tabs.recipe.d.ts +3 -3
- package/package.json +1 -1
- package/dist/lib/components/UpdateMobilePhoneNumber/UpdateMobilePhoneNumber.d.ts +0 -1
- package/dist/lib/components/UpdateMobilePhoneNumber/index.d.ts +0 -1
- package/dist/lib/components/UpdateMobilePhoneNumber/index.js +0 -1
|
@@ -165,7 +165,7 @@ export declare function createMockSignOutMutation(): {
|
|
|
165
165
|
*/
|
|
166
166
|
export declare function createMockMemberVerificationQuery(status?: 'VERIFIED' | 'PENDING' | 'REJECTED' | 'MISSING' | 'APPROVED', isLoading?: boolean): {
|
|
167
167
|
data: {
|
|
168
|
-
status: "
|
|
168
|
+
status: "VERIFIED" | "PENDING" | "REJECTED" | "MISSING" | "APPROVED";
|
|
169
169
|
};
|
|
170
170
|
isLoading: boolean;
|
|
171
171
|
isError: boolean;
|
|
@@ -110,16 +110,22 @@ export function useCamera(options = {}) {
|
|
|
110
110
|
return null;
|
|
111
111
|
}
|
|
112
112
|
}, [setData, setError, setSnapping]);
|
|
113
|
-
const close = useCallback(() => {
|
|
113
|
+
const close = useCallback(async () => {
|
|
114
114
|
setData(null);
|
|
115
115
|
setError(null);
|
|
116
116
|
setLoading(false);
|
|
117
117
|
setSnapping(false);
|
|
118
|
-
|
|
119
|
-
streamRef.current
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
if (streamRef.current) {
|
|
119
|
+
for (const track of streamRef.current.getTracks()) {
|
|
120
|
+
track.stop();
|
|
121
|
+
}
|
|
122
|
+
streamRef.current = null;
|
|
123
|
+
}
|
|
124
|
+
if (videoRef.current) {
|
|
125
|
+
videoRef.current.srcObject = null;
|
|
126
|
+
videoRef.current.pause();
|
|
127
|
+
}
|
|
128
|
+
await sleep(100);
|
|
123
129
|
}, []);
|
|
124
130
|
const snap = useCallback(async () => {
|
|
125
131
|
const video = videoRef.current;
|
|
@@ -162,7 +168,7 @@ export function useCamera(options = {}) {
|
|
|
162
168
|
const reopen = useCallback(async () => {
|
|
163
169
|
setSnapping(false);
|
|
164
170
|
setLoading(true);
|
|
165
|
-
close();
|
|
171
|
+
await close();
|
|
166
172
|
await sleep();
|
|
167
173
|
await open();
|
|
168
174
|
}, [close, open]);
|
|
@@ -160,7 +160,7 @@ function TransactionPassword() {
|
|
|
160
160
|
confirmPassword: '',
|
|
161
161
|
},
|
|
162
162
|
});
|
|
163
|
-
return (_jsxs("div", { children: [_jsxs("div", { className: "flex items-start gap-8", children: [_jsxs("div", { className: "grow", children: [_jsx("h2", { className: "font-semibold text-sm text-text-secondary-700", children: "
|
|
163
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: "flex items-start gap-8", children: [_jsxs("div", { className: "grow", children: [_jsx("h2", { className: "font-semibold text-sm text-text-secondary-700", children: "Withdrawal password" }), _jsx("p", { className: "text-sm text-text-tertiary-600", children: "The withdrawal password secures and confirms your wallet withdrawals." })] }), profileCompletion?.transactionPassword ? (_jsx(ark.svg, { asChild: true, className: "size-6 text-text-success-primary", children: _jsx(CheckVerified02Icon, {}) })) : (_jsxs("div", { className: "flex items-center gap-1 rounded-sm border border-[#93370d] bg-[#4e1d09] px-sm py-xs", children: [_jsx(AlertCircleIcon, { className: "h-5 w-5 text-[#FEC84B]" }), _jsx("span", { className: "m-0 text-nowrap text-[#FEC84B] text-xs", children: "Not Set" })] }))] }), !profileCompletion?.transactionPassword && (_jsx(AlertWarning, { title: "Please set your withdrawal password. This is required when making withdrawals and helps secure your account.", className: "my-3" })), _jsxs("form", { className: "mt-5 rounded-xl border border-border-secondary bg-bg-primary-alt shadow-xs", onSubmit: form.handleSubmit((data) => {
|
|
164
164
|
updateAccountMutation.mutate({
|
|
165
165
|
transactionPassword: data.password,
|
|
166
166
|
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
4
|
+
import Image from 'next/image';
|
|
5
|
+
import { useRef, useState } from 'react';
|
|
6
|
+
import { Controller, useForm } from 'react-hook-form';
|
|
7
|
+
import z from 'zod';
|
|
8
|
+
import { useAccountQuery } from '../../client/hooks/useAccountQuery.js';
|
|
9
|
+
import { useCooldown } from '../../client/hooks/useCooldown.js';
|
|
10
|
+
import { useLocaleInfo } from '../../client/hooks/useLocaleInfo.js';
|
|
11
|
+
import { useMobileNumberParser } from '../../client/hooks/useMobileNumberParser.js';
|
|
12
|
+
import { useSendVerificationCodeMutation } from '../../client/hooks/useSendVerificationCodeMutation.js';
|
|
13
|
+
import { useUpdateMobileNumber } from '../../client/hooks/useUpdateMobileNumber.js';
|
|
14
|
+
import { toaster } from '../../client/utils/toaster.js';
|
|
15
|
+
import { ArrowLeftIcon } from '../../icons/ArrowLeftIcon.js';
|
|
16
|
+
import inplayLogo from '../../images/inplay-logo.png';
|
|
17
|
+
import lightBg from '../../images/light-bg.png';
|
|
18
|
+
import { Button } from '../../ui/Button/index.js';
|
|
19
|
+
import { Dialog } from '../../ui/Dialog/index.js';
|
|
20
|
+
import { Field } from '../../ui/Field/index.js';
|
|
21
|
+
import { PinInput } from '../../ui/PinInput/index.js';
|
|
22
|
+
import { Portal } from '../../ui/Portal/index.js';
|
|
23
|
+
export function UpdateMobileNumber({ onClose }) {
|
|
24
|
+
const accountQuery = useAccountQuery();
|
|
25
|
+
const account = accountQuery.data;
|
|
26
|
+
const isAccountLoading = accountQuery.isLoading;
|
|
27
|
+
const hasMobileNumber = !!account?.mobileNumber;
|
|
28
|
+
const isDialogOpen = !isAccountLoading && !!account && !hasMobileNumber;
|
|
29
|
+
const [step, setStep] = useState(1);
|
|
30
|
+
const sendVerificationCodeMutation = useSendVerificationCodeMutation({
|
|
31
|
+
onSuccess: () => {
|
|
32
|
+
setStep(2);
|
|
33
|
+
cooldown.start();
|
|
34
|
+
},
|
|
35
|
+
onError: (err) => {
|
|
36
|
+
toaster.error({
|
|
37
|
+
title: 'Sign In Failed',
|
|
38
|
+
description: err.message,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
const updateMobileNumberMutation = useUpdateMobileNumber({
|
|
43
|
+
onSuccess: async () => {
|
|
44
|
+
step1Form.reset();
|
|
45
|
+
step2Form.reset();
|
|
46
|
+
setStep(1);
|
|
47
|
+
toaster.success({
|
|
48
|
+
title: 'Verification Successful',
|
|
49
|
+
description: 'Your mobile number has been verified.',
|
|
50
|
+
});
|
|
51
|
+
onClose?.();
|
|
52
|
+
},
|
|
53
|
+
onError: (err) => {
|
|
54
|
+
const errorMessage = err.message === 'Internal Server Error'
|
|
55
|
+
? `mobile number ${mobileNumberParser.format(step1Form.getValues('mobileNumber'))} is not available`
|
|
56
|
+
: err.message;
|
|
57
|
+
toaster.error({
|
|
58
|
+
title: 'Sign In Failed',
|
|
59
|
+
description: errorMessage,
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const localeInfo = useLocaleInfo();
|
|
64
|
+
const mobileNumberParser = useMobileNumberParser();
|
|
65
|
+
const Step1Definition = z.object({
|
|
66
|
+
mobileNumber: z
|
|
67
|
+
.string()
|
|
68
|
+
.min(1, 'Mobile number is required')
|
|
69
|
+
.superRefine((v, ctx) => {
|
|
70
|
+
if (!mobileNumberParser.validate(v)) {
|
|
71
|
+
ctx.addIssue({
|
|
72
|
+
code: z.ZodIssueCode.custom,
|
|
73
|
+
message: 'Invalid mobile number',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
const Step2Definition = z.object({
|
|
79
|
+
verificationCode: z.array(z.string()).superRefine((val, ctx) => {
|
|
80
|
+
if (val.length !== 6 || val.some((v) => v.length !== 1)) {
|
|
81
|
+
ctx.addIssue({
|
|
82
|
+
code: z.ZodIssueCode.custom,
|
|
83
|
+
message: 'Please enter your 6-digit verification code.',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
const step1Form = useForm({
|
|
89
|
+
resolver: zodResolver(Step1Definition),
|
|
90
|
+
defaultValues: {
|
|
91
|
+
mobileNumber: '',
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
const step2Form = useForm({
|
|
95
|
+
resolver: zodResolver(Step2Definition),
|
|
96
|
+
defaultValues: {
|
|
97
|
+
verificationCode: Array.from({ length: 6 }).fill(''),
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const cooldown = useCooldown({
|
|
101
|
+
max: 60,
|
|
102
|
+
duration: 1000 * 60,
|
|
103
|
+
});
|
|
104
|
+
const formRef = useRef(null);
|
|
105
|
+
return (_jsx(Dialog.Root, { open: isDialogOpen, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { className: "flex items-center", children: _jsxs(Dialog.Content, { className: "flex w-[375px] flex-col items-center space-y-4 rounded-xl bg-[#111827] p-6 text-center", style: {
|
|
106
|
+
backgroundImage: `url(${lightBg.src})`,
|
|
107
|
+
}, children: [_jsx(Image, { src: inplayLogo, alt: "inplay logo", width: 82, height: 34, className: "h-auto w-[82px]" }), _jsxs("div", { children: [step === 1 && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "font-bold text-sm", children: ["Get ", _jsx("span", { className: "text-[#F05127]", children: "\u20B150 Bonus" }), " when you verify your account and play."] }), _jsxs("form", { className: "mt-3xl", onSubmit: step1Form.handleSubmit(async (data) => {
|
|
108
|
+
sendVerificationCodeMutation.mutateAsync({
|
|
109
|
+
channel: 'SMS',
|
|
110
|
+
recipient: mobileNumberParser.format(data.mobileNumber),
|
|
111
|
+
});
|
|
112
|
+
}), children: [_jsxs(Field.Root, { invalid: !!step1Form.formState.errors.mobileNumber, className: "text-left", children: [_jsx(Field.Label, { children: "Mobile Number" }), _jsxs("div", { className: "relative", children: [_jsx("div", { className: "-translate-y-1/2 absolute top-1/2 left-3.5 flex shrink-0 items-center gap-md", children: _jsx("span", { className: "text-text-placeholder", children: localeInfo.mobileNumber.areaCode }) }), _jsx(Field.Input, { style: {
|
|
113
|
+
paddingLeft: `calc(1.25rem + ${localeInfo.mobileNumber.areaCode.length}ch)`,
|
|
114
|
+
}, ...step1Form.register('mobileNumber') })] }), _jsx(Field.ErrorText, { children: step1Form.formState.errors.mobileNumber?.message })] }), _jsx(Button, { type: "submit", className: "mt-3xl", disabled: step1Form.formState.isSubmitting, children: "Send Code" })] })] })), step === 2 && (_jsxs(_Fragment, { children: [_jsx("h2", { className: "mt-xl text-center font-semibold text-lg", children: "Check your Phone" }), _jsxs("p", { className: "mt-xs text-center text-sm text-text-secondary-700", children: ["We\u2019ve sent a verification code to your mobile number", ' ', _jsx("span", { className: "font-semibold text-[#F05127]", children: mobileNumberParser.format(step1Form.getValues('mobileNumber')) }), ' ', "via text"] }), _jsxs("form", { ref: formRef, className: "mt-5", onSubmit: step2Form.handleSubmit(async ({ verificationCode }) => {
|
|
115
|
+
updateMobileNumberMutation.mutateAsync({
|
|
116
|
+
mobileNumber: mobileNumberParser.format(step1Form.getValues('mobileNumber')),
|
|
117
|
+
verificationCode: verificationCode.join(''),
|
|
118
|
+
});
|
|
119
|
+
}), 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) => {
|
|
120
|
+
if (e.key === 'Backspace') {
|
|
121
|
+
step2Form.reset();
|
|
122
|
+
}
|
|
123
|
+
}, value: o.field.value, onValueChange: (details) => {
|
|
124
|
+
o.field.onChange(details.value);
|
|
125
|
+
o.field.onBlur();
|
|
126
|
+
}, otp: true, onValueComplete: () => {
|
|
127
|
+
formRef.current?.requestSubmit();
|
|
128
|
+
}, blurOnComplete: true, readOnly: step2Form.formState.isSubmitting, type: "numeric", children: [_jsxs(PinInput.Control, { className: "grid-cols-[1fr_1fr_1fr_auto_1fr_1fr_1fr] items-center gap-md", children: [_jsx(PinInput.Input, { index: 0 }), _jsx(PinInput.Input, { index: 1 }), _jsx(PinInput.Input, { index: 2 }), _jsx("span", { className: "font-medium text-2xl text-text-placeholder-subtle", children: "\u2013" }), _jsx(PinInput.Input, { index: 3 }), _jsx(PinInput.Input, { index: 4 }), _jsx(PinInput.Input, { index: 5 })] }), _jsx(PinInput.HiddenInput, {})] }), _jsx(Field.ErrorText, { children: o.fieldState.error?.message })] })) }), _jsx(Button, { type: "submit", className: "mt-4xl", disabled: step2Form.formState.isSubmitting, children: "Verify" }), _jsxs("div", { className: "mt-4 flex w-full items-center justify-center gap-xs text-xs", children: [_jsx("span", { className: "text-[#9CA3AF]", children: "Didn't receive the code?" }), _jsx("button", { type: "button", className: "font-semibold text-[#C084FC]", disabled: cooldown.cooling, onClick: async () => {
|
|
129
|
+
await sendVerificationCodeMutation.mutateAsync({
|
|
130
|
+
channel: 'SMS',
|
|
131
|
+
recipient: mobileNumberParser.format(step1Form.getValues('mobileNumber')),
|
|
132
|
+
});
|
|
133
|
+
cooldown.start();
|
|
134
|
+
}, children: cooldown.cooling
|
|
135
|
+
? `Resend in ${cooldown.countdown}s`
|
|
136
|
+
: 'Resend' })] }), _jsx("button", { type: "button", className: "absolute top-0 left-6 mx-auto mt-3xl flex h-8 w-8 items-center gap-1 rounded-full bg-[#1f2638] font-semibold text-sm text-text-tertiary-600", onClick: () => {
|
|
137
|
+
setStep(1);
|
|
138
|
+
step2Form.reset();
|
|
139
|
+
cooldown.stop();
|
|
140
|
+
}, children: _jsx(ArrowLeftIcon, { className: "mx-auto size-5" }) })] })] }))] })] }) })] }) }));
|
|
141
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './UpdateMobileNumber';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './UpdateMobileNumber.js';
|
|
@@ -111,6 +111,10 @@ export function useSelfieImageField(props) {
|
|
|
111
111
|
if (open) {
|
|
112
112
|
camera.open();
|
|
113
113
|
}
|
|
114
|
+
else {
|
|
115
|
+
setFaceFound(false);
|
|
116
|
+
camera.close();
|
|
117
|
+
}
|
|
114
118
|
},
|
|
115
119
|
});
|
|
116
120
|
const [faceFound, setFaceFound] = useState(false);
|
|
@@ -120,7 +124,7 @@ export function useSelfieImageField(props) {
|
|
|
120
124
|
}
|
|
121
125
|
setFaceFound(await validateFaceFromVideo(camera.videoRef.current, guideRef.current));
|
|
122
126
|
}, disclosure.open && !camera.data && !camera.error && !camera.loading
|
|
123
|
-
?
|
|
127
|
+
? 300
|
|
124
128
|
: null);
|
|
125
129
|
return {
|
|
126
130
|
field,
|
|
@@ -136,48 +140,85 @@ export function useSelfieImageField(props) {
|
|
|
136
140
|
faceFound,
|
|
137
141
|
};
|
|
138
142
|
}
|
|
139
|
-
let __image_face_detector__;
|
|
140
|
-
let __video_face_detector__;
|
|
141
|
-
let __vision__;
|
|
143
|
+
let __image_face_detector__ = null;
|
|
144
|
+
let __video_face_detector__ = null;
|
|
145
|
+
let __vision__ = null;
|
|
146
|
+
let __image_face_detector_promise__ = null;
|
|
147
|
+
let __video_face_detector_promise__ = null;
|
|
148
|
+
let __vision_promise__ = null;
|
|
149
|
+
async function getVision() {
|
|
150
|
+
if (__vision__)
|
|
151
|
+
return __vision__;
|
|
152
|
+
if (__vision_promise__)
|
|
153
|
+
return __vision_promise__;
|
|
154
|
+
__vision_promise__ = (async () => {
|
|
155
|
+
try {
|
|
156
|
+
const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm');
|
|
157
|
+
__vision__ = vision;
|
|
158
|
+
return vision;
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
__vision_promise__ = null;
|
|
162
|
+
throw e;
|
|
163
|
+
}
|
|
164
|
+
})();
|
|
165
|
+
return __vision_promise__;
|
|
166
|
+
}
|
|
142
167
|
async function getImageFaceDetector() {
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
168
|
+
if (__image_face_detector__)
|
|
169
|
+
return __image_face_detector__;
|
|
170
|
+
if (__image_face_detector_promise__)
|
|
171
|
+
return __image_face_detector_promise__;
|
|
172
|
+
__image_face_detector_promise__ = (async () => {
|
|
173
|
+
try {
|
|
174
|
+
const vision = await getVision();
|
|
175
|
+
const detector = await FaceDetector.createFromOptions(vision, {
|
|
176
|
+
runningMode: 'IMAGE',
|
|
177
|
+
minDetectionConfidence: 0.5,
|
|
178
|
+
baseOptions: {
|
|
179
|
+
delegate: 'GPU',
|
|
180
|
+
modelAssetPath: 'https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite',
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
__image_face_detector__ = detector;
|
|
184
|
+
return detector;
|
|
146
185
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
},
|
|
154
|
-
});
|
|
155
|
-
__image_face_detector__ = detector;
|
|
156
|
-
return detector;
|
|
157
|
-
}
|
|
158
|
-
return __image_face_detector__;
|
|
186
|
+
catch (e) {
|
|
187
|
+
__image_face_detector_promise__ = null;
|
|
188
|
+
throw e;
|
|
189
|
+
}
|
|
190
|
+
})();
|
|
191
|
+
return __image_face_detector_promise__;
|
|
159
192
|
}
|
|
160
193
|
async function getVideoFaceDetector() {
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
|
|
194
|
+
if (__video_face_detector__)
|
|
195
|
+
return __video_face_detector__;
|
|
196
|
+
if (__video_face_detector_promise__)
|
|
197
|
+
return __video_face_detector_promise__;
|
|
198
|
+
__video_face_detector_promise__ = (async () => {
|
|
199
|
+
try {
|
|
200
|
+
const vision = await getVision();
|
|
201
|
+
const detector = await FaceDetector.createFromOptions(vision, {
|
|
202
|
+
runningMode: 'VIDEO',
|
|
203
|
+
minDetectionConfidence: 0.5,
|
|
204
|
+
baseOptions: {
|
|
205
|
+
delegate: 'GPU',
|
|
206
|
+
modelAssetPath: 'https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite',
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
__video_face_detector__ = detector;
|
|
210
|
+
return detector;
|
|
164
211
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
__video_face_detector__ = detector;
|
|
174
|
-
return detector;
|
|
175
|
-
}
|
|
176
|
-
return __video_face_detector__;
|
|
212
|
+
catch (e) {
|
|
213
|
+
__video_face_detector_promise__ = null;
|
|
214
|
+
throw e;
|
|
215
|
+
}
|
|
216
|
+
})();
|
|
217
|
+
return __video_face_detector_promise__;
|
|
177
218
|
}
|
|
178
219
|
async function validateFaceFromImage(image) {
|
|
179
|
-
const detector = await getImageFaceDetector();
|
|
180
220
|
try {
|
|
221
|
+
const detector = await getImageFaceDetector();
|
|
181
222
|
const result = detector.detect(image);
|
|
182
223
|
return result.detections.length > 0;
|
|
183
224
|
}
|
|
@@ -189,26 +230,32 @@ async function validateFaceFromImage(image) {
|
|
|
189
230
|
async function validateFaceFromVideo(video, guide) {
|
|
190
231
|
if (video.readyState < 2)
|
|
191
232
|
return false;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
233
|
+
try {
|
|
234
|
+
const detector = await getVideoFaceDetector();
|
|
235
|
+
const result = detector.detectForVideo(video, performance.now());
|
|
236
|
+
const detection = result.detections.at(0);
|
|
237
|
+
if (!detection)
|
|
238
|
+
return false;
|
|
239
|
+
const videoRect = video.getBoundingClientRect();
|
|
240
|
+
const guideRect = guide.getBoundingClientRect();
|
|
241
|
+
if (!detection.boundingBox)
|
|
242
|
+
return false;
|
|
243
|
+
const faceLeft = videoRect.left +
|
|
244
|
+
(detection.boundingBox.originX / video.videoWidth) * videoRect.width;
|
|
245
|
+
const faceTop = videoRect.top +
|
|
246
|
+
(detection.boundingBox.originY / video.videoHeight) * videoRect.height;
|
|
247
|
+
const faceRight = faceLeft +
|
|
248
|
+
(detection.boundingBox.width / video.videoWidth) * videoRect.width;
|
|
249
|
+
const faceBottom = faceTop +
|
|
250
|
+
(detection.boundingBox.height / video.videoHeight) * videoRect.height;
|
|
251
|
+
const isInside = faceLeft >= guideRect.left &&
|
|
252
|
+
faceTop >= guideRect.top &&
|
|
253
|
+
faceRight <= guideRect.right &&
|
|
254
|
+
faceBottom <= guideRect.bottom;
|
|
255
|
+
return isInside;
|
|
256
|
+
}
|
|
257
|
+
catch (e) {
|
|
258
|
+
console.error(e);
|
|
200
259
|
return false;
|
|
201
|
-
|
|
202
|
-
(detection.boundingBox.originX / video.videoWidth) * videoRect.width;
|
|
203
|
-
const faceTop = videoRect.top +
|
|
204
|
-
(detection.boundingBox.originY / video.videoHeight) * videoRect.height;
|
|
205
|
-
const faceRight = faceLeft +
|
|
206
|
-
(detection.boundingBox.width / video.videoWidth) * videoRect.width;
|
|
207
|
-
const faceBottom = faceTop +
|
|
208
|
-
(detection.boundingBox.height / video.videoHeight) * videoRect.height;
|
|
209
|
-
const isInside = faceLeft >= guideRect.left &&
|
|
210
|
-
faceTop >= guideRect.top &&
|
|
211
|
-
faceRight <= guideRect.right &&
|
|
212
|
-
faceBottom <= guideRect.bottom;
|
|
213
|
-
return isInside;
|
|
260
|
+
}
|
|
214
261
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function UpdateMobileNumber(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -20,12 +20,13 @@ import { Dialog } from '../../ui/Dialog/index.js';
|
|
|
20
20
|
import { Field } from '../../ui/Field/index.js';
|
|
21
21
|
import { PinInput } from '../../ui/PinInput/index.js';
|
|
22
22
|
import { Portal } from '../../ui/Portal/index.js';
|
|
23
|
-
export function
|
|
23
|
+
export function UpdateMobileNumber() {
|
|
24
24
|
const accountQuery = useAccountQuery();
|
|
25
25
|
const account = accountQuery.data;
|
|
26
26
|
const isAccountLoading = accountQuery.isLoading;
|
|
27
27
|
const hasMobileNumber = !!account?.mobileNumber;
|
|
28
28
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
29
|
+
console.log('isDialogOpen', isDialogOpen);
|
|
29
30
|
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to open the dialog when the account data loads, not on every hasMobileNumber change
|
|
30
31
|
useEffect(() => {
|
|
31
32
|
if (!isAccountLoading && !!account && !hasMobileNumber) {
|
|
@@ -58,9 +59,11 @@ export function UpdateMobilePhoneNumber() {
|
|
|
58
59
|
description: 'Your mobile number has been verified.',
|
|
59
60
|
});
|
|
60
61
|
setIsDialogOpen(false);
|
|
61
|
-
console.log('
|
|
62
|
+
console.log('close dialog');
|
|
62
63
|
},
|
|
63
64
|
onError: (err) => {
|
|
65
|
+
console.log('err', err);
|
|
66
|
+
console.log('error updating mobile number');
|
|
64
67
|
const errorMessage = err.message === 'Internal Server Error'
|
|
65
68
|
? `mobile number ${mobileNumberParser.format(step1Form.getValues('mobileNumber'))} is not available`
|
|
66
69
|
: err.message;
|
|
@@ -68,7 +71,6 @@ export function UpdateMobilePhoneNumber() {
|
|
|
68
71
|
title: 'Sign In Failed',
|
|
69
72
|
description: errorMessage,
|
|
70
73
|
});
|
|
71
|
-
console.log('error updating mobile number');
|
|
72
74
|
},
|
|
73
75
|
});
|
|
74
76
|
const localeInfo = useLocaleInfo();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './UpdateMobileNumber';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './UpdateMobileNumber.js';
|
|
@@ -8,24 +8,24 @@ export declare const createForgotPasswordSchema: (mobileNumberParser: MobileNumb
|
|
|
8
8
|
mobileNumber: z.ZodEffects<z.ZodString, string, string>;
|
|
9
9
|
verificationCode: z.ZodEffects<z.ZodString, string, string>;
|
|
10
10
|
}, "strip", z.ZodTypeAny, {
|
|
11
|
-
password: string;
|
|
12
|
-
verificationCode: string;
|
|
13
11
|
mobileNumber: string;
|
|
12
|
+
verificationCode: string;
|
|
13
|
+
password: string;
|
|
14
14
|
confirmPassword: string;
|
|
15
15
|
}, {
|
|
16
|
-
password: string;
|
|
17
|
-
verificationCode: string;
|
|
18
16
|
mobileNumber: string;
|
|
17
|
+
verificationCode: string;
|
|
18
|
+
password: string;
|
|
19
19
|
confirmPassword: string;
|
|
20
20
|
}>, {
|
|
21
|
-
password: string;
|
|
22
|
-
verificationCode: string;
|
|
23
21
|
mobileNumber: string;
|
|
22
|
+
verificationCode: string;
|
|
23
|
+
password: string;
|
|
24
24
|
confirmPassword: string;
|
|
25
25
|
}, {
|
|
26
|
-
password: string;
|
|
27
|
-
verificationCode: string;
|
|
28
26
|
mobileNumber: string;
|
|
27
|
+
verificationCode: string;
|
|
28
|
+
password: string;
|
|
29
29
|
confirmPassword: string;
|
|
30
30
|
}>;
|
|
31
31
|
export type ForgotPasswordSchema = z.infer<ReturnType<typeof createForgotPasswordSchema>>;
|