@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/sign-up-page.tsx
|
|
4
|
-
import { useTranslations as useTranslations2 } 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
|
};
|
|
@@ -159,54 +190,56 @@ var AuthPageLayout = ({
|
|
|
159
190
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
160
191
|
import { Button } from "@mesob/ui/components/button";
|
|
161
192
|
import {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
FormMessage
|
|
168
|
-
} from "@mesob/ui/components/form";
|
|
193
|
+
Field,
|
|
194
|
+
FieldError,
|
|
195
|
+
FieldGroup,
|
|
196
|
+
FieldLabel
|
|
197
|
+
} from "@mesob/ui/components/field";
|
|
169
198
|
import { Input } from "@mesob/ui/components/input";
|
|
170
199
|
import { IconEye, IconEyeOff } from "@tabler/icons-react";
|
|
171
|
-
import {
|
|
172
|
-
import {
|
|
173
|
-
import { useForm } from "react-hook-form";
|
|
200
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
201
|
+
import { Controller, useForm } from "react-hook-form";
|
|
174
202
|
import { z } from "zod";
|
|
203
|
+
|
|
204
|
+
// src/hooks/use-translator.ts
|
|
205
|
+
function useTranslator(namespace) {
|
|
206
|
+
const { config } = useConfig();
|
|
207
|
+
return createTranslator(config.messages || {}, namespace);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/components/auth/sign-up.tsx
|
|
175
211
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
176
212
|
var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
|
|
213
|
+
var signUpSchema = (t) => z.object({
|
|
214
|
+
fullName: z.string().min(1, t("errors.fullNameRequired")),
|
|
215
|
+
identifier: z.string().min(1, t("errors.contactRequired")).refine(
|
|
216
|
+
(val) => {
|
|
217
|
+
if (!val) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return val.includes("@") || isPhone(val);
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
message: t("errors.invalidEmailOrPhone")
|
|
224
|
+
}
|
|
225
|
+
),
|
|
226
|
+
password: z.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError")),
|
|
227
|
+
confirmPassword: z.string()
|
|
228
|
+
}).refine((data) => data.password === data.confirmPassword, {
|
|
229
|
+
message: t("errors.passwordsMismatch"),
|
|
230
|
+
path: ["confirmPassword"]
|
|
231
|
+
});
|
|
177
232
|
var SignUp = ({
|
|
178
233
|
onSubmit,
|
|
179
234
|
isLoading = false,
|
|
180
235
|
initialIdentifier
|
|
181
236
|
}) => {
|
|
182
|
-
const t =
|
|
237
|
+
const t = useTranslator("Auth.signUp");
|
|
183
238
|
const hasInitialIdentifier = !!initialIdentifier;
|
|
184
239
|
const [showPassword, setShowPassword] = useState2(false);
|
|
185
240
|
const [showConfirmPassword, setShowConfirmPassword] = useState2(false);
|
|
186
|
-
const signUpSchema = useMemo(
|
|
187
|
-
() => z.object({
|
|
188
|
-
fullName: z.string().min(1, t("errors.fullNameRequired")),
|
|
189
|
-
identifier: z.string().min(1, t("errors.contactRequired")).refine(
|
|
190
|
-
(val) => {
|
|
191
|
-
if (!val) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
return val.includes("@") || isPhone(val);
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
message: t("errors.invalidEmailOrPhone")
|
|
198
|
-
}
|
|
199
|
-
),
|
|
200
|
-
password: z.string().min(8, t("errors.passwordLength")).max(128, t("errors.longPasswordError")),
|
|
201
|
-
confirmPassword: z.string()
|
|
202
|
-
}).refine((data) => data.password === data.confirmPassword, {
|
|
203
|
-
message: t("errors.passwordsMismatch"),
|
|
204
|
-
path: ["confirmPassword"]
|
|
205
|
-
}),
|
|
206
|
-
[t]
|
|
207
|
-
);
|
|
208
241
|
const form = useForm({
|
|
209
|
-
resolver: zodResolver(signUpSchema),
|
|
242
|
+
resolver: zodResolver(signUpSchema(t)),
|
|
210
243
|
defaultValues: {
|
|
211
244
|
fullName: "",
|
|
212
245
|
identifier: initialIdentifier || "",
|
|
@@ -232,101 +265,133 @@ var SignUp = ({
|
|
|
232
265
|
return t("form.phoneLabel");
|
|
233
266
|
};
|
|
234
267
|
const identifierLabel = getIdentifierLabel();
|
|
235
|
-
return /* @__PURE__ */
|
|
236
|
-
/* @__PURE__ */
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
/* @__PURE__ */
|
|
243
|
-
|
|
244
|
-
/* @__PURE__ */ jsx3(FormMessage, {})
|
|
245
|
-
] })
|
|
246
|
-
}
|
|
247
|
-
),
|
|
248
|
-
/* @__PURE__ */ jsx3(
|
|
249
|
-
FormField,
|
|
250
|
-
{
|
|
251
|
-
control: form.control,
|
|
252
|
-
name: "identifier",
|
|
253
|
-
render: ({ field }) => /* @__PURE__ */ jsxs2(FormItem, { children: [
|
|
254
|
-
/* @__PURE__ */ jsx3(FormLabel, { className: hasInitialIdentifier ? "block" : void 0, children: identifierLabel }),
|
|
255
|
-
/* @__PURE__ */ jsx3(FormControl, { children: /* @__PURE__ */ jsx3(
|
|
256
|
-
Input,
|
|
257
|
-
{
|
|
258
|
-
type: field.value.includes("@") ? "email" : "tel",
|
|
259
|
-
placeholder: hasInitialIdentifier ? void 0 : t("form.accountPlaceholder") || "Email or phone number",
|
|
260
|
-
...field,
|
|
261
|
-
disabled: hasInitialIdentifier
|
|
262
|
-
}
|
|
263
|
-
) }),
|
|
264
|
-
/* @__PURE__ */ jsx3(FormMessage, {})
|
|
265
|
-
] })
|
|
266
|
-
}
|
|
267
|
-
),
|
|
268
|
-
/* @__PURE__ */ jsx3(
|
|
269
|
-
FormField,
|
|
270
|
-
{
|
|
271
|
-
control: form.control,
|
|
272
|
-
name: "password",
|
|
273
|
-
render: ({ field }) => /* @__PURE__ */ jsxs2(FormItem, { children: [
|
|
274
|
-
/* @__PURE__ */ jsx3(FormLabel, { children: t("form.passwordLabel") }),
|
|
275
|
-
/* @__PURE__ */ jsx3(FormControl, { children: /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
268
|
+
return /* @__PURE__ */ jsxs2("form", { id: "sign-up-form", onSubmit: handleSubmit, children: [
|
|
269
|
+
/* @__PURE__ */ jsxs2(FieldGroup, { children: [
|
|
270
|
+
/* @__PURE__ */ jsx3(
|
|
271
|
+
Controller,
|
|
272
|
+
{
|
|
273
|
+
name: "fullName",
|
|
274
|
+
control: form.control,
|
|
275
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
276
|
+
/* @__PURE__ */ jsx3(FieldLabel, { htmlFor: "sign-up-fullName", children: t("form.fullNameLabel") }),
|
|
276
277
|
/* @__PURE__ */ jsx3(
|
|
277
278
|
Input,
|
|
278
279
|
{
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
280
|
+
...field,
|
|
281
|
+
id: "sign-up-fullName",
|
|
282
|
+
placeholder: t("form.fullNamePlaceholder"),
|
|
283
|
+
"aria-invalid": fieldState.invalid
|
|
282
284
|
}
|
|
283
285
|
),
|
|
286
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
287
|
+
] })
|
|
288
|
+
}
|
|
289
|
+
),
|
|
290
|
+
/* @__PURE__ */ jsx3(
|
|
291
|
+
Controller,
|
|
292
|
+
{
|
|
293
|
+
name: "identifier",
|
|
294
|
+
control: form.control,
|
|
295
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
284
296
|
/* @__PURE__ */ jsx3(
|
|
285
|
-
|
|
297
|
+
FieldLabel,
|
|
286
298
|
{
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
children: showPassword ? /* @__PURE__ */ jsx3(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(IconEye, { className: "h-4 w-4" })
|
|
299
|
+
htmlFor: "sign-up-identifier",
|
|
300
|
+
className: hasInitialIdentifier ? "block" : void 0,
|
|
301
|
+
children: identifierLabel
|
|
291
302
|
}
|
|
292
|
-
)
|
|
293
|
-
] }) }),
|
|
294
|
-
/* @__PURE__ */ jsx3(FormMessage, {})
|
|
295
|
-
] })
|
|
296
|
-
}
|
|
297
|
-
),
|
|
298
|
-
/* @__PURE__ */ jsx3(
|
|
299
|
-
FormField,
|
|
300
|
-
{
|
|
301
|
-
control: form.control,
|
|
302
|
-
name: "confirmPassword",
|
|
303
|
-
render: ({ field }) => /* @__PURE__ */ jsxs2(FormItem, { children: [
|
|
304
|
-
/* @__PURE__ */ jsx3(FormLabel, { children: t("form.confirmPasswordLabel") }),
|
|
305
|
-
/* @__PURE__ */ jsx3(FormControl, { children: /* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
303
|
+
),
|
|
306
304
|
/* @__PURE__ */ jsx3(
|
|
307
305
|
Input,
|
|
308
306
|
{
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
307
|
+
...field,
|
|
308
|
+
id: "sign-up-identifier",
|
|
309
|
+
type: field.value.includes("@") ? "email" : "tel",
|
|
310
|
+
placeholder: hasInitialIdentifier ? void 0 : t("form.accountPlaceholder") || "Email or phone number",
|
|
311
|
+
disabled: hasInitialIdentifier,
|
|
312
|
+
"aria-invalid": fieldState.invalid
|
|
312
313
|
}
|
|
313
314
|
),
|
|
314
|
-
/* @__PURE__ */ jsx3(
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
315
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
316
|
+
] })
|
|
317
|
+
}
|
|
318
|
+
),
|
|
319
|
+
/* @__PURE__ */ jsx3(
|
|
320
|
+
Controller,
|
|
321
|
+
{
|
|
322
|
+
name: "password",
|
|
323
|
+
control: form.control,
|
|
324
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
325
|
+
/* @__PURE__ */ jsx3(FieldLabel, { htmlFor: "sign-up-password", children: t("form.passwordLabel") }),
|
|
326
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
327
|
+
/* @__PURE__ */ jsx3(
|
|
328
|
+
Input,
|
|
329
|
+
{
|
|
330
|
+
...field,
|
|
331
|
+
id: "sign-up-password",
|
|
332
|
+
type: showPassword ? "text" : "password",
|
|
333
|
+
placeholder: t("form.passwordPlaceholder"),
|
|
334
|
+
"aria-invalid": fieldState.invalid
|
|
335
|
+
}
|
|
336
|
+
),
|
|
337
|
+
/* @__PURE__ */ jsx3(
|
|
338
|
+
"button",
|
|
339
|
+
{
|
|
340
|
+
type: "button",
|
|
341
|
+
onClick: () => setShowPassword(!showPassword),
|
|
342
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
343
|
+
children: showPassword ? /* @__PURE__ */ jsx3(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(IconEye, { className: "h-4 w-4" })
|
|
344
|
+
}
|
|
345
|
+
)
|
|
346
|
+
] }),
|
|
347
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
348
|
+
] })
|
|
349
|
+
}
|
|
350
|
+
),
|
|
351
|
+
/* @__PURE__ */ jsx3(
|
|
352
|
+
Controller,
|
|
353
|
+
{
|
|
354
|
+
name: "confirmPassword",
|
|
355
|
+
control: form.control,
|
|
356
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
357
|
+
/* @__PURE__ */ jsx3(FieldLabel, { htmlFor: "sign-up-confirmPassword", children: t("form.confirmPasswordLabel") }),
|
|
358
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
359
|
+
/* @__PURE__ */ jsx3(
|
|
360
|
+
Input,
|
|
361
|
+
{
|
|
362
|
+
...field,
|
|
363
|
+
id: "sign-up-confirmPassword",
|
|
364
|
+
type: showConfirmPassword ? "text" : "password",
|
|
365
|
+
placeholder: t("form.passwordPlaceholder"),
|
|
366
|
+
"aria-invalid": fieldState.invalid
|
|
367
|
+
}
|
|
368
|
+
),
|
|
369
|
+
/* @__PURE__ */ jsx3(
|
|
370
|
+
"button",
|
|
371
|
+
{
|
|
372
|
+
type: "button",
|
|
373
|
+
onClick: () => setShowConfirmPassword(!showConfirmPassword),
|
|
374
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
375
|
+
children: showConfirmPassword ? /* @__PURE__ */ jsx3(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(IconEye, { className: "h-4 w-4" })
|
|
376
|
+
}
|
|
377
|
+
)
|
|
378
|
+
] }),
|
|
379
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
380
|
+
] })
|
|
381
|
+
}
|
|
382
|
+
)
|
|
383
|
+
] }),
|
|
384
|
+
/* @__PURE__ */ jsx3("div", { className: "mt-4", children: /* @__PURE__ */ jsx3(
|
|
385
|
+
Button,
|
|
386
|
+
{
|
|
387
|
+
type: "submit",
|
|
388
|
+
form: "sign-up-form",
|
|
389
|
+
className: "w-full",
|
|
390
|
+
disabled: isLoading,
|
|
391
|
+
children: isLoading ? t("form.submitting") : t("form.submit")
|
|
326
392
|
}
|
|
327
|
-
)
|
|
328
|
-
|
|
329
|
-
] }) });
|
|
393
|
+
) })
|
|
394
|
+
] });
|
|
330
395
|
};
|
|
331
396
|
|
|
332
397
|
// src/components/auth/pages/sign-up-page.tsx
|
|
@@ -334,33 +399,48 @@ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
|
334
399
|
var isPhone2 = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
|
|
335
400
|
var SignUpPage = ({
|
|
336
401
|
redirectUrl,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}) => {
|
|
343
|
-
const t = useTranslations2("Auth.signUp");
|
|
344
|
-
const { client, setAuth } = useAuth();
|
|
402
|
+
initialIdentifier
|
|
403
|
+
} = {}) => {
|
|
404
|
+
const { hooks, setAuth } = useApi();
|
|
405
|
+
const { config } = useConfig();
|
|
406
|
+
const t = createTranslator(config.messages || {}, "Auth.signUp");
|
|
345
407
|
const [isLoading, setIsLoading] = useState3(false);
|
|
346
408
|
const [error, setError] = useState3(null);
|
|
347
|
-
const
|
|
409
|
+
const signUpMutation = hooks.useMutation("post", "/sign-up");
|
|
410
|
+
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
411
|
+
const Link = config.navigation?.linkComponent;
|
|
412
|
+
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
413
|
+
if (typeof window !== "undefined") {
|
|
414
|
+
window.location.href = path;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
const logoImage = config.ui.logoImage;
|
|
418
|
+
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
419
|
+
useEffect3(() => {
|
|
420
|
+
if (error) {
|
|
421
|
+
toast.error(error.title || "Error", {
|
|
422
|
+
description: error.description
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
}, [error]);
|
|
348
426
|
const handleSubmit = async (values) => {
|
|
349
427
|
setIsLoading(true);
|
|
350
428
|
setError(null);
|
|
351
429
|
try {
|
|
352
430
|
const identifier = values.identifier;
|
|
353
431
|
const usingPhone = isPhone2(identifier);
|
|
354
|
-
const res =
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
432
|
+
const res = await signUpMutation.mutateAsync({
|
|
433
|
+
body: usingPhone ? {
|
|
434
|
+
phone: identifier,
|
|
435
|
+
password: values.password,
|
|
436
|
+
fullName: values.fullName,
|
|
437
|
+
handle: values.handle
|
|
438
|
+
} : {
|
|
439
|
+
email: identifier,
|
|
440
|
+
password: values.password,
|
|
441
|
+
fullName: values.fullName,
|
|
442
|
+
handle: values.handle
|
|
443
|
+
}
|
|
364
444
|
});
|
|
365
445
|
if ("verificationId" in res && res.verificationId) {
|
|
366
446
|
if (usingPhone) {
|
|
@@ -377,19 +457,26 @@ var SignUpPage = ({
|
|
|
377
457
|
if ("user" in res && "session" in res) {
|
|
378
458
|
setAuth(res);
|
|
379
459
|
}
|
|
380
|
-
onNavigate(
|
|
460
|
+
onNavigate(defaultRedirect);
|
|
381
461
|
} catch (err) {
|
|
382
462
|
handleError(err, setError, t);
|
|
383
463
|
} finally {
|
|
384
464
|
setIsLoading(false);
|
|
385
465
|
}
|
|
386
466
|
};
|
|
387
|
-
|
|
467
|
+
let errorContent = null;
|
|
468
|
+
if (error) {
|
|
469
|
+
if (typeof error === "string") {
|
|
470
|
+
errorContent = { title: "Error", description: error };
|
|
471
|
+
} else {
|
|
472
|
+
errorContent = error;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return /* @__PURE__ */ jsxs3(
|
|
388
476
|
AuthPageLayout,
|
|
389
477
|
{
|
|
390
478
|
title: t("title"),
|
|
391
479
|
description: t("description"),
|
|
392
|
-
error,
|
|
393
480
|
logoImage,
|
|
394
481
|
footer: /* @__PURE__ */ jsxs3("p", { children: [
|
|
395
482
|
t("footer.hasAccount"),
|
|
@@ -407,14 +494,21 @@ var SignUpPage = ({
|
|
|
407
494
|
}
|
|
408
495
|
)
|
|
409
496
|
] }),
|
|
410
|
-
children:
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
497
|
+
children: [
|
|
498
|
+
/* @__PURE__ */ jsx4(
|
|
499
|
+
SignUp,
|
|
500
|
+
{
|
|
501
|
+
onSubmit: handleSubmit,
|
|
502
|
+
isLoading: isLoading || signUpMutation.isPending,
|
|
503
|
+
initialIdentifier
|
|
504
|
+
}
|
|
505
|
+
),
|
|
506
|
+
errorContent && /* @__PURE__ */ jsxs3(Alert, { variant: "destructive", className: "mt-4", children: [
|
|
507
|
+
/* @__PURE__ */ jsx4(IconAlertCircle, { className: "h-4 w-4" }),
|
|
508
|
+
/* @__PURE__ */ jsx4(AlertTitle, { children: errorContent.title }),
|
|
509
|
+
/* @__PURE__ */ jsx4(AlertDescription, { children: errorContent.description })
|
|
510
|
+
] })
|
|
511
|
+
]
|
|
418
512
|
}
|
|
419
513
|
);
|
|
420
514
|
};
|