@opexa/portal-components 0.0.258 → 0.0.260
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/hooks/useCamera.d.ts +11 -16
- package/dist/client/hooks/useCamera.js +29 -57
- package/dist/client/hooks/useUploadFileMutation.d.ts +4 -0
- package/dist/client/hooks/useUploadFileMutation.js +24 -0
- package/dist/client/hooks/useUploadImageFileMutation.d.ts +2 -2
- package/dist/client/hooks/useUploadImageFileMutation.js +2 -2
- package/dist/client/hooks/useUploadPrivateImageFileMutation.d.ts +4 -0
- package/dist/client/hooks/useUploadPrivateImageFileMutation.js +24 -0
- package/dist/components/Disclaimer/DisclaimerV2.js +2 -2
- package/dist/components/Disclaimer/TermsOfUse.js +0 -4
- package/dist/components/Search/Search.lazy.js +6 -2
- package/dist/components/SignIn/MobileNumberSignIn.js +1 -0
- package/dist/components/SignIn/utils.d.ts +1 -0
- package/dist/components/SignIn/utils.js +4 -0
- package/dist/components/shared/IdFrontImageField/IdFrontImageField.client.d.ts +15 -0
- package/dist/components/shared/IdFrontImageField/IdFrontImageField.client.js +140 -0
- package/dist/components/shared/IdFrontImageField/IdFrontImageField.d.ts +2 -0
- package/dist/components/shared/IdFrontImageField/IdFrontImageField.js +11 -0
- package/dist/components/shared/IdFrontImageField/IdFrontImageFieldContext.d.ts +6 -0
- package/dist/components/shared/IdFrontImageField/IdFrontImageFieldContext.js +2 -0
- package/dist/components/shared/IdFrontImageField/index.d.ts +1 -0
- package/dist/components/shared/IdFrontImageField/index.js +1 -0
- package/dist/components/shared/IdFrontImageField/useIdFrontImageField.d.ts +22 -0
- package/dist/components/shared/IdFrontImageField/useIdFrontImageField.js +111 -0
- package/dist/components/shared/SelfieImageField/SelfieImageField.client.d.ts +15 -0
- package/dist/components/shared/SelfieImageField/SelfieImageField.client.js +170 -0
- package/dist/components/shared/SelfieImageField/SelfieImageField.d.ts +2 -0
- package/dist/components/shared/SelfieImageField/SelfieImageField.js +11 -0
- package/dist/components/shared/SelfieImageField/SelfieImageFieldContext.d.ts +6 -0
- package/dist/components/shared/SelfieImageField/SelfieImageFieldContext.js +2 -0
- package/dist/components/shared/SelfieImageField/index.d.ts +1 -0
- package/dist/components/shared/SelfieImageField/index.js +1 -0
- package/dist/components/shared/SelfieImageField/useSelfieImageField.d.ts +23 -0
- package/dist/components/shared/SelfieImageField/useSelfieImageField.js +208 -0
- package/dist/handlers/deleteSession.d.ts +9 -0
- package/dist/handlers/deleteSession.js +19 -0
- package/dist/handlers/getHealthCheck.d.ts +9 -0
- package/dist/handlers/getHealthCheck.js +16 -0
- package/dist/handlers/getSession.d.ts +10 -0
- package/dist/handlers/getSession.js +63 -0
- package/dist/handlers/index.d.ts +40 -0
- package/dist/handlers/index.js +56 -0
- package/dist/handlers/patchSession.d.ts +10 -0
- package/dist/handlers/patchSession.js +26 -0
- package/dist/handlers/postAuthenticate.d.ts +10 -0
- package/dist/handlers/postAuthenticate.js +51 -0
- package/dist/handlers/postSession.d.ts +17 -0
- package/dist/handlers/postSession.js +78 -0
- package/dist/handlers/postTransformIdFrontImage.d.ts +3 -0
- package/dist/handlers/postTransformIdFrontImage.js +67 -0
- package/dist/handlers/postTransformSelfieImage.d.ts +3 -0
- package/dist/handlers/postTransformSelfieImage.js +71 -0
- package/dist/services/file.d.ts +17 -12
- package/dist/services/file.js +21 -1
- package/dist/services/queries.d.ts +2 -0
- package/dist/services/queries.js +36 -0
- package/dist/utils/mutationKeys.d.ts +2 -0
- package/dist/utils/mutationKeys.js +8 -0
- package/package.json +4 -3
|
@@ -9,22 +9,10 @@ export interface CameraData {
|
|
|
9
9
|
file: File;
|
|
10
10
|
image: HTMLImageElement;
|
|
11
11
|
}
|
|
12
|
-
export interface CameraCropPoints {
|
|
13
|
-
x: number;
|
|
14
|
-
y: number;
|
|
15
|
-
width: number;
|
|
16
|
-
height: number;
|
|
17
|
-
}
|
|
18
|
-
export type ScaleFactor = 1 | 1.15 | 1.25 | 1.5 | 1.75 | 2 | 2.15 | 2.25 | 2.5 | 2.75 | 3;
|
|
19
|
-
export interface CameraSnapOptions {
|
|
20
|
-
crop?: CameraCropPoints;
|
|
21
|
-
/** @default 2 */
|
|
22
|
-
scale?: ScaleFactor;
|
|
23
|
-
}
|
|
24
12
|
export interface UseCameraReturn<T extends string = never> {
|
|
25
13
|
open(): Promise<void>;
|
|
26
14
|
close(): Promise<void>;
|
|
27
|
-
snap(
|
|
15
|
+
snap(): Promise<void>;
|
|
28
16
|
reopen(): Promise<void>;
|
|
29
17
|
reset(): Promise<void>;
|
|
30
18
|
data: CameraData | null;
|
|
@@ -34,11 +22,18 @@ export interface UseCameraReturn<T extends string = never> {
|
|
|
34
22
|
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
35
23
|
videoProps: ComponentPropsWithRef<'video'>;
|
|
36
24
|
}
|
|
37
|
-
export
|
|
25
|
+
export type CameraTransformResult<T extends string = never> = {
|
|
26
|
+
ok: false;
|
|
27
|
+
error: CameraError<T>;
|
|
28
|
+
} | {
|
|
29
|
+
ok: true;
|
|
30
|
+
data: CameraData;
|
|
31
|
+
};
|
|
32
|
+
export interface CameraTransformContext extends CameraData {
|
|
33
|
+
video: HTMLVideoElement;
|
|
38
34
|
canvas: HTMLCanvasElement;
|
|
39
35
|
}
|
|
40
36
|
export interface UseCameraOptions<T extends string = never> extends MediaStreamConstraints {
|
|
41
|
-
transform?(
|
|
42
|
-
validate?(data: CameraData): CameraError<T> | void | null | undefined | Promise<CameraError<T> | void | null | undefined>;
|
|
37
|
+
transform?(context: CameraTransformContext): CameraTransformResult<T> | Promise<CameraTransformResult<T>>;
|
|
43
38
|
}
|
|
44
39
|
export declare function useCamera<T extends string = never>(options?: UseCameraOptions<T>): UseCameraReturn<T>;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { isBoolean,
|
|
1
|
+
import { isBoolean, isObject } from 'lodash-es';
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
3
3
|
import invariant from 'tiny-invariant';
|
|
4
4
|
import { useMediaQuery } from 'usehooks-ts';
|
|
5
5
|
export function useCamera(options = {}) {
|
|
6
|
-
const { transform, validate, ...constraints } = options;
|
|
7
6
|
const videoRef = useRef(null);
|
|
8
7
|
const streamRef = useRef(null);
|
|
9
8
|
const [data, setData] = useState(null);
|
|
@@ -30,7 +29,7 @@ export function useCamera(options = {}) {
|
|
|
30
29
|
const result = await navigator.mediaDevices.getUserMedia({
|
|
31
30
|
audio: false,
|
|
32
31
|
preferCurrentTab: true,
|
|
33
|
-
...
|
|
32
|
+
...options,
|
|
34
33
|
video: {
|
|
35
34
|
facingMode: 'user',
|
|
36
35
|
noiseSuppression: true,
|
|
@@ -47,14 +46,14 @@ export function useCamera(options = {}) {
|
|
|
47
46
|
max: 120,
|
|
48
47
|
ideal: 90,
|
|
49
48
|
},
|
|
50
|
-
...(isBoolean(
|
|
49
|
+
...(isBoolean(options.video) ? {} : options.video),
|
|
51
50
|
},
|
|
52
51
|
});
|
|
53
52
|
node.srcObject = result;
|
|
54
53
|
streamRef.current = result;
|
|
55
|
-
setMirror(!isObject(
|
|
54
|
+
setMirror(!isObject(options.video)
|
|
56
55
|
? true
|
|
57
|
-
:
|
|
56
|
+
: options.video.facingMode === 'environment'
|
|
58
57
|
? false
|
|
59
58
|
: true);
|
|
60
59
|
}
|
|
@@ -85,7 +84,7 @@ export function useCamera(options = {}) {
|
|
|
85
84
|
finally {
|
|
86
85
|
setLoading(false);
|
|
87
86
|
}
|
|
88
|
-
}, [
|
|
87
|
+
}, [options, desktop]);
|
|
89
88
|
const close = useCallback(() => {
|
|
90
89
|
setData(null);
|
|
91
90
|
setError(null);
|
|
@@ -97,7 +96,7 @@ export function useCamera(options = {}) {
|
|
|
97
96
|
resolve();
|
|
98
97
|
});
|
|
99
98
|
}, [setData, setError]);
|
|
100
|
-
const snap = useCallback(async (
|
|
99
|
+
const snap = useCallback(async () => {
|
|
101
100
|
setData(null);
|
|
102
101
|
setError(null);
|
|
103
102
|
setSnapping(true);
|
|
@@ -107,44 +106,15 @@ export function useCamera(options = {}) {
|
|
|
107
106
|
invariant(video, 'Could not find video element');
|
|
108
107
|
invariant(context, 'Could not get canvas context');
|
|
109
108
|
video.currentTime = 1;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const hdResolution = video.videoWidth >= 1280 && video.videoHeight >= 720;
|
|
113
|
-
const highResolution = video.videoWidth >= 1920 && video.videoHeight >= 1080;
|
|
114
|
-
const scaleFactor = lowResolution
|
|
115
|
-
? (opts.scale ?? (opts.crop ? 2.15 : 2))
|
|
116
|
-
: highResolution
|
|
117
|
-
? opts.crop
|
|
118
|
-
? 1.25
|
|
119
|
-
: 1.15
|
|
120
|
-
: hdResolution
|
|
121
|
-
? opts.crop
|
|
122
|
-
? 1.5
|
|
123
|
-
: 1.25
|
|
124
|
-
: opts.crop
|
|
125
|
-
? 1.5
|
|
126
|
-
: 2;
|
|
127
|
-
let x = 0;
|
|
128
|
-
let y = 0;
|
|
129
|
-
let w = video.videoWidth;
|
|
130
|
-
let h = video.videoHeight;
|
|
131
|
-
if (opts.crop) {
|
|
132
|
-
const scaleX = video.videoWidth / videoRect.width;
|
|
133
|
-
const scaleY = video.videoHeight / videoRect.height;
|
|
134
|
-
x = (opts.crop.x - videoRect.x) * scaleX;
|
|
135
|
-
y = (opts.crop.y - videoRect.y) * scaleY;
|
|
136
|
-
w = opts.crop.width * scaleX;
|
|
137
|
-
h = opts.crop.height * scaleY;
|
|
138
|
-
}
|
|
139
|
-
canvas.width = w * scaleFactor;
|
|
140
|
-
canvas.height = h * scaleFactor;
|
|
109
|
+
canvas.width = video.videoWidth;
|
|
110
|
+
canvas.height = video.videoHeight;
|
|
141
111
|
context.imageSmoothingEnabled = true;
|
|
142
112
|
context.imageSmoothingQuality = 'high';
|
|
143
113
|
if (mirror) {
|
|
144
114
|
context.translate(canvas.width, 0);
|
|
145
115
|
context.scale(-1, 1);
|
|
146
116
|
}
|
|
147
|
-
context.drawImage(video,
|
|
117
|
+
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
|
148
118
|
canvas.toBlob(async (blob) => {
|
|
149
119
|
if (!blob) {
|
|
150
120
|
setSnapping(false);
|
|
@@ -170,26 +140,28 @@ export function useCamera(options = {}) {
|
|
|
170
140
|
image.onerror = () => reject();
|
|
171
141
|
});
|
|
172
142
|
}
|
|
173
|
-
const data =
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
})
|
|
180
|
-
: {
|
|
181
|
-
url,
|
|
182
|
-
file,
|
|
183
|
-
image,
|
|
184
|
-
};
|
|
185
|
-
const error = await validate?.(data);
|
|
186
|
-
if (error)
|
|
187
|
-
setError(error);
|
|
188
|
-
else
|
|
143
|
+
const data = {
|
|
144
|
+
url,
|
|
145
|
+
file,
|
|
146
|
+
image,
|
|
147
|
+
};
|
|
148
|
+
if (!options.transform) {
|
|
189
149
|
setData(data);
|
|
150
|
+
setSnapping(false);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const transformResult = await options.transform({
|
|
154
|
+
...data,
|
|
155
|
+
video,
|
|
156
|
+
canvas,
|
|
157
|
+
});
|
|
158
|
+
if (transformResult.ok)
|
|
159
|
+
setData(transformResult.data);
|
|
160
|
+
else
|
|
161
|
+
setError(transformResult.error);
|
|
190
162
|
setSnapping(false);
|
|
191
163
|
}, 'image/jpeg', 1);
|
|
192
|
-
}, [mirror,
|
|
164
|
+
}, [mirror, options]);
|
|
193
165
|
const reset = useCallback(() => {
|
|
194
166
|
setData(null);
|
|
195
167
|
setError(null);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ObjectId } from '@opexa/object-id';
|
|
2
|
+
import { useMutation } from '@tanstack/react-query';
|
|
3
|
+
import invariant from 'tiny-invariant';
|
|
4
|
+
import { uploadFile } from '../../services/file.js';
|
|
5
|
+
import { ObjectType } from '../../services/ObjectType.js';
|
|
6
|
+
import { getUploadFileMutationKey } from '../../utils/mutationKeys.js';
|
|
7
|
+
import { getSession } from '../services/getSession.js';
|
|
8
|
+
export const useUploadFileMutation = (config) => {
|
|
9
|
+
return useMutation({
|
|
10
|
+
...config,
|
|
11
|
+
mutationKey: getUploadFileMutationKey(),
|
|
12
|
+
mutationFn: async (input) => {
|
|
13
|
+
const session = await getSession();
|
|
14
|
+
invariant(session.status === 'authenticated');
|
|
15
|
+
const id = input.id ?? ObjectId.generate(ObjectType.File).toString();
|
|
16
|
+
await uploadFile({ ...input, id }, {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${session.token}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
return id;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { SetOptional } from 'type-fest';
|
|
2
|
-
import { type
|
|
2
|
+
import { type UploadFileInput } from '../../services/file';
|
|
3
3
|
import type { Mutation } from '../../types';
|
|
4
|
-
export declare const useUploadImageFileMutation: Mutation<string, SetOptional<
|
|
4
|
+
export declare const useUploadImageFileMutation: Mutation<string, SetOptional<UploadFileInput, 'id'>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ObjectId } from '@opexa/object-id';
|
|
2
2
|
import { useMutation } from '@tanstack/react-query';
|
|
3
3
|
import invariant from 'tiny-invariant';
|
|
4
|
-
import {
|
|
4
|
+
import { uploadImageFile } from '../../services/file.js';
|
|
5
5
|
import { ObjectType } from '../../services/ObjectType.js';
|
|
6
6
|
import { getUploadImageFileMutationKey } from '../../utils/mutationKeys.js';
|
|
7
7
|
import { getSession } from '../services/getSession.js';
|
|
@@ -13,7 +13,7 @@ export const useUploadImageFileMutation = (config) => {
|
|
|
13
13
|
const session = await getSession();
|
|
14
14
|
invariant(session.status === 'authenticated');
|
|
15
15
|
const id = input.id ?? ObjectId.generate(ObjectType.File).toString();
|
|
16
|
-
await
|
|
16
|
+
await uploadImageFile({ ...input, id }, {
|
|
17
17
|
headers: {
|
|
18
18
|
Authorization: `Bearer ${session.token}`,
|
|
19
19
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ObjectId } from '@opexa/object-id';
|
|
2
|
+
import { useMutation } from '@tanstack/react-query';
|
|
3
|
+
import invariant from 'tiny-invariant';
|
|
4
|
+
import { uploadPrivateImageFile, } from '../../services/file.js';
|
|
5
|
+
import { ObjectType } from '../../services/ObjectType.js';
|
|
6
|
+
import { getUploadPrivateImageFileMutationKey } from '../../utils/mutationKeys.js';
|
|
7
|
+
import { getSession } from '../services/getSession.js';
|
|
8
|
+
export const useUploadPrivateImageFileMutation = (config) => {
|
|
9
|
+
return useMutation({
|
|
10
|
+
...config,
|
|
11
|
+
mutationKey: getUploadPrivateImageFileMutationKey(),
|
|
12
|
+
mutationFn: async (input) => {
|
|
13
|
+
const session = await getSession();
|
|
14
|
+
invariant(session.status === 'authenticated');
|
|
15
|
+
const id = input.id ?? ObjectId.generate(ObjectType.File).toString();
|
|
16
|
+
await uploadPrivateImageFile({ ...input, id }, {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${session.token}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
return id;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -17,7 +17,7 @@ export function DisclaimerV2(props) {
|
|
|
17
17
|
const acceptTriggerRef = useRef(null);
|
|
18
18
|
const [isResponsibleGamingOpen, setResponsibleGamingOpen] = useState(false);
|
|
19
19
|
const [isTermsOfUseOpen, setTermsOfUseOpen] = useState(false);
|
|
20
|
-
const [isChecked, setIsChecked] = useState(
|
|
20
|
+
const [isChecked, setIsChecked] = useState(false);
|
|
21
21
|
return (_jsxs(_Fragment, { children: [_jsx(ResponsibleGaming, { responsibleGamingContent: props.responsibleGamingContent, logo: props.logo, open: isResponsibleGamingOpen, onCloseAction: () => setResponsibleGamingOpen(false), responsibleGamingLogo: props.responsibleGamingLogo }), _jsx(TermsOfUse, { termsOfUseContent: props.termsOfUseContent, siteName: props.siteName, logo: props.logo, open: isTermsOfUseOpen, onCloseAction: () => setTermsOfUseOpen(false), responsibleGamingLogo: props.responsibleGamingLogo }), _jsx(Dialog.Root, { open: disclaimer.open, lazyMount: true, unmountOnExit: true, closeOnEscape: false, closeOnInteractOutside: false, initialFocusEl: () => acceptTriggerRef.current, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, {}), _jsx(Dialog.Positioner, { children: _jsxs(Dialog.Content, { className: "flex h-full w-full flex-col items-start gap-y-4 overflow-y-auto p-3xl lg:mx-auto lg:h-auto lg:w-[400px] lg:rounded-xl", children: [_jsx(Image, { src: props.logo, alt: "", width: 200, height: 100, className: "mx-auto h-auto w-[120px]", draggable: false }), _jsxs("div", { className: "flex w-full items-center justify-center gap-3xl", children: [_jsx(Image, { src: pagcorLogo, alt: "", height: 43, width: 88, className: "h-[43px] w-auto shrink-0", draggable: false }), _jsx(Image, { src: props.responsibleGamingLogo ?? responsibleGamingLogo, alt: "", height: 50, width: 186, className: "h-[50px] w-auto shrink-0", draggable: false })] }), _jsx("div", { className: "text-sm", children: "The following individuals are prohibited from registering or participating in this online gaming platform." }), _jsx("div", { className: "w-full grow", children: _jsxs(Dialog.Description, { className: "space-y-4 text-sm", children: [_jsxs("ul", { className: "space-y-1.5 text-left", children: [_jsxs("li", { className: "flex gap-4", children: [_jsx(Circle, {}), "Persons below the legal gambling age of 21."] }), _jsxs("li", { className: "flex gap-4", children: [_jsx(Circle, {}), "Any government official or employee directly involved in the operations of the government or its agencies."] }), _jsxs("li", { className: "flex gap-4", children: [_jsx(Circle, {}), "Member of the Armed Forces of the Philippines, including the Army, Navy, Air Force and the Philippine National Police."] }), _jsxs("li", { className: "flex gap-4", children: [_jsx(Circle, {}), "Individuals listed in PAGCOR's National Database of Restricted Persons (NDRP)"] }), _jsxs("li", { className: "flex gap-4", children: [_jsx(Circle, {}), "Holders of a valid Gaming Employment License (GEL)"] })] }), !props.hasNoCheckbox ? (_jsxs(Checkbox.Root, { checked: isChecked, onCheckedChange: (e) => {
|
|
22
22
|
setIsChecked(!!e.checked);
|
|
23
23
|
}, children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, { asChild: true, children: _jsx(CheckIcon, {}) }) }), _jsxs(Checkbox.Label, { children: ["I have read and agreed to ", props.siteName, ' ', _jsx("button", { type: "button", className: "text-brand-400 underline underline-offset-2", onClick: () => {
|
|
@@ -35,7 +35,7 @@ export function DisclaimerV2(props) {
|
|
|
35
35
|
else {
|
|
36
36
|
window.location.href = props.redirectUrlOnNoConsent;
|
|
37
37
|
}
|
|
38
|
-
}, variant: "outline", children: "Exit" }), _jsx(Button, { ref: acceptTriggerRef, type: "button", onClick: () => {
|
|
38
|
+
}, variant: "outline", children: "Exit" }), _jsx(Button, { ref: acceptTriggerRef, type: "button", disabled: !isChecked, "aria-disabled": !isChecked, onClick: () => {
|
|
39
39
|
if (isChecked) {
|
|
40
40
|
disclaimer.close();
|
|
41
41
|
}
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Image, {} from 'next/image';
|
|
4
|
-
import { useShallow } from 'zustand/shallow';
|
|
5
|
-
import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
|
|
6
4
|
import pagcorLogo from '../../images/pagcor.png';
|
|
7
5
|
import responsibleGamingLogo from '../../images/responsible-gaming.png';
|
|
8
6
|
import { Button } from '../../ui/Button/index.js';
|
|
9
7
|
import { Dialog } from '../../ui/Dialog/index.js';
|
|
10
8
|
import { Portal } from '../../ui/Portal/index.js';
|
|
11
9
|
export function TermsOfUse({ logo, open, onCloseAction, siteName, termsOfUseContent, ...props }) {
|
|
12
|
-
const disclaimerStore = useGlobalStore(useShallow((state) => state.disclaimer));
|
|
13
10
|
return (_jsx(Dialog.Root, { open: open, children: _jsxs(Portal, { children: [_jsx(Dialog.Backdrop, { className: "z-popover" }), _jsx(Dialog.Positioner, { className: "z-popover", children: _jsxs(Dialog.Content, { className: "flex h-full w-full flex-col items-start overflow-y-auto p-3xl lg:mx-auto lg:h-auto lg:w-[400px] lg:rounded-xl", children: [_jsx(Image, { src: logo, alt: "", width: 200, height: 100, className: "mx-auto h-auto w-[120px]", draggable: false }), _jsxs("div", { className: "w-full grow", children: [_jsxs(Dialog.Title, { className: "text-brand-400 mt-3xl text-center text-lg font-semibold", children: [siteName, " Terms of Use"] }), _jsx(Dialog.Description, { className: "leading-2xl mt-xs text-sm", children: termsOfUseContent }), _jsxs("div", { className: "mt-5 flex items-center justify-center gap-3xl", children: [_jsx(Image, { src: pagcorLogo, alt: "", height: 75, width: 88, className: "h-[88px] w-auto shrink-0", draggable: false }), _jsx(Image, { src: props.responsibleGamingLogo ?? responsibleGamingLogo, alt: "", height: 62, width: 186, className: "h-[62px] w-auto shrink-0", draggable: false })] })] }), _jsx("div", { className: "w-full", children: _jsx(Button, { type: "button", className: "mt-3", onClick: () => {
|
|
14
11
|
onCloseAction();
|
|
15
|
-
disclaimerStore.setOpen(true);
|
|
16
12
|
}, children: "I Agree" }) })] }) })] }) }));
|
|
17
13
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { isString } from 'lodash-es';
|
|
4
4
|
import Image, {} from 'next/image';
|
|
5
5
|
import Link from 'next/link';
|
|
6
|
-
import { useRef, useState } from 'react';
|
|
6
|
+
import { useEffect, useRef, useState } from 'react';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
8
8
|
import { useDebounceCallback } from 'usehooks-ts';
|
|
9
9
|
import { useShallow } from 'zustand/shallow';
|
|
@@ -64,10 +64,11 @@ export function Search(props) {
|
|
|
64
64
|
const classNames = isString(props.className)
|
|
65
65
|
? { root: props.className }
|
|
66
66
|
: (props.className ?? {});
|
|
67
|
+
console.log({ search });
|
|
67
68
|
return (_jsx(Dialog.Root, { open: globalStore.search.open, onOpenChange: (details) => {
|
|
68
69
|
globalStore.search.setOpen(details.open);
|
|
69
70
|
setSearch('');
|
|
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
|
|
71
|
+
}, 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 overflow-y-auto 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, placeholder: props.placeholder ?? '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
72
|
setSearch('');
|
|
72
73
|
inputRef.current?.focus();
|
|
73
74
|
}, 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-brand-800 flex h-14 w-full items-center rounded-md', classNames.providerThumbnailRoot), onClick: () => {
|
|
@@ -88,6 +89,9 @@ function DebouncedInput(props) {
|
|
|
88
89
|
});
|
|
89
90
|
const setValueDebounced = useDebounceCallback(setValue, 300);
|
|
90
91
|
const [internalValue, setInternalValue] = useState(value);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
setInternalValue(value);
|
|
94
|
+
}, [value]);
|
|
91
95
|
return (_jsx(Field.Input, { ref: props.ref, type: "search", value: internalValue, onChange: (e) => {
|
|
92
96
|
setInternalValue(e.target.value);
|
|
93
97
|
setValueDebounced(e.target.value);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
type Options = {
|
|
2
2
|
accountName?: string;
|
|
3
3
|
siteName?: string;
|
|
4
|
+
signInOptions?: 'MOBILE_NUMBER' | 'NAME_AND_PASSWORD';
|
|
4
5
|
};
|
|
5
6
|
export type ErrorCode = 'MEMBER_ACCOUNT_BLACKLISTED' | 'MEMBER_ACCOUNT_SUSPENDED' | 'INVALID_RECAPTCHA_RESPONSE' | 'MEMBER_NOT_FOUND' | 'RATE_LIMIT_REACH' | 'NOT_READY_TO_SEND_VERIFICATION_ERROR' | 'Forbidden';
|
|
6
7
|
export declare function getFriendlyErrorMessage(code: ErrorCode, options?: Options): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export function getFriendlyErrorMessage(code, options) {
|
|
2
2
|
const accountName = options?.accountName ?? '';
|
|
3
3
|
const siteName = options?.siteName ?? '';
|
|
4
|
+
const signInOptions = options?.signInOptions ?? 'NAME_AND_PASSWORD';
|
|
4
5
|
switch (code) {
|
|
5
6
|
case 'MEMBER_ACCOUNT_BLACKLISTED':
|
|
6
7
|
return `Your account ${accountName} has been blacklisted due to a serious violation of our policies. For more information or to appeal, please contact the ${siteName} Chat Support team.`;
|
|
@@ -15,6 +16,9 @@ export function getFriendlyErrorMessage(code, options) {
|
|
|
15
16
|
case 'NOT_READY_TO_SEND_VERIFICATION_ERROR':
|
|
16
17
|
return 'Your account is not ready to send verification requests. Please try again later.';
|
|
17
18
|
case 'Forbidden':
|
|
19
|
+
if (signInOptions === 'MOBILE_NUMBER') {
|
|
20
|
+
return 'Invalid verification code. Please check the code and try again.';
|
|
21
|
+
}
|
|
18
22
|
return 'Invalid username or password, please try again.';
|
|
19
23
|
default:
|
|
20
24
|
return 'Something went wrong. Please try again later.';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CSSProperties, type RefObject } from 'react';
|
|
2
|
+
import { type ValidateFileError } from '../../../utils/validateFile';
|
|
3
|
+
import { type UseIdFrontImageFieldProps } from './useIdFrontImageField';
|
|
4
|
+
export interface IdFrontImageFieldProps extends UseIdFrontImageFieldProps {
|
|
5
|
+
ref?: RefObject<HTMLDivElement | null>;
|
|
6
|
+
id?: string;
|
|
7
|
+
style?: CSSProperties;
|
|
8
|
+
className?: string;
|
|
9
|
+
invalid?: boolean;
|
|
10
|
+
readOnly?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
onError?: (error: ValidateFileError) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function IdFrontImageField__client(props: IdFrontImageFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Image from 'next/image';
|
|
3
|
+
import { useEffect, useId, useState, } from 'react';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { Camera01Icon } from '../../../icons/Camera01Icon.js';
|
|
6
|
+
import { CameraOffIcon } from '../../../icons/CameraOffIcon.js';
|
|
7
|
+
import { CheckCircleIcon } from '../../../icons/CheckCircleIcon.js';
|
|
8
|
+
import { RefreshCcw01Icon } from '../../../icons/RefreshCcw01Icon.js';
|
|
9
|
+
import { Spinner02Icon } from '../../../icons/Spinner02Icon.js';
|
|
10
|
+
import { UploadCloud02Icon } from '../../../icons/UploadCloud02Icon.js';
|
|
11
|
+
import { XIcon } from '../../../icons/XIcon.js';
|
|
12
|
+
import { Button } from '../../../ui/Button/index.js';
|
|
13
|
+
import { Dialog } from '../../../ui/Dialog/index.js';
|
|
14
|
+
import { Portal } from '../../../ui/Portal/index.js';
|
|
15
|
+
import { createSplitProps } from '../../../utils/createSplitProps.js';
|
|
16
|
+
import { validateFile, } from '../../../utils/validateFile.js';
|
|
17
|
+
import { IdFrontImageFieldProvider, useIdFrontImageFieldContext, } from './IdFrontImageFieldContext.js';
|
|
18
|
+
import { useIdFrontImageField, } from './useIdFrontImageField.js';
|
|
19
|
+
export function IdFrontImageField__client(props) {
|
|
20
|
+
const [useIdFrontImageFieldProps, localProps] = createSplitProps([
|
|
21
|
+
'value',
|
|
22
|
+
'onChange',
|
|
23
|
+
'defaultValue',
|
|
24
|
+
])(props);
|
|
25
|
+
const context = useIdFrontImageField(useIdFrontImageFieldProps);
|
|
26
|
+
return (_jsxs(IdFrontImageFieldProvider, { value: context, children: [_jsxs("div", { ref: localProps.ref, id: localProps.id, style: localProps.style, className: twMerge('border-border-primary bg-bg-primary group relative aspect-[352/180] w-full shrink-0 rounded-xl border p-xl', localProps.className), onDragOver: (e) => e.preventDefault(), onDragEnter: (e) => e.preventDefault(), onDragLeave: (e) => e.preventDefault(), onDrop: (e) => {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
const file = e.dataTransfer.files?.[0];
|
|
29
|
+
if (!file)
|
|
30
|
+
return;
|
|
31
|
+
const error = validateFile(file);
|
|
32
|
+
if (error)
|
|
33
|
+
return localProps.onError?.(error);
|
|
34
|
+
context.mutation.mutate({ file });
|
|
35
|
+
}, "aria-describedby": context.field?.ariaDescribedby, children: [_jsx("input", { id: context.field?.ids?.control, ref: context.inputRef, type: "file", accept: "image/png, image/jpeg", onChange: (e) => {
|
|
36
|
+
const file = e.target.files?.[0];
|
|
37
|
+
if (!file)
|
|
38
|
+
return;
|
|
39
|
+
const error = validateFile(file);
|
|
40
|
+
if (error)
|
|
41
|
+
return localProps.onError?.(error);
|
|
42
|
+
context.mutation.mutate({ file });
|
|
43
|
+
}, disabled: context.field?.disabled ||
|
|
44
|
+
context.query.isLoading ||
|
|
45
|
+
context.mutation.isPending ||
|
|
46
|
+
localProps.disabled, readOnly: context.field?.readOnly || localProps.readOnly, required: context.field?.required || localProps.required, className: "sr-only" }), !context.query.data?.url && (_jsxs("div", { className: "flex size-full flex-col justify-center", children: [_jsx("div", { className: "border-border-primary shadow-xs mx-auto flex size-8 items-center justify-center rounded-sm border", children: _jsx(UploadCloud02Icon, { className: "text-text-placeholder-subtle size-4" }) }), _jsxs("h2", { className: "text-text-tertiary-600 mt-lg", children: [_jsxs("span", { className: "block text-center text-sm", children: [_jsx("button", { type: "button", onClick: () => {
|
|
47
|
+
context.inputRef.current?.click();
|
|
48
|
+
}, disabled: context.field?.disabled ||
|
|
49
|
+
context.field?.readOnly ||
|
|
50
|
+
context.query.isLoading ||
|
|
51
|
+
context.mutation.isPending ||
|
|
52
|
+
localProps.disabled ||
|
|
53
|
+
localProps.readOnly, className: "text-button-secondary-fg font-semibold 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: () => {
|
|
54
|
+
context.disclosure.setOpen(true);
|
|
55
|
+
}, disabled: context.field?.disabled ||
|
|
56
|
+
context.field?.readOnly ||
|
|
57
|
+
context.query.isLoading ||
|
|
58
|
+
context.mutation.isPending ||
|
|
59
|
+
localProps.disabled ||
|
|
60
|
+
localProps.readOnly, children: "Take a photo" })] })), context.query.data?.url && (_jsxs("div", { className: "relative", children: [_jsx(Image, { src: context.query.data.url, alt: "", width: 600, height: 378.08, unoptimized: true, className: "h-auto w-full rounded-md" }), _jsx("button", { type: "button", className: "backdrop-blur-xs absolute right-2 top-2 rounded-full bg-white/10 p-1", onClick: () => {
|
|
61
|
+
context.setValue('');
|
|
62
|
+
}, children: _jsx(XIcon, { className: "size-5" }) })] }))] }), _jsx(Camera, {})] }));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* -------------------------------------
|
|
66
|
+
* Camera
|
|
67
|
+
* -------------------------------------
|
|
68
|
+
*/
|
|
69
|
+
function Camera() {
|
|
70
|
+
const context = useIdFrontImageFieldContext();
|
|
71
|
+
return (_jsx(Dialog.Root, { open: context.disclosure.open, onOpenChange: (details) => {
|
|
72
|
+
context.disclosure.setOpen(details.open);
|
|
73
|
+
}, 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: "bg-bg-primary-alt mx-auto w-[calc(100dvw-1rem)] max-w-[calc(100dvw-1rem)] overflow-y-auto rounded-lg 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: "text-text-tertiary-600 mt-md text-center 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: "border-border-disabled flex aspect-[4/3] flex-col items-center justify-center rounded-md border bg-black px-4 lg:aspect-video", children: [_jsx(CameraOffIcon, { className: "text-text-placeholder-subtle size-10 text-center lg:size-12" }), _jsx("h2", { className: "mt-3 text-sm font-semibold lg:mt-4 lg:text-base", children: context.camera.error.name }), _jsx("p", { className: "text-text-tertiary-600 mt-0.5 text-center 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: () => {
|
|
74
|
+
context.camera.reopen();
|
|
75
|
+
}, children: "Try again" })] })), context.camera.loading && (_jsx("div", { className: "border-border-disabled flex aspect-[4/3] flex-col items-center justify-center rounded-md border bg-black px-4 lg:aspect-video", children: _jsx(Spinner02Icon, { className: "text-text-placeholder size-8" }) })), context.camera.data && (_jsx("div", { className: "border-border-disabled aspect-[4/3] w-full overflow-hidden rounded-md border bg-black lg:aspect-video", children: _jsx(Image, { src: context.camera.data.url, alt: "", width: 600, height: 378.08, unoptimized: true, className: "mx-auto mt-2 block h-[calc(100%-1rem)] w-auto" }) }))] }), !context.camera.data && (_jsx("div", { className: "mt-5 lg:mt-10", children: _jsxs(Button, { className: "disabled:bg-bg-disabled disabled:text-text-disabled mx-auto w-full px-xl py-lg lg:w-[10rem]", onClick: () => {
|
|
76
|
+
context.camera.snap();
|
|
77
|
+
}, disabled: context.camera.snapping ||
|
|
78
|
+
context.camera.loading ||
|
|
79
|
+
!!context.camera.error, children: [context.camera.snapping ? (_jsx(Spinner02Icon, { className: "size-5" })) : (_jsx(Camera01Icon, { className: "size-5" })), "Capture"] }) })), context.camera.data && (_jsxs("div", { className: "mt-5 flex gap-3 lg:mt-10 lg:justify-center", children: [_jsxs(Button, { onClick: () => {
|
|
80
|
+
const file = context.camera.data?.file;
|
|
81
|
+
if (!file)
|
|
82
|
+
return;
|
|
83
|
+
context.mutation.mutate({ file });
|
|
84
|
+
context.disclosure.setOpen(false);
|
|
85
|
+
}, className: "w-full lg:w-[10rem]", children: [_jsx(CheckCircleIcon, { className: "size-5" }), "Use Photo"] }), _jsxs(Button, { variant: "outline", colorScheme: "gray", onClick: () => {
|
|
86
|
+
context.camera.reset();
|
|
87
|
+
}, className: "w-full lg:w-[10rem]", children: [_jsx(RefreshCcw01Icon, { className: "size-5" }), " Retake"] })] }))] }) })] }) }));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* -------------------------------------
|
|
91
|
+
* Video
|
|
92
|
+
* -------------------------------------
|
|
93
|
+
*/
|
|
94
|
+
function Video() {
|
|
95
|
+
const id = useId();
|
|
96
|
+
const context = useIdFrontImageFieldContext();
|
|
97
|
+
const [maskBox, setMaskBox] = useState({
|
|
98
|
+
x: 0,
|
|
99
|
+
y: 0,
|
|
100
|
+
width: 0,
|
|
101
|
+
height: 0,
|
|
102
|
+
});
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const update = () => {
|
|
105
|
+
const guide = context.guideRef.current;
|
|
106
|
+
const mask = context.maskRef.current;
|
|
107
|
+
if (!guide || !mask)
|
|
108
|
+
return;
|
|
109
|
+
const guideRect = guide.getBoundingClientRect();
|
|
110
|
+
const maskRect = mask.getBoundingClientRect();
|
|
111
|
+
const x = guideRect.left - maskRect.left;
|
|
112
|
+
const y = guideRect.top - maskRect.top;
|
|
113
|
+
const width = guideRect.width;
|
|
114
|
+
const height = guideRect.height;
|
|
115
|
+
if (width && height) {
|
|
116
|
+
setMaskBox({
|
|
117
|
+
x,
|
|
118
|
+
y,
|
|
119
|
+
width,
|
|
120
|
+
height,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const observer = new ResizeObserver(update);
|
|
125
|
+
if (context.guideRef.current)
|
|
126
|
+
observer.observe(context.guideRef.current);
|
|
127
|
+
if (context.maskRef.current)
|
|
128
|
+
observer.observe(context.maskRef.current);
|
|
129
|
+
requestAnimationFrame(update);
|
|
130
|
+
return () => observer.disconnect();
|
|
131
|
+
}, [context.guideRef, context.maskRef]);
|
|
132
|
+
return (_jsxs("div", { className: twMerge('relative h-auto w-full overflow-hidden', !context.camera.data && !context.camera.error && !context.camera.loading
|
|
133
|
+
? 'block'
|
|
134
|
+
: 'hidden'), children: [_jsx("video", { ...context.camera.videoProps }), _jsx("svg", { className: "pointer-events-none absolute -inset-4 size-[200%]", children: _jsx("defs", { children: _jsxs("mask", { id: id, maskUnits: "userSpaceOnUse", children: [_jsx("rect", { x: "0", y: "0", width: "200%", height: "200%", fill: "white" }), _jsx("rect", { x: maskBox.x, y: maskBox.y, width: maskBox.width, height: maskBox.height, fill: "black", rx: "8", ry: "8" })] }) }) }), _jsx("div", { ref: context.maskRef, className: "absolute -inset-4 size-[200%] bg-black/60 backdrop-blur-sm", style: {
|
|
135
|
+
mask: `url(#${id})`,
|
|
136
|
+
WebkitMask: `url(#${id})`,
|
|
137
|
+
maskRepeat: 'no-repeat',
|
|
138
|
+
WebkitMaskRepeat: 'no-repeat',
|
|
139
|
+
} }), _jsx("div", { ref: context.guideRef, className: "border-utility-warning-700 pointer-events-none absolute left-1/2 top-1/2 z-10 aspect-[85.6/53.98] w-[calc(100%-1rem)] max-w-[24.688rem] -translate-x-1/2 -translate-y-1/2 rounded-md border-4 border-dashed transition-all duration-200" })] }));
|
|
140
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import dynamic from 'next/dynamic';
|
|
4
|
+
import { Spinner02Icon } from '../../../icons/Spinner02Icon.js';
|
|
5
|
+
const Component = dynamic(() => import('./IdFrontImageField.client.js').then((mod) => mod.IdFrontImageField__client), {
|
|
6
|
+
ssr: false,
|
|
7
|
+
loading: () => (_jsx("div", { className: "border-border-primary bg-bg-primary flex aspect-[352/180] w-full shrink-0 items-center justify-center rounded-xl border", children: _jsx(Spinner02Icon, { className: "text-text-quinary size-8" }) })),
|
|
8
|
+
});
|
|
9
|
+
export function IdFrontImageField(props) {
|
|
10
|
+
return _jsx(Component, { ...props });
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UseIdFrontImageFieldReturn } from './useIdFrontImageField';
|
|
2
|
+
export declare const IdFrontImageFieldProvider: (props: {
|
|
3
|
+
value: UseIdFrontImageFieldReturn;
|
|
4
|
+
} & {
|
|
5
|
+
children?: import("react").ReactNode | undefined;
|
|
6
|
+
}) => React.ReactNode, useIdFrontImageFieldContext: () => UseIdFrontImageFieldReturn;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './IdFrontImageField';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './IdFrontImageField.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface UseIdFrontImageFieldProps {
|
|
2
|
+
value?: string;
|
|
3
|
+
onChange?: (value: string) => void;
|
|
4
|
+
defaultValue?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface UseIdFrontImageFieldReturn extends ReturnType<typeof useIdFrontImageField> {
|
|
7
|
+
}
|
|
8
|
+
export declare function useIdFrontImageField(props: UseIdFrontImageFieldProps): {
|
|
9
|
+
field: import("@ark-ui/react").UseFieldContext;
|
|
10
|
+
value: string;
|
|
11
|
+
setValue: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
12
|
+
query: import("@tanstack/react-query").UseQueryResult<import("../../../types").File | null, Error>;
|
|
13
|
+
mutation: import("@tanstack/react-query").UseMutationResult<string, Error, {
|
|
14
|
+
file: globalThis.File;
|
|
15
|
+
id?: string | undefined;
|
|
16
|
+
}, unknown>;
|
|
17
|
+
camera: import("../../../client/hooks/useCamera").UseCameraReturn<never>;
|
|
18
|
+
disclosure: import("../../../client/hooks/useDisclosure").UseDisclosureReturn;
|
|
19
|
+
inputRef: import("react").RefObject<HTMLInputElement | null>;
|
|
20
|
+
guideRef: import("react").RefObject<HTMLDivElement | null>;
|
|
21
|
+
maskRef: import("react").RefObject<HTMLDivElement | null>;
|
|
22
|
+
};
|