@mesob/auth-react 0.0.7 → 0.1.0
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/components/auth/auth-page-layout.d.ts +1 -3
- package/dist/components/auth/auth-page-layout.js +1 -17
- package/dist/components/auth/auth-page-layout.js.map +1 -1
- package/dist/components/auth/countdown.js +70 -9
- package/dist/components/auth/countdown.js.map +1 -1
- package/dist/components/auth/forgot-password.js +101 -35
- package/dist/components/auth/forgot-password.js.map +1 -1
- package/dist/components/auth/pages/forgot-password-page.d.ts +2 -13
- package/dist/components/auth/pages/forgot-password-page.js +198 -126
- package/dist/components/auth/pages/forgot-password-page.js.map +1 -1
- package/dist/components/auth/pages/reset-password-page.d.ts +1 -12
- package/dist/components/auth/pages/reset-password-page.js +288 -200
- package/dist/components/auth/pages/reset-password-page.js.map +1 -1
- package/dist/components/auth/pages/sign-in-page.d.ts +1 -12
- package/dist/components/auth/pages/sign-in-page.js +352 -230
- package/dist/components/auth/pages/sign-in-page.js.map +1 -1
- package/dist/components/auth/pages/sign-up-page.d.ts +1 -11
- package/dist/components/auth/pages/sign-up-page.js +310 -216
- package/dist/components/auth/pages/sign-up-page.js.map +1 -1
- package/dist/components/auth/pages/verify-email-page.d.ts +2 -12
- package/dist/components/auth/pages/verify-email-page.js +203 -135
- package/dist/components/auth/pages/verify-email-page.js.map +1 -1
- package/dist/components/auth/pages/verify-phone-page.d.ts +1 -11
- package/dist/components/auth/pages/verify-phone-page.js +206 -137
- package/dist/components/auth/pages/verify-phone-page.js.map +1 -1
- package/dist/components/auth/reset-password-form.d.ts +1 -1
- package/dist/components/auth/reset-password-form.js +188 -106
- package/dist/components/auth/reset-password-form.js.map +1 -1
- package/dist/components/auth/sign-in.d.ts +3 -3
- package/dist/components/auth/sign-in.js +228 -109
- package/dist/components/auth/sign-in.js.map +1 -1
- package/dist/components/auth/sign-up.js +210 -122
- package/dist/components/auth/sign-up.js.map +1 -1
- package/dist/components/auth/verification-form.d.ts +1 -1
- package/dist/components/auth/verification-form.js +101 -53
- package/dist/components/auth/verification-form.js.map +1 -1
- package/dist/components/error-boundary.d.ts +27 -0
- package/dist/components/error-boundary.js +49 -0
- package/dist/components/error-boundary.js.map +1 -0
- package/dist/components/iam/permissions/permissions-page.d.ts +5 -0
- package/dist/components/iam/permissions/permissions-page.js +201 -0
- package/dist/components/iam/permissions/permissions-page.js.map +1 -0
- package/dist/components/iam/roles/roles-page.d.ts +5 -0
- package/dist/components/iam/roles/roles-page.js +199 -0
- package/dist/components/iam/roles/roles-page.js.map +1 -0
- package/dist/components/iam/sessions/sessions-page.d.ts +5 -0
- package/dist/components/iam/sessions/sessions-page.js +202 -0
- package/dist/components/iam/sessions/sessions-page.js.map +1 -0
- package/dist/components/iam/tenants/tenants-page.d.ts +5 -0
- package/dist/components/iam/tenants/tenants-page.js +202 -0
- package/dist/components/iam/tenants/tenants-page.js.map +1 -0
- package/dist/components/iam/users/users-page.d.ts +5 -0
- package/dist/components/iam/users/users-page.js +211 -0
- package/dist/components/iam/users/users-page.js.map +1 -0
- package/dist/components/profile/profile-page.d.ts +8 -0
- package/dist/components/profile/profile-page.js +163 -0
- package/dist/components/profile/profile-page.js.map +1 -0
- package/dist/components/shared/data-table/data-table.d.ts +22 -0
- package/dist/components/shared/data-table/data-table.js +85 -0
- package/dist/components/shared/data-table/data-table.js.map +1 -0
- package/dist/components/skeletons/auth-form-skeleton.d.ts +5 -0
- package/dist/components/skeletons/auth-form-skeleton.js +32 -0
- package/dist/components/skeletons/auth-form-skeleton.js.map +1 -0
- package/dist/components/skeletons/profile-skeleton.d.ts +5 -0
- package/dist/components/skeletons/profile-skeleton.js +33 -0
- package/dist/components/skeletons/profile-skeleton.js.map +1 -0
- package/dist/components/skeletons/table-skeleton.d.ts +9 -0
- package/dist/components/skeletons/table-skeleton.js +39 -0
- package/dist/components/skeletons/table-skeleton.js.map +1 -0
- package/dist/handle-error-BqDMxnQZ.d.ts +8 -0
- package/dist/index.d.ts +75 -208
- package/dist/index.js +2091 -1057
- package/dist/index.js.map +1 -1
- package/package.json +9 -3
- package/dist/handle-error-H0iqQxJ5.d.ts +0 -6
|
@@ -1,40 +1,75 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/components/auth/pages/verify-phone-page.tsx
|
|
4
|
-
import { useTranslations as useTranslations3 } from "next-intl";
|
|
5
|
-
import { useState as useState3 } from "react";
|
|
6
|
-
|
|
7
|
-
// src/context/auth-provider.tsx
|
|
8
4
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from "react";
|
|
5
|
+
Alert,
|
|
6
|
+
AlertDescription,
|
|
7
|
+
AlertTitle
|
|
8
|
+
} from "@mesob/ui/components/alert";
|
|
9
|
+
import { toast } from "@mesob/ui/components/sonner";
|
|
10
|
+
import { IconAlertCircle } from "@tabler/icons-react";
|
|
11
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
12
|
+
|
|
13
|
+
// src/lib/translations.ts
|
|
14
|
+
function createTranslator(messages, namespace) {
|
|
15
|
+
return (key, params) => {
|
|
16
|
+
const fullKey = namespace ? `${namespace}.${key}` : key;
|
|
17
|
+
const keys = fullKey.split(".");
|
|
18
|
+
let value = messages;
|
|
19
|
+
for (const k of keys) {
|
|
20
|
+
if (value && typeof value === "object" && value !== null) {
|
|
21
|
+
value = value[k];
|
|
22
|
+
} else {
|
|
23
|
+
return fullKey;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (typeof value !== "string") {
|
|
27
|
+
return fullKey;
|
|
28
|
+
}
|
|
29
|
+
if (params) {
|
|
30
|
+
return value.replace(
|
|
31
|
+
/\{(\w+)\}/g,
|
|
32
|
+
(_, param) => String(params[param] ?? `{${param}}`)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/provider.tsx
|
|
40
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
41
|
+
import { deepmerge } from "deepmerge-ts";
|
|
42
|
+
import createFetchClient from "openapi-fetch";
|
|
43
|
+
import createClient from "openapi-react-query";
|
|
44
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
15
45
|
import { jsx } from "react/jsx-runtime";
|
|
16
|
-
var
|
|
17
|
-
var
|
|
18
|
-
|
|
46
|
+
var SessionContext = createContext(null);
|
|
47
|
+
var ApiContext = createContext(null);
|
|
48
|
+
var ConfigContext = createContext(null);
|
|
49
|
+
var queryClient = new QueryClient({
|
|
50
|
+
defaultOptions: {
|
|
51
|
+
queries: {
|
|
52
|
+
staleTime: 1e3 * 60 * 5,
|
|
53
|
+
gcTime: 1e3 * 60 * 10,
|
|
54
|
+
retry: 1,
|
|
55
|
+
refetchOnWindowFocus: false
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
function useApi() {
|
|
60
|
+
const context = useContext(ApiContext);
|
|
19
61
|
if (!context) {
|
|
20
|
-
throw new Error("
|
|
62
|
+
throw new Error("useApi must be used within MesobAuthProvider");
|
|
21
63
|
}
|
|
22
64
|
return context;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
status;
|
|
29
|
-
details;
|
|
30
|
-
constructor(message, code, status, details) {
|
|
31
|
-
super(message);
|
|
32
|
-
this.name = "AuthError";
|
|
33
|
-
this.code = code;
|
|
34
|
-
this.status = status;
|
|
35
|
-
this.details = details;
|
|
65
|
+
}
|
|
66
|
+
function useConfig() {
|
|
67
|
+
const context = useContext(ConfigContext);
|
|
68
|
+
if (!context) {
|
|
69
|
+
throw new Error("useConfig must be used within MesobAuthProvider");
|
|
36
70
|
}
|
|
37
|
-
|
|
71
|
+
return context;
|
|
72
|
+
}
|
|
38
73
|
|
|
39
74
|
// src/constants/auth.error.codes.ts
|
|
40
75
|
var AUTH_ERROR_MAPPING = {
|
|
@@ -86,71 +121,67 @@ var AUTH_ERROR_MAPPING = {
|
|
|
86
121
|
var validCodes = Object.keys(AUTH_ERROR_MAPPING);
|
|
87
122
|
|
|
88
123
|
// src/utils/handle-error.ts
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {
|
|
101
|
-
const mapping = AUTH_ERROR_MAPPING[errorCode];
|
|
102
|
-
setError({
|
|
103
|
-
title: mapping.title,
|
|
104
|
-
description: mapping.description
|
|
105
|
-
});
|
|
106
|
-
return;
|
|
124
|
+
function isAuthError(err) {
|
|
125
|
+
return typeof err === "object" && err !== null && "message" in err && typeof err.message === "string";
|
|
126
|
+
}
|
|
127
|
+
function extractErrorCode(err) {
|
|
128
|
+
if (err.code && validCodes.includes(err.code)) {
|
|
129
|
+
return err.code;
|
|
130
|
+
}
|
|
131
|
+
if (err.message) {
|
|
132
|
+
const messageUpper = err.message.toUpperCase().trim();
|
|
133
|
+
if (validCodes.includes(messageUpper)) {
|
|
134
|
+
return messageUpper;
|
|
107
135
|
}
|
|
136
|
+
}
|
|
137
|
+
return "";
|
|
138
|
+
}
|
|
139
|
+
function handleAuthError(err, setError, t) {
|
|
140
|
+
const errorCode = extractErrorCode(err);
|
|
141
|
+
if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {
|
|
142
|
+
const mapping = AUTH_ERROR_MAPPING[errorCode];
|
|
108
143
|
setError({
|
|
109
|
-
title:
|
|
110
|
-
|
|
111
|
-
description: err.message || t("errors.fallback")
|
|
144
|
+
title: mapping.title,
|
|
145
|
+
description: mapping.description
|
|
112
146
|
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
setError({
|
|
150
|
+
title: t("errors.fallback"),
|
|
151
|
+
description: err.message || t("errors.fallback")
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
function handleGenericError(err, setError, t) {
|
|
155
|
+
const message = err instanceof Error ? err.message : t("errors.fallback");
|
|
156
|
+
setError({
|
|
157
|
+
title: "Error",
|
|
158
|
+
description: message
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
var handleError = (err, setError, t) => {
|
|
162
|
+
if (isAuthError(err)) {
|
|
163
|
+
handleAuthError(err, setError, t);
|
|
113
164
|
} else {
|
|
114
|
-
|
|
115
|
-
setError({
|
|
116
|
-
title: "Error",
|
|
117
|
-
description: message
|
|
118
|
-
});
|
|
165
|
+
handleGenericError(err, setError, t);
|
|
119
166
|
}
|
|
120
167
|
};
|
|
121
168
|
|
|
122
169
|
// src/components/auth/auth-page-layout.tsx
|
|
123
|
-
import {
|
|
124
|
-
Alert,
|
|
125
|
-
AlertDescription,
|
|
126
|
-
AlertTitle
|
|
127
|
-
} from "@mesob/ui/components/alert";
|
|
128
|
-
import { IconAlertCircle } from "@tabler/icons-react";
|
|
129
170
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
130
171
|
var AuthPageLayout = ({
|
|
131
172
|
title,
|
|
132
173
|
description,
|
|
133
174
|
children,
|
|
134
|
-
error,
|
|
135
175
|
footer,
|
|
136
176
|
logoImage
|
|
137
177
|
}) => {
|
|
138
|
-
const errorContent = error ? (
|
|
139
|
-
// biome-ignore lint/style/noNestedTernary: <explanation>
|
|
140
|
-
typeof error === "string" ? { title: "Error", description: error } : error
|
|
141
|
-
) : null;
|
|
142
178
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
143
|
-
/* @__PURE__ */ jsx2("div", { className: "flex size-8 mb-6 w-full items-center justify-center rounded-md", children: /* @__PURE__ */ jsx2("img", { src: logoImage || "", alt: "
|
|
179
|
+
/* @__PURE__ */ jsx2("div", { className: "flex size-8 mb-6 w-full items-center justify-center rounded-md", children: /* @__PURE__ */ jsx2("img", { src: logoImage || "", alt: "Mesob", width: 42, height: 42 }) }),
|
|
144
180
|
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
145
181
|
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
146
182
|
description && /* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
147
183
|
] }),
|
|
148
184
|
children,
|
|
149
|
-
errorContent && /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
|
|
150
|
-
/* @__PURE__ */ jsx2(IconAlertCircle, { className: "h-4 w-4" }),
|
|
151
|
-
/* @__PURE__ */ jsx2(AlertTitle, { children: errorContent.title }),
|
|
152
|
-
/* @__PURE__ */ jsx2(AlertDescription, { children: errorContent.description })
|
|
153
|
-
] }),
|
|
154
185
|
/* @__PURE__ */ jsx2("div", { className: "mt-2 w-full", children: footer && /* @__PURE__ */ jsx2("div", { className: "w-full text-center text-sm text-muted-foreground", children: footer }) })
|
|
155
186
|
] });
|
|
156
187
|
};
|
|
@@ -158,28 +189,25 @@ var AuthPageLayout = ({
|
|
|
158
189
|
// src/components/auth/verification-form.tsx
|
|
159
190
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
160
191
|
import { Button as Button2 } from "@mesob/ui/components/button";
|
|
161
|
-
import {
|
|
162
|
-
Form,
|
|
163
|
-
FormControl,
|
|
164
|
-
FormField,
|
|
165
|
-
FormItem,
|
|
166
|
-
FormMessage
|
|
167
|
-
} from "@mesob/ui/components/form";
|
|
192
|
+
import { Field, FieldError, FieldGroup } from "@mesob/ui/components/field";
|
|
168
193
|
import {
|
|
169
194
|
InputOTP,
|
|
170
195
|
InputOTPGroup,
|
|
171
196
|
InputOTPSlot
|
|
172
197
|
} from "@mesob/ui/components/input-otp";
|
|
173
198
|
import { Spinner as Spinner2 } from "@mesob/ui/components/spinner";
|
|
174
|
-
import {
|
|
175
|
-
import { useMemo } from "react";
|
|
176
|
-
import { useForm } from "react-hook-form";
|
|
199
|
+
import { Controller, useForm } from "react-hook-form";
|
|
177
200
|
import { z } from "zod";
|
|
178
201
|
|
|
202
|
+
// src/hooks/use-translator.ts
|
|
203
|
+
function useTranslator(namespace) {
|
|
204
|
+
const { config } = useConfig();
|
|
205
|
+
return createTranslator(config.messages || {}, namespace);
|
|
206
|
+
}
|
|
207
|
+
|
|
179
208
|
// src/components/auth/countdown.tsx
|
|
180
209
|
import { Button } from "@mesob/ui/components/button";
|
|
181
210
|
import { Spinner } from "@mesob/ui/components/spinner";
|
|
182
|
-
import { useTranslations } from "next-intl";
|
|
183
211
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
184
212
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
185
213
|
var Countdown = ({
|
|
@@ -187,7 +215,7 @@ var Countdown = ({
|
|
|
187
215
|
onResend,
|
|
188
216
|
resending = false
|
|
189
217
|
}) => {
|
|
190
|
-
const t =
|
|
218
|
+
const t = useTranslator("Common");
|
|
191
219
|
const [seconds, setSeconds] = useState2(initialSeconds);
|
|
192
220
|
const [isResending, setIsResending] = useState2(false);
|
|
193
221
|
useEffect2(() => {
|
|
@@ -234,32 +262,32 @@ var Countdown = ({
|
|
|
234
262
|
|
|
235
263
|
// src/components/auth/verification-form.tsx
|
|
236
264
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
265
|
+
var verificationSchema = (t) => z.object({
|
|
266
|
+
code: z.string().length(6, t("form.codeLength"))
|
|
267
|
+
});
|
|
237
268
|
var VerificationForm = ({
|
|
238
269
|
onSubmit,
|
|
239
270
|
onResend,
|
|
240
271
|
isLoading = false
|
|
241
272
|
}) => {
|
|
242
|
-
const t =
|
|
243
|
-
const verificationSchema = useMemo(
|
|
244
|
-
() => z.object({
|
|
245
|
-
code: z.string().length(6, t("form.codeLength"))
|
|
246
|
-
}),
|
|
247
|
-
[t]
|
|
248
|
-
);
|
|
273
|
+
const t = useTranslator("Auth.verification");
|
|
249
274
|
const form = useForm({
|
|
250
|
-
resolver: zodResolver(verificationSchema),
|
|
275
|
+
resolver: zodResolver(verificationSchema(t)),
|
|
251
276
|
defaultValues: {
|
|
252
277
|
code: ""
|
|
253
278
|
}
|
|
254
279
|
});
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
280
|
+
const handleSubmit = form.handleSubmit(async (values) => {
|
|
281
|
+
await onSubmit(values);
|
|
282
|
+
});
|
|
283
|
+
return /* @__PURE__ */ jsxs3("form", { id: "verification-form", onSubmit: handleSubmit, children: [
|
|
284
|
+
/* @__PURE__ */ jsx4(FieldGroup, { children: /* @__PURE__ */ jsx4(
|
|
285
|
+
Controller,
|
|
258
286
|
{
|
|
259
|
-
control: form.control,
|
|
260
287
|
name: "code",
|
|
261
|
-
|
|
262
|
-
|
|
288
|
+
control: form.control,
|
|
289
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs3(Field, { "data-invalid": fieldState.invalid, children: [
|
|
290
|
+
/* @__PURE__ */ jsx4("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx4(
|
|
263
291
|
InputOTP,
|
|
264
292
|
{
|
|
265
293
|
maxLength: 6,
|
|
@@ -269,6 +297,7 @@ var VerificationForm = ({
|
|
|
269
297
|
onChange: field.onChange,
|
|
270
298
|
onBlur: field.onBlur,
|
|
271
299
|
containerClassName: "gap-4 justify-center mb-2 flex items-center",
|
|
300
|
+
"aria-invalid": fieldState.invalid,
|
|
272
301
|
children: /* @__PURE__ */ jsxs3(InputOTPGroup, { className: "gap-3 *:data-[slot=input-otp-slot]:h-12 *:data-[slot=input-otp-slot]:w-12 *:data-[slot=input-otp-slot]:rounded-md *:data-[slot=input-otp-slot]:border *:data-[slot=input-otp-slot]:text-xl", children: [
|
|
273
302
|
/* @__PURE__ */ jsx4(InputOTPSlot, { className: "h-12", index: 0 }),
|
|
274
303
|
/* @__PURE__ */ jsx4(InputOTPSlot, { className: "h-12", index: 1 }),
|
|
@@ -278,22 +307,18 @@ var VerificationForm = ({
|
|
|
278
307
|
/* @__PURE__ */ jsx4(InputOTPSlot, { className: "h-12", index: 5 })
|
|
279
308
|
] })
|
|
280
309
|
}
|
|
281
|
-
) })
|
|
282
|
-
/* @__PURE__ */ jsx4(
|
|
310
|
+
) }),
|
|
311
|
+
fieldState.invalid && /* @__PURE__ */ jsx4(FieldError, { errors: [fieldState.error] })
|
|
283
312
|
] })
|
|
284
313
|
}
|
|
285
|
-
),
|
|
286
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center", children: [
|
|
314
|
+
) }),
|
|
315
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center mt-4", children: [
|
|
287
316
|
/* @__PURE__ */ jsx4(Countdown, { onResend, resending: isLoading }),
|
|
288
317
|
/* @__PURE__ */ jsxs3(
|
|
289
318
|
Button2,
|
|
290
319
|
{
|
|
291
|
-
type: "
|
|
292
|
-
|
|
293
|
-
form.handleSubmit(async (values) => {
|
|
294
|
-
await onSubmit(values);
|
|
295
|
-
})();
|
|
296
|
-
},
|
|
320
|
+
type: "submit",
|
|
321
|
+
form: "verification-form",
|
|
297
322
|
disabled: isLoading || form.watch("code").length !== 6,
|
|
298
323
|
children: [
|
|
299
324
|
isLoading && /* @__PURE__ */ jsx4(Spinner2, {}),
|
|
@@ -302,28 +327,51 @@ var VerificationForm = ({
|
|
|
302
327
|
}
|
|
303
328
|
)
|
|
304
329
|
] })
|
|
305
|
-
] })
|
|
330
|
+
] });
|
|
306
331
|
};
|
|
307
332
|
|
|
308
333
|
// src/components/auth/pages/verify-phone-page.tsx
|
|
309
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
334
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
310
335
|
var VerifyPhonePage = ({
|
|
311
336
|
verificationId,
|
|
312
337
|
context,
|
|
313
338
|
phone = "",
|
|
314
|
-
onNavigate,
|
|
315
|
-
linkComponent: Link,
|
|
316
|
-
links,
|
|
317
|
-
logoImage,
|
|
318
339
|
redirectUrl
|
|
319
340
|
}) => {
|
|
320
|
-
const
|
|
321
|
-
const
|
|
322
|
-
const
|
|
323
|
-
const
|
|
341
|
+
const { hooks, refresh, setAuth } = useApi();
|
|
342
|
+
const { config } = useConfig();
|
|
343
|
+
const t = createTranslator(config.messages || {}, "Auth.verification");
|
|
344
|
+
const common = createTranslator(config.messages || {}, "Common");
|
|
345
|
+
const footer = createTranslator(
|
|
346
|
+
config.messages || {},
|
|
347
|
+
"Auth.forgotPassword.footer"
|
|
348
|
+
);
|
|
324
349
|
const [isLoading, setIsLoading] = useState3(false);
|
|
325
350
|
const [error, setError] = useState3(null);
|
|
326
|
-
const
|
|
351
|
+
const verifyPhoneMutation = hooks.useMutation(
|
|
352
|
+
"post",
|
|
353
|
+
"/phone/verification/confirm"
|
|
354
|
+
);
|
|
355
|
+
const requestPhoneMutation = hooks.useMutation(
|
|
356
|
+
"post",
|
|
357
|
+
"/phone/verification/request"
|
|
358
|
+
);
|
|
359
|
+
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
360
|
+
const Link = config.navigation?.linkComponent;
|
|
361
|
+
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
362
|
+
if (typeof window !== "undefined") {
|
|
363
|
+
window.location.href = path;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
const logoImage = config.ui.logoImage;
|
|
367
|
+
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
368
|
+
useEffect3(() => {
|
|
369
|
+
if (error) {
|
|
370
|
+
toast.error(error.title || "Error", {
|
|
371
|
+
description: error.description
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}, [error]);
|
|
327
375
|
const handleSubmit = async (values) => {
|
|
328
376
|
if (!verificationId) {
|
|
329
377
|
setError({
|
|
@@ -335,18 +383,20 @@ var VerifyPhonePage = ({
|
|
|
335
383
|
setIsLoading(true);
|
|
336
384
|
setError(null);
|
|
337
385
|
try {
|
|
338
|
-
const res = await
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
386
|
+
const res = await verifyPhoneMutation.mutateAsync({
|
|
387
|
+
body: {
|
|
388
|
+
verificationId,
|
|
389
|
+
code: values.code,
|
|
390
|
+
context
|
|
391
|
+
}
|
|
342
392
|
});
|
|
343
393
|
if (res && "user" in res && "session" in res && res.session) {
|
|
344
394
|
setAuth(res);
|
|
345
|
-
onNavigate(
|
|
395
|
+
onNavigate(defaultRedirect);
|
|
346
396
|
return;
|
|
347
397
|
}
|
|
348
398
|
await refresh();
|
|
349
|
-
onNavigate(
|
|
399
|
+
onNavigate(defaultRedirect);
|
|
350
400
|
} catch (err) {
|
|
351
401
|
handleError(err, setError, t);
|
|
352
402
|
} finally {
|
|
@@ -364,7 +414,12 @@ var VerifyPhonePage = ({
|
|
|
364
414
|
});
|
|
365
415
|
return;
|
|
366
416
|
}
|
|
367
|
-
const res = await
|
|
417
|
+
const res = await requestPhoneMutation.mutateAsync({
|
|
418
|
+
body: {
|
|
419
|
+
phone: targetPhone,
|
|
420
|
+
context
|
|
421
|
+
}
|
|
422
|
+
});
|
|
368
423
|
if (res && "verificationId" in res && res.verificationId) {
|
|
369
424
|
onNavigate(
|
|
370
425
|
`/auth/verify-phone?context=${context}&verificationId=${res.verificationId}&phone=${targetPhone}`
|
|
@@ -401,14 +456,21 @@ var VerifyPhonePage = ({
|
|
|
401
456
|
}
|
|
402
457
|
);
|
|
403
458
|
}
|
|
404
|
-
|
|
459
|
+
let errorContent = null;
|
|
460
|
+
if (error) {
|
|
461
|
+
if (typeof error === "string") {
|
|
462
|
+
errorContent = { title: "Error", description: error };
|
|
463
|
+
} else {
|
|
464
|
+
errorContent = error;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
return /* @__PURE__ */ jsxs4(
|
|
405
468
|
AuthPageLayout,
|
|
406
469
|
{
|
|
407
470
|
title: t("phone.title"),
|
|
408
471
|
description: t("phone.description", {
|
|
409
472
|
target: phone || t("phone.missingPhone")
|
|
410
473
|
}),
|
|
411
|
-
error,
|
|
412
474
|
logoImage,
|
|
413
475
|
footer: Link ? /* @__PURE__ */ jsx5(Link, { href: signInLink, className: "text-primary hover:underline", children: footer("backToSignIn") }) : /* @__PURE__ */ jsx5(
|
|
414
476
|
"a",
|
|
@@ -422,16 +484,23 @@ var VerifyPhonePage = ({
|
|
|
422
484
|
children: footer("backToSignIn")
|
|
423
485
|
}
|
|
424
486
|
),
|
|
425
|
-
children:
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
487
|
+
children: [
|
|
488
|
+
/* @__PURE__ */ jsx5(
|
|
489
|
+
VerificationForm,
|
|
490
|
+
{
|
|
491
|
+
verificationId,
|
|
492
|
+
onSubmit: handleSubmit,
|
|
493
|
+
onResend: handleResend,
|
|
494
|
+
isLoading: isLoading || verifyPhoneMutation.isPending || requestPhoneMutation.isPending,
|
|
495
|
+
error
|
|
496
|
+
}
|
|
497
|
+
),
|
|
498
|
+
errorContent && /* @__PURE__ */ jsxs4(Alert, { variant: "destructive", className: "mt-4", children: [
|
|
499
|
+
/* @__PURE__ */ jsx5(IconAlertCircle, { className: "h-4 w-4" }),
|
|
500
|
+
/* @__PURE__ */ jsx5(AlertTitle, { children: errorContent.title }),
|
|
501
|
+
/* @__PURE__ */ jsx5(AlertDescription, { children: errorContent.description })
|
|
502
|
+
] })
|
|
503
|
+
]
|
|
435
504
|
}
|
|
436
505
|
);
|
|
437
506
|
};
|