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