@mesob/auth-react 0.1.0 → 0.2.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 → auth-layout.d.ts} +3 -3
- package/dist/components/auth/{auth-page-layout.js → auth-layout.js} +4 -4
- package/dist/components/auth/auth-layout.js.map +1 -0
- package/dist/components/auth/countdown.js +15 -6
- package/dist/components/auth/countdown.js.map +1 -1
- package/dist/components/auth/forgot-password.d.ts +1 -9
- package/dist/components/auth/forgot-password.js +267 -43
- package/dist/components/auth/forgot-password.js.map +1 -1
- package/dist/components/auth/reset-password-form.d.ts +2 -10
- package/dist/components/auth/reset-password-form.js +366 -118
- package/dist/components/auth/reset-password-form.js.map +1 -1
- package/dist/components/auth/sign-in.d.ts +2 -10
- package/dist/components/auth/sign-in.js +358 -130
- package/dist/components/auth/sign-in.js.map +1 -1
- package/dist/components/auth/sign-up.d.ts +2 -10
- package/dist/components/auth/sign-up.js +379 -131
- package/dist/components/auth/sign-up.js.map +1 -1
- package/dist/components/auth/verification-form.d.ts +2 -16
- package/dist/components/auth/verification-form.js +15 -6
- package/dist/components/auth/verification-form.js.map +1 -1
- package/dist/components/auth/verify-email.d.ts +10 -0
- package/dist/components/auth/{pages/verify-email-page.js → verify-email.js} +54 -34
- package/dist/components/auth/verify-email.js.map +1 -0
- package/dist/components/auth/verify-phone.d.ts +11 -0
- package/dist/components/auth/{pages/verify-phone-page.js → verify-phone.js} +53 -46
- package/dist/components/auth/verify-phone.js.map +1 -0
- package/dist/components/error-boundary.d.ts +2 -2
- package/dist/components/iam/permissions.d.ts +5 -0
- package/dist/components/iam/{permissions/permissions-page.js → permissions.js} +29 -13
- package/dist/components/iam/permissions.js.map +1 -0
- package/dist/components/iam/roles.d.ts +5 -0
- package/dist/components/iam/{roles/roles-page.js → roles.js} +29 -13
- package/dist/components/iam/roles.js.map +1 -0
- package/dist/components/iam/sessions.d.ts +5 -0
- package/dist/components/iam/{sessions/sessions-page.js → sessions.js} +13 -11
- package/dist/components/iam/sessions.js.map +1 -0
- package/dist/components/iam/tenants.d.ts +5 -0
- package/dist/components/iam/{tenants/tenants-page.js → tenants.js} +13 -11
- package/dist/components/iam/tenants.js.map +1 -0
- package/dist/components/iam/users.d.ts +5 -0
- package/dist/components/iam/{users/users-page.js → users.js} +13 -11
- package/dist/components/iam/users.js.map +1 -0
- package/dist/components/profile/account.d.ts +5 -0
- package/dist/components/profile/account.js +66 -0
- package/dist/components/profile/account.js.map +1 -0
- package/dist/components/profile/change-email-form.d.ts +5 -0
- package/dist/components/profile/change-email-form.js +721 -0
- package/dist/components/profile/change-email-form.js.map +1 -0
- package/dist/components/profile/change-password-form.d.ts +5 -0
- package/dist/components/profile/change-password-form.js +256 -0
- package/dist/components/profile/change-password-form.js.map +1 -0
- package/dist/components/profile/change-phone-form.d.ts +5 -0
- package/dist/components/profile/change-phone-form.js +758 -0
- package/dist/components/profile/change-phone-form.js.map +1 -0
- package/dist/components/profile/change-profile.d.ts +9 -0
- package/dist/components/profile/change-profile.js +37 -0
- package/dist/components/profile/change-profile.js.map +1 -0
- package/dist/components/profile/otp-verification-modal.d.ts +15 -0
- package/dist/components/profile/otp-verification-modal.js +261 -0
- package/dist/components/profile/otp-verification-modal.js.map +1 -0
- package/dist/components/profile/request-change-email-form.d.ts +10 -0
- package/dist/components/profile/request-change-email-form.js +293 -0
- package/dist/components/profile/request-change-email-form.js.map +1 -0
- package/dist/components/profile/request-change-phone-form.d.ts +10 -0
- package/dist/components/profile/request-change-phone-form.js +331 -0
- package/dist/components/profile/request-change-phone-form.js.map +1 -0
- package/dist/components/profile/security.d.ts +5 -0
- package/dist/components/profile/security.js +1439 -0
- package/dist/components/profile/security.js.map +1 -0
- package/dist/components/profile/verify-change-email-form.d.ts +11 -0
- package/dist/components/profile/verify-change-email-form.js +402 -0
- package/dist/components/profile/verify-change-email-form.js.map +1 -0
- package/dist/components/profile/verify-change-phone-form.d.ts +11 -0
- package/dist/components/profile/verify-change-phone-form.js +406 -0
- package/dist/components/profile/verify-change-phone-form.js.map +1 -0
- package/dist/components/shared/{data-table/data-table.js → data-table.js} +2 -2
- package/dist/components/shared/data-table.js.map +1 -0
- package/dist/index.d.ts +42 -88
- package/dist/index.js +2297 -1299
- package/dist/index.js.map +1 -1
- package/dist/types-D3s9oE-5.d.ts +75 -0
- package/dist/verification-form-ipSRTtQB.d.ts +22 -0
- package/package.json +3 -2
- package/dist/components/auth/auth-page-layout.js.map +0 -1
- package/dist/components/auth/pages/forgot-password-page.d.ts +0 -6
- package/dist/components/auth/pages/forgot-password-page.js +0 -362
- package/dist/components/auth/pages/forgot-password-page.js.map +0 -1
- package/dist/components/auth/pages/reset-password-page.d.ts +0 -9
- package/dist/components/auth/pages/reset-password-page.js +0 -514
- package/dist/components/auth/pages/reset-password-page.js.map +0 -1
- package/dist/components/auth/pages/sign-in-page.d.ts +0 -8
- package/dist/components/auth/pages/sign-in-page.js +0 -565
- package/dist/components/auth/pages/sign-in-page.js.map +0 -1
- package/dist/components/auth/pages/sign-up-page.d.ts +0 -9
- package/dist/components/auth/pages/sign-up-page.js +0 -518
- package/dist/components/auth/pages/sign-up-page.js.map +0 -1
- package/dist/components/auth/pages/verify-email-page.d.ts +0 -10
- package/dist/components/auth/pages/verify-email-page.js.map +0 -1
- package/dist/components/auth/pages/verify-phone-page.d.ts +0 -11
- package/dist/components/auth/pages/verify-phone-page.js.map +0 -1
- package/dist/components/iam/permissions/permissions-page.d.ts +0 -5
- package/dist/components/iam/permissions/permissions-page.js.map +0 -1
- package/dist/components/iam/roles/roles-page.d.ts +0 -5
- package/dist/components/iam/roles/roles-page.js.map +0 -1
- package/dist/components/iam/sessions/sessions-page.d.ts +0 -5
- package/dist/components/iam/sessions/sessions-page.js.map +0 -1
- package/dist/components/iam/tenants/tenants-page.d.ts +0 -5
- package/dist/components/iam/tenants/tenants-page.js.map +0 -1
- package/dist/components/iam/users/users-page.d.ts +0 -5
- package/dist/components/iam/users/users-page.js.map +0 -1
- package/dist/components/profile/profile-page.d.ts +0 -8
- package/dist/components/profile/profile-page.js +0 -163
- package/dist/components/profile/profile-page.js.map +0 -1
- package/dist/components/shared/data-table/data-table.js.map +0 -1
- package/dist/handle-error-BqDMxnQZ.d.ts +0 -8
- /package/dist/components/shared/{data-table/data-table.d.ts → data-table.d.ts} +0 -0
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
// src/components/auth/sign-up.tsx
|
|
4
4
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
5
|
+
import {
|
|
6
|
+
Alert,
|
|
7
|
+
AlertDescription,
|
|
8
|
+
AlertTitle
|
|
9
|
+
} from "@mesob/ui/components/alert";
|
|
5
10
|
import { Button } from "@mesob/ui/components/button";
|
|
6
11
|
import {
|
|
7
12
|
Field,
|
|
@@ -10,11 +15,16 @@ import {
|
|
|
10
15
|
FieldLabel
|
|
11
16
|
} from "@mesob/ui/components/field";
|
|
12
17
|
import { Input } from "@mesob/ui/components/input";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
18
|
+
import { useMesob as useMesob2 } from "@mesob/ui/components/mesob-context";
|
|
19
|
+
import { IconAlertCircle, IconEye, IconEyeOff } from "@tabler/icons-react";
|
|
20
|
+
import { useEffect, useState as useState2 } from "react";
|
|
15
21
|
import { Controller, useForm } from "react-hook-form";
|
|
22
|
+
import { toast } from "sonner";
|
|
16
23
|
import { z } from "zod";
|
|
17
24
|
|
|
25
|
+
// src/hooks/use-translator.ts
|
|
26
|
+
import { useMesob } from "@mesob/ui/components/mesob-context";
|
|
27
|
+
|
|
18
28
|
// src/lib/translations.ts
|
|
19
29
|
function createTranslator(messages, namespace) {
|
|
20
30
|
return (key, params) => {
|
|
@@ -46,7 +56,12 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
|
46
56
|
import { deepmerge } from "deepmerge-ts";
|
|
47
57
|
import createFetchClient from "openapi-fetch";
|
|
48
58
|
import createClient from "openapi-react-query";
|
|
49
|
-
import { createContext, useContext,
|
|
59
|
+
import { createContext, useContext, useMemo, useState } from "react";
|
|
60
|
+
|
|
61
|
+
// src/utils/cookie.ts
|
|
62
|
+
var isProduction = typeof process !== "undefined" && process.env.NODE_ENV === "production";
|
|
63
|
+
|
|
64
|
+
// src/provider.tsx
|
|
50
65
|
import { jsx } from "react/jsx-runtime";
|
|
51
66
|
var SessionContext = createContext(null);
|
|
52
67
|
var ApiContext = createContext(null);
|
|
@@ -54,13 +69,17 @@ var ConfigContext = createContext(null);
|
|
|
54
69
|
var queryClient = new QueryClient({
|
|
55
70
|
defaultOptions: {
|
|
56
71
|
queries: {
|
|
57
|
-
staleTime: 1e3 * 60 * 5,
|
|
58
|
-
gcTime: 1e3 * 60 * 10,
|
|
59
|
-
retry: 1,
|
|
60
72
|
refetchOnWindowFocus: false
|
|
61
73
|
}
|
|
62
74
|
}
|
|
63
75
|
});
|
|
76
|
+
function useApi() {
|
|
77
|
+
const context = useContext(ApiContext);
|
|
78
|
+
if (!context) {
|
|
79
|
+
throw new Error("useApi must be used within MesobAuthProvider");
|
|
80
|
+
}
|
|
81
|
+
return context;
|
|
82
|
+
}
|
|
64
83
|
function useConfig() {
|
|
65
84
|
const context = useContext(ConfigContext);
|
|
66
85
|
if (!context) {
|
|
@@ -71,12 +90,143 @@ function useConfig() {
|
|
|
71
90
|
|
|
72
91
|
// src/hooks/use-translator.ts
|
|
73
92
|
function useTranslator(namespace) {
|
|
93
|
+
const mesob = useMesob();
|
|
74
94
|
const { config } = useConfig();
|
|
95
|
+
if (mesob?.t) {
|
|
96
|
+
return (key, params) => mesob.t(namespace ? `${namespace}.${key}` : key, params);
|
|
97
|
+
}
|
|
75
98
|
return createTranslator(config.messages || {}, namespace);
|
|
76
99
|
}
|
|
77
100
|
|
|
78
|
-
// src/
|
|
101
|
+
// src/constants/auth.error.codes.ts
|
|
102
|
+
var AUTH_ERROR_MAPPING = {
|
|
103
|
+
USER_NOT_FOUND: {
|
|
104
|
+
title: "Account Not Found",
|
|
105
|
+
description: "We could not find an account with that identifier. Please check your spelling or sign up."
|
|
106
|
+
},
|
|
107
|
+
INVALID_PASSWORD: {
|
|
108
|
+
title: "Invalid Password",
|
|
109
|
+
description: "The password you entered is incorrect. Please try again."
|
|
110
|
+
},
|
|
111
|
+
USER_EXISTS: {
|
|
112
|
+
title: "Account Already Exists",
|
|
113
|
+
description: "An account with this identifier already exists. Please sign in instead."
|
|
114
|
+
},
|
|
115
|
+
VERIFICATION_EXPIRED: {
|
|
116
|
+
title: "Verification Expired",
|
|
117
|
+
description: "The verification code or link has expired. Please request a new one."
|
|
118
|
+
},
|
|
119
|
+
VERIFICATION_MISMATCH: {
|
|
120
|
+
title: "Invalid Code",
|
|
121
|
+
description: "The verification code you entered is invalid. Please double-check and try again."
|
|
122
|
+
},
|
|
123
|
+
VERIFICATION_NOT_FOUND: {
|
|
124
|
+
title: "Verification Not Found",
|
|
125
|
+
description: "We could not find a pending verification request. Please restart the process."
|
|
126
|
+
},
|
|
127
|
+
TOO_MANY_ATTEMPTS: {
|
|
128
|
+
title: "Too Many Attempts",
|
|
129
|
+
description: "You have made too many requests recently. Please wait a moment before trying again."
|
|
130
|
+
},
|
|
131
|
+
REQUIRES_VERIFICATION: {
|
|
132
|
+
title: "Verification Required",
|
|
133
|
+
description: "You need to verify your account before you can continue. Please check your email or phone."
|
|
134
|
+
},
|
|
135
|
+
UNAUTHORIZED: {
|
|
136
|
+
title: "Unauthorized",
|
|
137
|
+
description: "You are not authorized to perform this action. Please sign in again."
|
|
138
|
+
},
|
|
139
|
+
ACCESS_DENIED: {
|
|
140
|
+
title: "Access Denied",
|
|
141
|
+
description: "You do not have permission to access this resource. Please contact support if you believe this is an error."
|
|
142
|
+
},
|
|
143
|
+
HAS_NO_PASSWORD: {
|
|
144
|
+
title: "No Password Set",
|
|
145
|
+
description: "Your account does not have a password set (e.g. social login). Please sign in with your provider or reset your password."
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
var validCodes = Object.keys(AUTH_ERROR_MAPPING);
|
|
149
|
+
|
|
150
|
+
// src/utils/handle-error.ts
|
|
151
|
+
function isAuthError(err) {
|
|
152
|
+
return typeof err === "object" && err !== null && "message" in err && typeof err.message === "string";
|
|
153
|
+
}
|
|
154
|
+
function extractErrorCode(err) {
|
|
155
|
+
if (err.code && validCodes.includes(err.code)) {
|
|
156
|
+
return err.code;
|
|
157
|
+
}
|
|
158
|
+
if (err.message) {
|
|
159
|
+
const messageUpper = err.message.toUpperCase().trim();
|
|
160
|
+
if (validCodes.includes(messageUpper)) {
|
|
161
|
+
return messageUpper;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return "";
|
|
165
|
+
}
|
|
166
|
+
function sanitizeErrorMessage(message) {
|
|
167
|
+
const lowerMessage = message.toLowerCase();
|
|
168
|
+
const isDatabaseError = lowerMessage.includes("failed query") || lowerMessage.includes("select") || lowerMessage.includes("insert") || lowerMessage.includes("update") || lowerMessage.includes("delete") || lowerMessage.includes("from") || lowerMessage.includes("where") || lowerMessage.includes("limit") || lowerMessage.includes("params:") || lowerMessage.includes("query") || message.includes('"iam".') || message.includes('"tenants"') || message.includes('"users"') || message.includes('"sessions"') || message.includes('"accounts"') || lowerMessage.includes("relation") || lowerMessage.includes("column") || lowerMessage.includes("syntax error") || lowerMessage.includes("database") || lowerMessage.includes("postgres") || lowerMessage.includes("sql");
|
|
169
|
+
if (isDatabaseError) {
|
|
170
|
+
return "An error occurred while processing your request";
|
|
171
|
+
}
|
|
172
|
+
return message;
|
|
173
|
+
}
|
|
174
|
+
function handleAuthError(err, setError, t) {
|
|
175
|
+
const errorCode = extractErrorCode(err);
|
|
176
|
+
if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {
|
|
177
|
+
const mapping = AUTH_ERROR_MAPPING[errorCode];
|
|
178
|
+
setError({
|
|
179
|
+
title: mapping.title,
|
|
180
|
+
description: mapping.description
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const sanitizedMessage = sanitizeErrorMessage(
|
|
185
|
+
err.message || t("errors.fallback")
|
|
186
|
+
);
|
|
187
|
+
setError({
|
|
188
|
+
title: t("errors.fallback"),
|
|
189
|
+
description: sanitizedMessage
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function handleGenericError(err, setError, t) {
|
|
193
|
+
const rawMessage = err instanceof Error ? err.message : t("errors.fallback");
|
|
194
|
+
const sanitizedMessage = sanitizeErrorMessage(rawMessage);
|
|
195
|
+
setError({
|
|
196
|
+
title: "Error",
|
|
197
|
+
description: sanitizedMessage
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
var handleError = (err, setError, t) => {
|
|
201
|
+
if (isAuthError(err)) {
|
|
202
|
+
handleAuthError(err, setError, t);
|
|
203
|
+
} else {
|
|
204
|
+
handleGenericError(err, setError, t);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// src/components/auth/auth-layout.tsx
|
|
79
209
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
210
|
+
var AuthLayout = ({
|
|
211
|
+
title,
|
|
212
|
+
description,
|
|
213
|
+
children,
|
|
214
|
+
footer,
|
|
215
|
+
logoImage
|
|
216
|
+
}) => {
|
|
217
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
218
|
+
/* @__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 }) }),
|
|
219
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
220
|
+
/* @__PURE__ */ jsx2("h1", { className: "text-2xl font-bold tracking-tight", children: title }),
|
|
221
|
+
description && /* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
222
|
+
] }),
|
|
223
|
+
children,
|
|
224
|
+
/* @__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 }) })
|
|
225
|
+
] });
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// src/components/auth/sign-up.tsx
|
|
229
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
80
230
|
var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
|
|
81
231
|
var signUpSchema = (t) => z.object({
|
|
82
232
|
fullName: z.string().min(1, t("errors.fullNameRequired")),
|
|
@@ -98,14 +248,28 @@ var signUpSchema = (t) => z.object({
|
|
|
98
248
|
path: ["confirmPassword"]
|
|
99
249
|
});
|
|
100
250
|
var SignUp = ({
|
|
101
|
-
|
|
102
|
-
isLoading = false,
|
|
251
|
+
redirectUrl,
|
|
103
252
|
initialIdentifier
|
|
104
|
-
}) => {
|
|
253
|
+
} = {}) => {
|
|
254
|
+
const { hooks, setAuth } = useApi();
|
|
255
|
+
const { config } = useConfig();
|
|
256
|
+
const mesob = useMesob2();
|
|
105
257
|
const t = useTranslator("Auth.signUp");
|
|
106
|
-
const
|
|
258
|
+
const Link = mesob?.linkComponent ?? config.navigation?.linkComponent;
|
|
259
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
260
|
+
const [error, setError] = useState2(null);
|
|
107
261
|
const [showPassword, setShowPassword] = useState2(false);
|
|
108
262
|
const [showConfirmPassword, setShowConfirmPassword] = useState2(false);
|
|
263
|
+
const signUpMutation = hooks.useMutation("post", "/sign-up");
|
|
264
|
+
const signInLink = config.navigation?.links?.signIn || "/auth/sign-in";
|
|
265
|
+
const onNavigate = config.navigation?.onNavigate || ((path) => {
|
|
266
|
+
if (typeof window !== "undefined") {
|
|
267
|
+
window.location.href = path;
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
const logoImage = config.ui.logoImage;
|
|
271
|
+
const defaultRedirect = redirectUrl || config.navigation?.defaultRedirectUrl || "/";
|
|
272
|
+
const hasInitialIdentifier = !!initialIdentifier;
|
|
109
273
|
const form = useForm({
|
|
110
274
|
resolver: zodResolver(signUpSchema(t)),
|
|
111
275
|
defaultValues: {
|
|
@@ -115,13 +279,58 @@ var SignUp = ({
|
|
|
115
279
|
confirmPassword: ""
|
|
116
280
|
}
|
|
117
281
|
});
|
|
118
|
-
|
|
282
|
+
useEffect(() => {
|
|
119
283
|
if (initialIdentifier) {
|
|
120
284
|
form.setValue("identifier", initialIdentifier);
|
|
121
285
|
}
|
|
122
286
|
}, [initialIdentifier, form]);
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
if (error) {
|
|
289
|
+
toast.error(error.title || "Error", {
|
|
290
|
+
description: error.description
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}, [error]);
|
|
123
294
|
const handleSubmit = form.handleSubmit(async (values) => {
|
|
124
|
-
|
|
295
|
+
setIsLoading(true);
|
|
296
|
+
setError(null);
|
|
297
|
+
try {
|
|
298
|
+
const identifier = values.identifier;
|
|
299
|
+
const usingPhone = isPhone(identifier);
|
|
300
|
+
const res = await signUpMutation.mutateAsync({
|
|
301
|
+
body: usingPhone ? {
|
|
302
|
+
phone: identifier,
|
|
303
|
+
password: values.password,
|
|
304
|
+
fullName: values.fullName,
|
|
305
|
+
handle: values.handle
|
|
306
|
+
} : {
|
|
307
|
+
email: identifier,
|
|
308
|
+
password: values.password,
|
|
309
|
+
fullName: values.fullName,
|
|
310
|
+
handle: values.handle
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
if ("verificationId" in res && res.verificationId) {
|
|
314
|
+
if (usingPhone) {
|
|
315
|
+
onNavigate(
|
|
316
|
+
`/auth/verify-phone?context=sign-up&verificationId=${res.verificationId}&phone=${encodeURIComponent(identifier)}`
|
|
317
|
+
);
|
|
318
|
+
} else {
|
|
319
|
+
onNavigate(
|
|
320
|
+
`/auth/verify-email?verificationId=${res.verificationId}&email=${encodeURIComponent(identifier)}`
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if ("user" in res && "session" in res) {
|
|
326
|
+
setAuth(res);
|
|
327
|
+
}
|
|
328
|
+
onNavigate(defaultRedirect);
|
|
329
|
+
} catch (err) {
|
|
330
|
+
handleError(err, setError, t);
|
|
331
|
+
} finally {
|
|
332
|
+
setIsLoading(false);
|
|
333
|
+
}
|
|
125
334
|
});
|
|
126
335
|
const getIdentifierLabel = () => {
|
|
127
336
|
if (!hasInitialIdentifier) {
|
|
@@ -133,133 +342,172 @@ var SignUp = ({
|
|
|
133
342
|
return t("form.phoneLabel");
|
|
134
343
|
};
|
|
135
344
|
const identifierLabel = getIdentifierLabel();
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
345
|
+
let errorContent = null;
|
|
346
|
+
if (error) {
|
|
347
|
+
if (typeof error === "string") {
|
|
348
|
+
errorContent = { title: "Error", description: error };
|
|
349
|
+
} else {
|
|
350
|
+
errorContent = error;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return /* @__PURE__ */ jsxs2(
|
|
354
|
+
AuthLayout,
|
|
355
|
+
{
|
|
356
|
+
title: t("title"),
|
|
357
|
+
description: t("description"),
|
|
358
|
+
logoImage,
|
|
359
|
+
footer: /* @__PURE__ */ jsxs2("p", { children: [
|
|
360
|
+
t("footer.hasAccount"),
|
|
361
|
+
" ",
|
|
362
|
+
Link ? /* @__PURE__ */ jsx3(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.signInCta") }) : /* @__PURE__ */ jsx3(
|
|
363
|
+
"a",
|
|
364
|
+
{
|
|
365
|
+
href: signInLink,
|
|
366
|
+
onClick: (e) => {
|
|
367
|
+
e.preventDefault();
|
|
368
|
+
onNavigate(signInLink);
|
|
369
|
+
},
|
|
370
|
+
className: "text-primary hover:underline",
|
|
371
|
+
children: t("footer.signInCta")
|
|
372
|
+
}
|
|
373
|
+
)
|
|
374
|
+
] }),
|
|
375
|
+
children: [
|
|
376
|
+
/* @__PURE__ */ jsxs2("form", { id: "sign-up-form", onSubmit: handleSubmit, children: [
|
|
377
|
+
/* @__PURE__ */ jsxs2(FieldGroup, { children: [
|
|
378
|
+
/* @__PURE__ */ jsx3(
|
|
379
|
+
Controller,
|
|
147
380
|
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
381
|
+
name: "fullName",
|
|
382
|
+
control: form.control,
|
|
383
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
384
|
+
/* @__PURE__ */ jsx3(FieldLabel, { htmlFor: "sign-up-fullName", children: t("form.fullNameLabel") }),
|
|
385
|
+
/* @__PURE__ */ jsx3(
|
|
386
|
+
Input,
|
|
387
|
+
{
|
|
388
|
+
...field,
|
|
389
|
+
id: "sign-up-fullName",
|
|
390
|
+
placeholder: t("form.fullNamePlaceholder"),
|
|
391
|
+
"aria-invalid": fieldState.invalid
|
|
392
|
+
}
|
|
393
|
+
),
|
|
394
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
395
|
+
] })
|
|
152
396
|
}
|
|
153
397
|
),
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
),
|
|
158
|
-
/* @__PURE__ */ jsx2(
|
|
159
|
-
Controller,
|
|
160
|
-
{
|
|
161
|
-
name: "identifier",
|
|
162
|
-
control: form.control,
|
|
163
|
-
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs(Field, { "data-invalid": fieldState.invalid, children: [
|
|
164
|
-
/* @__PURE__ */ jsx2(
|
|
165
|
-
FieldLabel,
|
|
398
|
+
/* @__PURE__ */ jsx3(
|
|
399
|
+
Controller,
|
|
166
400
|
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
children:
|
|
401
|
+
name: "identifier",
|
|
402
|
+
control: form.control,
|
|
403
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
404
|
+
/* @__PURE__ */ jsx3(
|
|
405
|
+
FieldLabel,
|
|
406
|
+
{
|
|
407
|
+
htmlFor: "sign-up-identifier",
|
|
408
|
+
className: hasInitialIdentifier ? "block" : void 0,
|
|
409
|
+
children: identifierLabel
|
|
410
|
+
}
|
|
411
|
+
),
|
|
412
|
+
/* @__PURE__ */ jsx3(
|
|
413
|
+
Input,
|
|
414
|
+
{
|
|
415
|
+
...field,
|
|
416
|
+
id: "sign-up-identifier",
|
|
417
|
+
type: field.value.includes("@") ? "email" : "tel",
|
|
418
|
+
placeholder: hasInitialIdentifier ? void 0 : t("form.accountPlaceholder") || "Email or phone number",
|
|
419
|
+
disabled: hasInitialIdentifier,
|
|
420
|
+
"aria-invalid": fieldState.invalid
|
|
421
|
+
}
|
|
422
|
+
),
|
|
423
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
424
|
+
] })
|
|
170
425
|
}
|
|
171
426
|
),
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
|
|
427
|
+
/* @__PURE__ */ jsx3(
|
|
428
|
+
Controller,
|
|
174
429
|
{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
430
|
+
name: "password",
|
|
431
|
+
control: form.control,
|
|
432
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
433
|
+
/* @__PURE__ */ jsx3(FieldLabel, { htmlFor: "sign-up-password", children: t("form.passwordLabel") }),
|
|
434
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
435
|
+
/* @__PURE__ */ jsx3(
|
|
436
|
+
Input,
|
|
437
|
+
{
|
|
438
|
+
...field,
|
|
439
|
+
id: "sign-up-password",
|
|
440
|
+
type: showPassword ? "text" : "password",
|
|
441
|
+
placeholder: t("form.passwordPlaceholder"),
|
|
442
|
+
"aria-invalid": fieldState.invalid
|
|
443
|
+
}
|
|
444
|
+
),
|
|
445
|
+
/* @__PURE__ */ jsx3(
|
|
446
|
+
"button",
|
|
447
|
+
{
|
|
448
|
+
type: "button",
|
|
449
|
+
onClick: () => setShowPassword(!showPassword),
|
|
450
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
451
|
+
children: showPassword ? /* @__PURE__ */ jsx3(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(IconEye, { className: "h-4 w-4" })
|
|
452
|
+
}
|
|
453
|
+
)
|
|
454
|
+
] }),
|
|
455
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
456
|
+
] })
|
|
181
457
|
}
|
|
182
458
|
),
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
),
|
|
237
|
-
/* @__PURE__ */ jsx2(
|
|
238
|
-
"button",
|
|
239
|
-
{
|
|
240
|
-
type: "button",
|
|
241
|
-
onClick: () => setShowConfirmPassword(!showConfirmPassword),
|
|
242
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
243
|
-
children: showConfirmPassword ? /* @__PURE__ */ jsx2(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx2(IconEye, { className: "h-4 w-4" })
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
] }),
|
|
247
|
-
fieldState.invalid && /* @__PURE__ */ jsx2(FieldError, { errors: [fieldState.error] })
|
|
248
|
-
] })
|
|
249
|
-
}
|
|
250
|
-
)
|
|
251
|
-
] }),
|
|
252
|
-
/* @__PURE__ */ jsx2("div", { className: "mt-4", children: /* @__PURE__ */ jsx2(
|
|
253
|
-
Button,
|
|
254
|
-
{
|
|
255
|
-
type: "submit",
|
|
256
|
-
form: "sign-up-form",
|
|
257
|
-
className: "w-full",
|
|
258
|
-
disabled: isLoading,
|
|
259
|
-
children: isLoading ? t("form.submitting") : t("form.submit")
|
|
260
|
-
}
|
|
261
|
-
) })
|
|
262
|
-
] });
|
|
459
|
+
/* @__PURE__ */ jsx3(
|
|
460
|
+
Controller,
|
|
461
|
+
{
|
|
462
|
+
name: "confirmPassword",
|
|
463
|
+
control: form.control,
|
|
464
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2(Field, { "data-invalid": fieldState.invalid, children: [
|
|
465
|
+
/* @__PURE__ */ jsx3(FieldLabel, { htmlFor: "sign-up-confirmPassword", children: t("form.confirmPasswordLabel") }),
|
|
466
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
467
|
+
/* @__PURE__ */ jsx3(
|
|
468
|
+
Input,
|
|
469
|
+
{
|
|
470
|
+
...field,
|
|
471
|
+
id: "sign-up-confirmPassword",
|
|
472
|
+
type: showConfirmPassword ? "text" : "password",
|
|
473
|
+
placeholder: t("form.passwordPlaceholder"),
|
|
474
|
+
"aria-invalid": fieldState.invalid
|
|
475
|
+
}
|
|
476
|
+
),
|
|
477
|
+
/* @__PURE__ */ jsx3(
|
|
478
|
+
"button",
|
|
479
|
+
{
|
|
480
|
+
type: "button",
|
|
481
|
+
onClick: () => setShowConfirmPassword(!showConfirmPassword),
|
|
482
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
483
|
+
children: showConfirmPassword ? /* @__PURE__ */ jsx3(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx3(IconEye, { className: "h-4 w-4" })
|
|
484
|
+
}
|
|
485
|
+
)
|
|
486
|
+
] }),
|
|
487
|
+
fieldState.invalid && /* @__PURE__ */ jsx3(FieldError, { errors: [fieldState.error] })
|
|
488
|
+
] })
|
|
489
|
+
}
|
|
490
|
+
)
|
|
491
|
+
] }),
|
|
492
|
+
/* @__PURE__ */ jsx3("div", { className: "mt-4", children: /* @__PURE__ */ jsx3(
|
|
493
|
+
Button,
|
|
494
|
+
{
|
|
495
|
+
type: "submit",
|
|
496
|
+
form: "sign-up-form",
|
|
497
|
+
className: "w-full",
|
|
498
|
+
disabled: isLoading || signUpMutation.isPending,
|
|
499
|
+
children: isLoading || signUpMutation.isPending ? t("form.submitting") : t("form.submit")
|
|
500
|
+
}
|
|
501
|
+
) })
|
|
502
|
+
] }),
|
|
503
|
+
errorContent && /* @__PURE__ */ jsxs2(Alert, { variant: "destructive", className: "mt-4", children: [
|
|
504
|
+
/* @__PURE__ */ jsx3(IconAlertCircle, { className: "h-4 w-4" }),
|
|
505
|
+
/* @__PURE__ */ jsx3(AlertTitle, { children: errorContent.title }),
|
|
506
|
+
/* @__PURE__ */ jsx3(AlertDescription, { children: errorContent.description })
|
|
507
|
+
] })
|
|
508
|
+
]
|
|
509
|
+
}
|
|
510
|
+
);
|
|
263
511
|
};
|
|
264
512
|
export {
|
|
265
513
|
SignUp
|