@mesob/auth-react 0.0.3 → 0.0.4

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 (62) hide show
  1. package/dist/components/auth/auth-card.js +11 -0
  2. package/dist/components/auth/auth-card.js.map +1 -0
  3. package/dist/components/{auth-page-layout.d.ts → auth/auth-page-layout.d.ts} +2 -1
  4. package/dist/components/{auth-page-layout.js → auth/auth-page-layout.js} +16 -3
  5. package/dist/components/auth/auth-page-layout.js.map +1 -0
  6. package/dist/components/{countdown.js → auth/countdown.js} +8 -4
  7. package/dist/components/auth/countdown.js.map +1 -0
  8. package/dist/components/{forgot-password.d.ts → auth/forgot-password.d.ts} +1 -1
  9. package/dist/components/{forgot-password.js → auth/forgot-password.js} +7 -4
  10. package/dist/components/auth/forgot-password.js.map +1 -0
  11. package/dist/components/{pages → auth/pages}/forgot-password-page.js +94 -28
  12. package/dist/components/auth/pages/forgot-password-page.js.map +1 -0
  13. package/dist/components/{pages → auth/pages}/reset-password-page.d.ts +2 -1
  14. package/dist/components/{pages → auth/pages}/reset-password-page.js +111 -42
  15. package/dist/components/auth/pages/reset-password-page.js.map +1 -0
  16. package/dist/components/{pages → auth/pages}/sign-in-page.js +130 -30
  17. package/dist/components/auth/pages/sign-in-page.js.map +1 -0
  18. package/dist/components/{pages → auth/pages}/sign-up-page.d.ts +2 -1
  19. package/dist/components/{pages → auth/pages}/sign-up-page.js +93 -29
  20. package/dist/components/auth/pages/sign-up-page.js.map +1 -0
  21. package/dist/components/{pages → auth/pages}/verify-email-page.d.ts +2 -1
  22. package/dist/components/{pages → auth/pages}/verify-email-page.js +131 -61
  23. package/dist/components/auth/pages/verify-email-page.js.map +1 -0
  24. package/dist/components/{pages → auth/pages}/verify-phone-page.d.ts +2 -1
  25. package/dist/components/{pages → auth/pages}/verify-phone-page.js +136 -63
  26. package/dist/components/auth/pages/verify-phone-page.js.map +1 -0
  27. package/dist/components/{reset-password-form.d.ts → auth/reset-password-form.d.ts} +3 -2
  28. package/dist/components/{reset-password-form.js → auth/reset-password-form.js} +17 -15
  29. package/dist/components/auth/reset-password-form.js.map +1 -0
  30. package/dist/components/{sign-in.js → auth/sign-in.js} +43 -6
  31. package/dist/components/auth/sign-in.js.map +1 -0
  32. package/dist/components/{sign-up.js → auth/sign-up.js} +4 -4
  33. package/dist/components/auth/sign-up.js.map +1 -0
  34. package/dist/components/{verification-form.d.ts → auth/verification-form.d.ts} +2 -1
  35. package/dist/components/{verification-form.js → auth/verification-form.js} +33 -33
  36. package/dist/components/auth/verification-form.js.map +1 -0
  37. package/dist/handle-error-H0iqQxJ5.d.ts +6 -0
  38. package/dist/index.d.ts +49 -15
  39. package/dist/index.js +302 -142
  40. package/dist/index.js.map +1 -1
  41. package/package.json +3 -3
  42. package/dist/components/auth-card.js +0 -11
  43. package/dist/components/auth-card.js.map +0 -1
  44. package/dist/components/auth-page-layout.js.map +0 -1
  45. package/dist/components/countdown.js.map +0 -1
  46. package/dist/components/forgot-password.js.map +0 -1
  47. package/dist/components/pages/forgot-password-page.js.map +0 -1
  48. package/dist/components/pages/reset-password-page.js.map +0 -1
  49. package/dist/components/pages/sign-in-page.js.map +0 -1
  50. package/dist/components/pages/sign-up-page.js.map +0 -1
  51. package/dist/components/pages/verify-email-page.js.map +0 -1
  52. package/dist/components/pages/verify-phone-page.js.map +0 -1
  53. package/dist/components/reset-password-form.js.map +0 -1
  54. package/dist/components/sign-in.js.map +0 -1
  55. package/dist/components/sign-up.js.map +0 -1
  56. package/dist/components/verification-form.js.map +0 -1
  57. /package/dist/components/{auth-card.d.ts → auth/auth-card.d.ts} +0 -0
  58. /package/dist/components/{countdown.d.ts → auth/countdown.d.ts} +0 -0
  59. /package/dist/components/{pages → auth/pages}/forgot-password-page.d.ts +0 -0
  60. /package/dist/components/{pages → auth/pages}/sign-in-page.d.ts +0 -0
  61. /package/dist/components/{sign-in.d.ts → auth/sign-in.d.ts} +0 -0
  62. /package/dist/components/{sign-up.d.ts → auth/sign-up.d.ts} +0 -0
package/dist/index.js CHANGED
@@ -145,6 +145,12 @@ var AuthClient = class {
145
145
  body: JSON.stringify(data)
146
146
  });
147
147
  }
148
+ verifyPassword(data) {
149
+ return this.request("/password/verify", {
150
+ method: "POST",
151
+ body: JSON.stringify(data)
152
+ });
153
+ }
148
154
  changePassword(data) {
149
155
  return this.request("/password/change", {
150
156
  method: "POST",
@@ -156,16 +162,47 @@ var AuthClient = class {
156
162
  method: "GET"
157
163
  });
158
164
  }
165
+ getPendingAccountChange() {
166
+ return this.request(
167
+ "/account-change/pending",
168
+ {
169
+ method: "GET"
170
+ }
171
+ );
172
+ }
173
+ updateProfile(data) {
174
+ return this.request("/profile", {
175
+ method: "PUT",
176
+ body: JSON.stringify(data)
177
+ });
178
+ }
179
+ updateEmail(data) {
180
+ return this.request("/profile/email", {
181
+ method: "PUT",
182
+ body: JSON.stringify(data)
183
+ });
184
+ }
185
+ updatePhone(data) {
186
+ return this.request("/profile/phone", {
187
+ method: "PUT",
188
+ body: JSON.stringify(data)
189
+ });
190
+ }
159
191
  };
160
192
 
161
- // src/components/auth-card.tsx
193
+ // src/components/auth/auth-card.tsx
162
194
  import { jsx } from "react/jsx-runtime";
163
195
  var AuthCard = ({ children }) => {
164
- return /* @__PURE__ */ jsx("div", { className: "flex min-h-screen items-center justify-center bg-gradient-to-br from-slate-50 to-slate-100 p-4 dark:from-slate-900 dark:to-slate-800", children: /* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx("div", { className: "rounded-xl border bg-card p-8 shadow-lg", children }) }) });
196
+ return /* @__PURE__ */ jsx("div", { className: "flex min-h-screen p-4 items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx("div", { className: "rounded-xl border bg-card p-8 shadow-lg", children }) }) });
165
197
  };
166
198
 
167
- // src/components/auth-page-layout.tsx
168
- import { Alert, AlertDescription } from "@mesob/ui/components/alert";
199
+ // src/components/auth/auth-page-layout.tsx
200
+ import {
201
+ Alert,
202
+ AlertDescription,
203
+ AlertTitle
204
+ } from "@mesob/ui/components/alert";
205
+ import { IconAlertCircle } from "@tabler/icons-react";
169
206
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
170
207
  var AuthPageLayout = ({
171
208
  title,
@@ -175,6 +212,10 @@ var AuthPageLayout = ({
175
212
  footer,
176
213
  logoImage
177
214
  }) => {
215
+ const errorContent = error ? (
216
+ // biome-ignore lint/style/noNestedTernary: <explanation>
217
+ typeof error === "string" ? { title: "Error", description: error } : error
218
+ ) : null;
178
219
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
179
220
  /* @__PURE__ */ jsx2("div", { className: "flex size-8 mb-6 w-full items-center justify-center rounded-md", children: /* @__PURE__ */ jsx2("img", { src: logoImage || "", alt: "Jiret", width: 42, height: 42 }) }),
180
221
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
@@ -182,16 +223,21 @@ var AuthPageLayout = ({
182
223
  description && /* @__PURE__ */ jsx2("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
183
224
  ] }),
184
225
  children,
185
- error && /* @__PURE__ */ jsx2(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx2(AlertDescription, { children: error }) }),
226
+ errorContent && /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
227
+ /* @__PURE__ */ jsx2(IconAlertCircle, { className: "h-4 w-4" }),
228
+ /* @__PURE__ */ jsx2(AlertTitle, { children: errorContent.title }),
229
+ /* @__PURE__ */ jsx2(AlertDescription, { children: errorContent.description })
230
+ ] }),
186
231
  /* @__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 }) })
187
232
  ] });
188
233
  };
189
234
 
190
- // src/components/countdown.tsx
235
+ // src/components/auth/countdown.tsx
191
236
  import { Button } from "@mesob/ui/components/button";
237
+ import { Spinner } from "@mesob/ui/components/spinner";
192
238
  import { useTranslations } from "next-intl";
193
239
  import { useEffect, useState } from "react";
194
- import { jsx as jsx3 } from "react/jsx-runtime";
240
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
195
241
  var Countdown = ({
196
242
  initialSeconds = 60,
197
243
  onResend,
@@ -228,18 +274,21 @@ var Countdown = ({
228
274
  if (seconds > 0) {
229
275
  return /* @__PURE__ */ jsx3(Button, { variant: "ghost", disabled: true, children: t("resendIn", { seconds }) });
230
276
  }
231
- return /* @__PURE__ */ jsx3(
277
+ return /* @__PURE__ */ jsxs2(
232
278
  Button,
233
279
  {
234
280
  variant: "ghost",
235
281
  onClick: handleResend,
236
282
  disabled: isResending || resending,
237
- children: isResending || resending ? t("resending") : t("resend")
283
+ children: [
284
+ isResending || resending && /* @__PURE__ */ jsx3(Spinner, {}),
285
+ t("resend")
286
+ ]
238
287
  }
239
288
  );
240
289
  };
241
290
 
242
- // src/components/forgot-password.tsx
291
+ // src/components/auth/forgot-password.tsx
243
292
  import { zodResolver } from "@hookform/resolvers/zod";
244
293
  import { Button as Button2 } from "@mesob/ui/components/button";
245
294
  import {
@@ -251,15 +300,15 @@ import {
251
300
  FormMessage
252
301
  } from "@mesob/ui/components/form";
253
302
  import { Input } from "@mesob/ui/components/input";
303
+ import { Spinner as Spinner2 } from "@mesob/ui/components/spinner";
254
304
  import { useTranslations as useTranslations2 } from "next-intl";
255
305
  import { useMemo } from "react";
256
306
  import { useForm } from "react-hook-form";
257
307
  import { z } from "zod";
258
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
308
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
259
309
  var ForgotPassword = ({
260
310
  onSubmit,
261
- isLoading = false,
262
- onBack
311
+ isLoading = false
263
312
  }) => {
264
313
  const t = useTranslations2("Auth.forgotPassword");
265
314
  const forgotPasswordSchema = useMemo(
@@ -277,13 +326,13 @@ var ForgotPassword = ({
277
326
  const handleSubmit = form.handleSubmit(async (values) => {
278
327
  await onSubmit(values);
279
328
  });
280
- return /* @__PURE__ */ jsx4(Form, { ...form, children: /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, className: "space-y-5", children: [
329
+ return /* @__PURE__ */ jsx4(Form, { ...form, children: /* @__PURE__ */ jsxs3("form", { onSubmit: handleSubmit, className: "space-y-5", children: [
281
330
  /* @__PURE__ */ jsx4(
282
331
  FormField,
283
332
  {
284
333
  control: form.control,
285
334
  name: "account",
286
- render: ({ field }) => /* @__PURE__ */ jsxs2(FormItem, { children: [
335
+ render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem, { children: [
287
336
  /* @__PURE__ */ jsx4(FormLabel, { children: t("form.accountLabel") }),
288
337
  /* @__PURE__ */ jsx4(FormControl, { children: /* @__PURE__ */ jsx4(
289
338
  Input,
@@ -297,11 +346,14 @@ var ForgotPassword = ({
297
346
  ] })
298
347
  }
299
348
  ),
300
- /* @__PURE__ */ jsx4(Button2, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? t("form.submitting") : t("form.submit") })
349
+ /* @__PURE__ */ jsxs3(Button2, { type: "submit", className: "w-full", disabled: isLoading, children: [
350
+ isLoading && /* @__PURE__ */ jsx4(Spinner2, {}),
351
+ isLoading ? t("form.submitting") : t("form.submit")
352
+ ] })
301
353
  ] }) });
302
354
  };
303
355
 
304
- // src/components/pages/forgot-password-page.tsx
356
+ // src/components/auth/pages/forgot-password-page.tsx
305
357
  import { useTranslations as useTranslations3 } from "next-intl";
306
358
  import { useState as useState3 } from "react";
307
359
 
@@ -371,39 +423,89 @@ var AuthProvider = ({ client, children }) => {
371
423
  };
372
424
 
373
425
  // src/constants/auth.error.codes.ts
374
- var validCodes = [
375
- "USER_NOT_FOUND",
376
- "INVALID_PASSWORD",
377
- "USER_EXISTS",
378
- "VERIFICATION_EXPIRED",
379
- "VERIFICATION_MISMATCH",
380
- "VERIFICATION_NOT_FOUND",
381
- "TOO_MANY_ATTEMPTS",
382
- "REQUIRES_VERIFICATION",
383
- "UNAUTHORIZED",
384
- "ACCESS_DENIED",
385
- "HAS_NO_PASSWORD"
386
- ];
426
+ var AUTH_ERROR_MAPPING = {
427
+ USER_NOT_FOUND: {
428
+ title: "Account Not Found",
429
+ description: "We could not find an account with that identifier. Please check your spelling or sign up."
430
+ },
431
+ INVALID_PASSWORD: {
432
+ title: "Invalid Password",
433
+ description: "The password you entered is incorrect. Please try again."
434
+ },
435
+ USER_EXISTS: {
436
+ title: "Account Already Exists",
437
+ description: "An account with this identifier already exists. Please sign in instead."
438
+ },
439
+ VERIFICATION_EXPIRED: {
440
+ title: "Verification Expired",
441
+ description: "The verification code or link has expired. Please request a new one."
442
+ },
443
+ VERIFICATION_MISMATCH: {
444
+ title: "Invalid Code",
445
+ description: "The verification code you entered is invalid. Please double-check and try again."
446
+ },
447
+ VERIFICATION_NOT_FOUND: {
448
+ title: "Verification Not Found",
449
+ description: "We could not find a pending verification request. Please restart the process."
450
+ },
451
+ TOO_MANY_ATTEMPTS: {
452
+ title: "Too Many Attempts",
453
+ description: "You have made too many requests recently. Please wait a moment before trying again."
454
+ },
455
+ REQUIRES_VERIFICATION: {
456
+ title: "Verification Required",
457
+ description: "You need to verify your account before you can continue. Please check your email or phone."
458
+ },
459
+ UNAUTHORIZED: {
460
+ title: "Unauthorized",
461
+ description: "You are not authorized to perform this action. Please sign in again."
462
+ },
463
+ ACCESS_DENIED: {
464
+ title: "Access Denied",
465
+ description: "You do not have permission to access this resource. Please contact support if you believe this is an error."
466
+ },
467
+ HAS_NO_PASSWORD: {
468
+ title: "No Password Set",
469
+ description: "Your account does not have a password set (e.g. social login). Please sign in with your provider or reset your password."
470
+ }
471
+ };
472
+ var validCodes = Object.keys(AUTH_ERROR_MAPPING);
387
473
 
388
474
  // src/utils/handle-error.ts
389
475
  var handleError = (err, setError, t) => {
390
476
  if (err instanceof AuthError) {
391
- let errorKey = "errors.fallback";
392
- if (err.code) {
393
- errorKey = `errors.${err.code.toLowerCase()}`;
477
+ let errorCode = "";
478
+ if (err.code && validCodes.includes(err.code)) {
479
+ errorCode = err.code;
394
480
  } else if (err.message) {
395
481
  const messageUpper = err.message.toUpperCase().trim();
396
482
  if (validCodes.includes(messageUpper)) {
397
- errorKey = `errors.${messageUpper.toLowerCase()}`;
483
+ errorCode = messageUpper;
398
484
  }
399
485
  }
400
- setError(t(errorKey, { defaultValue: err.message }));
486
+ if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {
487
+ const mapping = AUTH_ERROR_MAPPING[errorCode];
488
+ setError({
489
+ title: mapping.title,
490
+ description: mapping.description
491
+ });
492
+ return;
493
+ }
494
+ setError({
495
+ title: t("errors.fallback"),
496
+ // or 'Error'
497
+ description: err.message || t("errors.fallback")
498
+ });
401
499
  } else {
402
- setError(err instanceof Error ? err.message : t("errors.fallback"));
500
+ const message = err instanceof Error ? err.message : t("errors.fallback");
501
+ setError({
502
+ title: "Error",
503
+ description: message
504
+ });
403
505
  }
404
506
  };
405
507
 
406
- // src/components/pages/forgot-password-page.tsx
508
+ // src/components/auth/pages/forgot-password-page.tsx
407
509
  import { jsx as jsx6 } from "react/jsx-runtime";
408
510
  var ForgotPasswordPage = ({
409
511
  onNavigate,
@@ -468,11 +570,11 @@ var ForgotPasswordPage = ({
468
570
  );
469
571
  };
470
572
 
471
- // src/components/pages/reset-password-page.tsx
573
+ // src/components/auth/pages/reset-password-page.tsx
472
574
  import { useTranslations as useTranslations5 } from "next-intl";
473
575
  import { useState as useState5 } from "react";
474
576
 
475
- // src/components/reset-password-form.tsx
577
+ // src/components/auth/reset-password-form.tsx
476
578
  import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
477
579
  import { Button as Button3 } from "@mesob/ui/components/button";
478
580
  import {
@@ -489,17 +591,16 @@ import {
489
591
  InputOTPGroup,
490
592
  InputOTPSlot
491
593
  } from "@mesob/ui/components/input-otp";
492
- import { Eye, EyeOff } from "lucide-react";
594
+ import { Spinner as Spinner3 } from "@mesob/ui/components/spinner";
595
+ import { IconEye, IconEyeOff } from "@tabler/icons-react";
493
596
  import { useTranslations as useTranslations4 } from "next-intl";
494
597
  import { useMemo as useMemo2, useState as useState4 } from "react";
495
598
  import { useForm as useForm2 } from "react-hook-form";
496
599
  import { z as z2 } from "zod";
497
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
600
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
498
601
  var ResetPasswordForm = ({
499
- verificationId,
500
602
  onSubmit,
501
- isLoading = false,
502
- error
603
+ isLoading = false
503
604
  }) => {
504
605
  const t = useTranslations4("Auth.resetPassword");
505
606
  const [showPassword, setShowPassword] = useState4(false);
@@ -525,21 +626,21 @@ var ResetPasswordForm = ({
525
626
  const handleSubmit = form.handleSubmit(async (values) => {
526
627
  await onSubmit(values);
527
628
  });
528
- return /* @__PURE__ */ jsx7(Form2, { ...form, children: /* @__PURE__ */ jsxs3("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
629
+ return /* @__PURE__ */ jsx7(Form2, { ...form, children: /* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
529
630
  /* @__PURE__ */ jsx7(
530
631
  FormField2,
531
632
  {
532
633
  control: form.control,
533
634
  name: "code",
534
- render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem2, { children: [
635
+ render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem2, { children: [
535
636
  /* @__PURE__ */ jsx7("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx7(FormLabel2, { children: t("form.codeLabel") }) }),
536
- /* @__PURE__ */ jsx7(FormControl2, { children: /* @__PURE__ */ jsx7("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx7(InputOTP, { maxLength: 6, ...field, children: /* @__PURE__ */ jsxs3(InputOTPGroup, { children: [
537
- /* @__PURE__ */ jsx7(InputOTPSlot, { index: 0 }),
538
- /* @__PURE__ */ jsx7(InputOTPSlot, { index: 1 }),
539
- /* @__PURE__ */ jsx7(InputOTPSlot, { index: 2 }),
540
- /* @__PURE__ */ jsx7(InputOTPSlot, { index: 3 }),
541
- /* @__PURE__ */ jsx7(InputOTPSlot, { index: 4 }),
542
- /* @__PURE__ */ jsx7(InputOTPSlot, { index: 5 })
637
+ /* @__PURE__ */ jsx7(FormControl2, { children: /* @__PURE__ */ jsx7("div", { className: "flex mt-2 justify-center", children: /* @__PURE__ */ jsx7(InputOTP, { maxLength: 6, ...field, containerClassName: "gap-4", children: /* @__PURE__ */ jsxs4(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: [
638
+ /* @__PURE__ */ jsx7(InputOTPSlot, { className: "h-12", index: 0 }),
639
+ /* @__PURE__ */ jsx7(InputOTPSlot, { className: "h-12", index: 1 }),
640
+ /* @__PURE__ */ jsx7(InputOTPSlot, { className: "h-12", index: 2 }),
641
+ /* @__PURE__ */ jsx7(InputOTPSlot, { className: "h-12", index: 3 }),
642
+ /* @__PURE__ */ jsx7(InputOTPSlot, { className: "h-12", index: 4 }),
643
+ /* @__PURE__ */ jsx7(InputOTPSlot, { className: "h-12", index: 5 })
543
644
  ] }) }) }) }),
544
645
  /* @__PURE__ */ jsx7(FormMessage2, {})
545
646
  ] })
@@ -550,9 +651,9 @@ var ResetPasswordForm = ({
550
651
  {
551
652
  control: form.control,
552
653
  name: "password",
553
- render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem2, { children: [
654
+ render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem2, { children: [
554
655
  /* @__PURE__ */ jsx7(FormLabel2, { children: t("form.passwordLabel") }),
555
- /* @__PURE__ */ jsx7(FormControl2, { children: /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
656
+ /* @__PURE__ */ jsx7(FormControl2, { children: /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
556
657
  /* @__PURE__ */ jsx7(
557
658
  Input2,
558
659
  {
@@ -567,7 +668,7 @@ var ResetPasswordForm = ({
567
668
  type: "button",
568
669
  onClick: () => setShowPassword(!showPassword),
569
670
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
570
- children: showPassword ? /* @__PURE__ */ jsx7(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(Eye, { className: "h-4 w-4" })
671
+ children: showPassword ? /* @__PURE__ */ jsx7(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(IconEye, { className: "h-4 w-4" })
571
672
  }
572
673
  )
573
674
  ] }) }),
@@ -580,9 +681,9 @@ var ResetPasswordForm = ({
580
681
  {
581
682
  control: form.control,
582
683
  name: "confirmPassword",
583
- render: ({ field }) => /* @__PURE__ */ jsxs3(FormItem2, { children: [
684
+ render: ({ field }) => /* @__PURE__ */ jsxs4(FormItem2, { children: [
584
685
  /* @__PURE__ */ jsx7(FormLabel2, { children: t("form.confirmPasswordLabel") }),
585
- /* @__PURE__ */ jsx7(FormControl2, { children: /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
686
+ /* @__PURE__ */ jsx7(FormControl2, { children: /* @__PURE__ */ jsxs4("div", { className: "relative", children: [
586
687
  /* @__PURE__ */ jsx7(
587
688
  Input2,
588
689
  {
@@ -597,7 +698,7 @@ var ResetPasswordForm = ({
597
698
  type: "button",
598
699
  onClick: () => setShowPassword(!showPassword),
599
700
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
600
- children: showPassword ? /* @__PURE__ */ jsx7(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(Eye, { className: "h-4 w-4" })
701
+ children: showPassword ? /* @__PURE__ */ jsx7(IconEyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(IconEye, { className: "h-4 w-4" })
601
702
  }
602
703
  )
603
704
  ] }) }),
@@ -605,18 +706,22 @@ var ResetPasswordForm = ({
605
706
  ] })
606
707
  }
607
708
  ),
608
- /* @__PURE__ */ jsx7(Button3, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? t("form.submitting") : t("form.submit") })
709
+ /* @__PURE__ */ jsxs4(Button3, { type: "submit", className: "w-full", disabled: isLoading, children: [
710
+ isLoading && /* @__PURE__ */ jsx7(Spinner3, {}),
711
+ isLoading ? t("form.submitting") : t("form.submit")
712
+ ] })
609
713
  ] }) });
610
714
  };
611
715
 
612
- // src/components/pages/reset-password-page.tsx
613
- import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
716
+ // src/components/auth/pages/reset-password-page.tsx
717
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
614
718
  var ResetPasswordPage = ({
615
719
  verificationId,
616
720
  onNavigate,
617
721
  linkComponent: Link,
618
722
  links,
619
- logoImage
723
+ logoImage,
724
+ redirectUrl
620
725
  }) => {
621
726
  const t = useTranslations5("Auth.resetPassword");
622
727
  const common = useTranslations5("Common");
@@ -627,7 +732,10 @@ var ResetPasswordPage = ({
627
732
  const forgotPasswordLink = links?.forgotPassword || "/auth/forgot-password";
628
733
  const handleSubmit = async (values) => {
629
734
  if (!verificationId) {
630
- setError(t("errors.missingVerificationId"));
735
+ setError({
736
+ title: t("errors.fallback"),
737
+ description: t("errors.missingVerificationId")
738
+ });
631
739
  return;
632
740
  }
633
741
  setIsLoading(true);
@@ -639,7 +747,7 @@ var ResetPasswordPage = ({
639
747
  password: values.password
640
748
  });
641
749
  await refresh();
642
- onNavigate("/dashboard");
750
+ onNavigate(redirectUrl || "/");
643
751
  } catch (err) {
644
752
  handleError(err, setError, t);
645
753
  } finally {
@@ -683,7 +791,7 @@ var ResetPasswordPage = ({
683
791
  description: t("description"),
684
792
  error,
685
793
  logoImage,
686
- footer: Link ? /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between w-full gap-2", children: [
794
+ footer: Link ? /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between w-full gap-2", children: [
687
795
  /* @__PURE__ */ jsx8(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.backToSignIn") }),
688
796
  /* @__PURE__ */ jsx8(
689
797
  Link,
@@ -693,7 +801,7 @@ var ResetPasswordPage = ({
693
801
  children: t("footer.changeAccount")
694
802
  }
695
803
  )
696
- ] }) : /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between w-full gap-2", children: [
804
+ ] }) : /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between w-full gap-2", children: [
697
805
  /* @__PURE__ */ jsx8(
698
806
  "a",
699
807
  {
@@ -732,11 +840,11 @@ var ResetPasswordPage = ({
732
840
  );
733
841
  };
734
842
 
735
- // src/components/pages/sign-in-page.tsx
843
+ // src/components/auth/pages/sign-in-page.tsx
736
844
  import { useTranslations as useTranslations7 } from "next-intl";
737
845
  import { useState as useState7 } from "react";
738
846
 
739
- // src/components/sign-in.tsx
847
+ // src/components/auth/sign-in.tsx
740
848
  import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
741
849
  import { Button as Button4 } from "@mesob/ui/components/button";
742
850
  import {
@@ -748,12 +856,33 @@ import {
748
856
  FormMessage as FormMessage3
749
857
  } from "@mesob/ui/components/form";
750
858
  import { Input as Input3 } from "@mesob/ui/components/input";
751
- import { Eye as Eye2, EyeOff as EyeOff2 } from "lucide-react";
859
+ import { Spinner as Spinner4 } from "@mesob/ui/components/spinner";
860
+ import { IconEye as IconEye2, IconEyeOff as IconEyeOff2 } from "@tabler/icons-react";
752
861
  import { useTranslations as useTranslations6 } from "next-intl";
753
862
  import { useMemo as useMemo3, useState as useState6 } from "react";
754
863
  import { useForm as useForm3 } from "react-hook-form";
755
864
  import { z as z3 } from "zod";
756
- import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
865
+
866
+ // src/utils/normalize-phone.ts
867
+ function normalizePhone(phone) {
868
+ const cleaned = phone.trim().replace(/\s/g, "");
869
+ if (cleaned.startsWith("+2519")) {
870
+ return cleaned;
871
+ }
872
+ if (cleaned.startsWith("2519")) {
873
+ return `+${cleaned}`;
874
+ }
875
+ if (cleaned.startsWith("09")) {
876
+ return `+251${cleaned.slice(1)}`;
877
+ }
878
+ if (cleaned.startsWith("9") && cleaned.length === 9) {
879
+ return `+251${cleaned}`;
880
+ }
881
+ return cleaned;
882
+ }
883
+
884
+ // src/components/auth/sign-in.tsx
885
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
757
886
  var SignIn = ({
758
887
  onSubmit,
759
888
  isLoading = false,
@@ -765,7 +894,17 @@ var SignIn = ({
765
894
  const [showPassword, setShowPassword] = useState6(false);
766
895
  const identifierSchema = useMemo3(
767
896
  () => z3.object({
768
- account: z3.string().min(1, t("errors.accountRequired")).email(t("errors.invalidEmail"))
897
+ account: z3.string().trim().min(1, { message: t("errors.requiredField") }).refine(
898
+ (val) => {
899
+ const isEmail = z3.string().email().safeParse(val).success;
900
+ const phoneRegex = /^(\+2519|2519|09)\d{8}$/;
901
+ const isPhone4 = phoneRegex.test(val);
902
+ return isEmail || isPhone4;
903
+ },
904
+ {
905
+ message: t("errors.invalidEmailOrPhone")
906
+ }
907
+ )
769
908
  }),
770
909
  [t]
771
910
  );
@@ -788,7 +927,9 @@ var SignIn = ({
788
927
  }
789
928
  });
790
929
  const handleIdentifierSubmit = identifierForm.handleSubmit(async (values) => {
791
- await onSubmit({ account: values.account, password: "" }, "identifier");
930
+ const phoneRegex = /^(\+2519|2519|09)\d{8}$/;
931
+ const normalizedAccount = phoneRegex.test(values.account) ? normalizePhone(values.account) : values.account;
932
+ await onSubmit({ account: normalizedAccount, password: "" }, "identifier");
792
933
  });
793
934
  const handlePasswordSubmit = passwordForm.handleSubmit(async (values) => {
794
935
  await onSubmit(
@@ -797,8 +938,8 @@ var SignIn = ({
797
938
  );
798
939
  });
799
940
  if (step === "password") {
800
- return /* @__PURE__ */ jsx9(Form3, { ...passwordForm, children: /* @__PURE__ */ jsxs5("form", { onSubmit: handlePasswordSubmit, className: "space-y-4", children: [
801
- /* @__PURE__ */ jsxs5("div", { className: "text-center", children: [
941
+ return /* @__PURE__ */ jsx9(Form3, { ...passwordForm, children: /* @__PURE__ */ jsxs6("form", { onSubmit: handlePasswordSubmit, className: "space-y-4", children: [
942
+ /* @__PURE__ */ jsxs6("div", { className: "text-center", children: [
802
943
  /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground mb-2", children: t("form.enterPasswordFor") }),
803
944
  /* @__PURE__ */ jsx9("p", { className: "font-bold", children: identifier })
804
945
  ] }),
@@ -807,14 +948,15 @@ var SignIn = ({
807
948
  {
808
949
  control: passwordForm.control,
809
950
  name: "password",
810
- render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem3, { children: [
951
+ render: ({ field }) => /* @__PURE__ */ jsxs6(FormItem3, { children: [
811
952
  /* @__PURE__ */ jsx9(FormLabel3, { children: t("form.passwordLabel") }),
812
- /* @__PURE__ */ jsx9(FormControl3, { children: /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
953
+ /* @__PURE__ */ jsx9(FormControl3, { children: /* @__PURE__ */ jsxs6("div", { className: "relative", children: [
813
954
  /* @__PURE__ */ jsx9(
814
955
  Input3,
815
956
  {
816
957
  type: showPassword ? "text" : "password",
817
958
  placeholder: t("form.passwordPlaceholder"),
959
+ autoComplete: "current-password",
818
960
  ...field
819
961
  }
820
962
  ),
@@ -824,7 +966,7 @@ var SignIn = ({
824
966
  type: "button",
825
967
  onClick: () => setShowPassword(!showPassword),
826
968
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
827
- children: showPassword ? /* @__PURE__ */ jsx9(EyeOff2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx9(Eye2, { className: "h-4 w-4" })
969
+ children: showPassword ? /* @__PURE__ */ jsx9(IconEyeOff2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx9(IconEye2, { className: "h-4 w-4" })
828
970
  }
829
971
  )
830
972
  ] }) }),
@@ -835,13 +977,13 @@ var SignIn = ({
835
977
  /* @__PURE__ */ jsx9(Button4, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? t("form.submitting") : t("form.submit") })
836
978
  ] }) });
837
979
  }
838
- return /* @__PURE__ */ jsx9(Form3, { ...identifierForm, children: /* @__PURE__ */ jsxs5("form", { onSubmit: handleIdentifierSubmit, className: "space-y-4", children: [
980
+ return /* @__PURE__ */ jsx9(Form3, { ...identifierForm, children: /* @__PURE__ */ jsxs6("form", { onSubmit: handleIdentifierSubmit, className: "space-y-4", children: [
839
981
  /* @__PURE__ */ jsx9(
840
982
  FormField3,
841
983
  {
842
984
  control: identifierForm.control,
843
985
  name: "account",
844
- render: ({ field }) => /* @__PURE__ */ jsxs5(FormItem3, { children: [
986
+ render: ({ field }) => /* @__PURE__ */ jsxs6(FormItem3, { children: [
845
987
  /* @__PURE__ */ jsx9(FormLabel3, { children: t("form.accountLabel") }),
846
988
  /* @__PURE__ */ jsx9(FormControl3, { children: /* @__PURE__ */ jsx9(
847
989
  Input3,
@@ -855,12 +997,15 @@ var SignIn = ({
855
997
  ] })
856
998
  }
857
999
  ),
858
- /* @__PURE__ */ jsx9(Button4, { type: "submit", className: "w-full", disabled: isLoading, children: isLoading ? t("form.submitting") : t("form.continue") })
1000
+ /* @__PURE__ */ jsxs6(Button4, { type: "submit", className: "w-full", disabled: isLoading, children: [
1001
+ isLoading && /* @__PURE__ */ jsx9(Spinner4, {}),
1002
+ isLoading ? t("form.submitting") : t("form.continue")
1003
+ ] })
859
1004
  ] }) });
860
1005
  };
861
1006
 
862
- // src/components/pages/sign-in-page.tsx
863
- import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1007
+ // src/components/auth/pages/sign-in-page.tsx
1008
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
864
1009
  var isPhone = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
865
1010
  var SignInPage = ({
866
1011
  redirectUrl,
@@ -934,7 +1079,7 @@ var SignInPage = ({
934
1079
  description: isStepPassword ? void 0 : t("description"),
935
1080
  error,
936
1081
  logoImage,
937
- footer: /* @__PURE__ */ jsxs6(
1082
+ footer: /* @__PURE__ */ jsxs7(
938
1083
  "div",
939
1084
  {
940
1085
  className: "flex items-center justify-center w-full gap-2",
@@ -982,11 +1127,11 @@ var SignInPage = ({
982
1127
  ) });
983
1128
  };
984
1129
 
985
- // src/components/pages/sign-up-page.tsx
1130
+ // src/components/auth/pages/sign-up-page.tsx
986
1131
  import { useTranslations as useTranslations9 } from "next-intl";
987
1132
  import { useState as useState9 } from "react";
988
1133
 
989
- // src/components/sign-up.tsx
1134
+ // src/components/auth/sign-up.tsx
990
1135
  import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
991
1136
  import { Button as Button5 } from "@mesob/ui/components/button";
992
1137
  import {
@@ -998,12 +1143,12 @@ import {
998
1143
  FormMessage as FormMessage4
999
1144
  } from "@mesob/ui/components/form";
1000
1145
  import { Input as Input4 } from "@mesob/ui/components/input";
1001
- import { Eye as Eye3, EyeOff as EyeOff3 } from "lucide-react";
1146
+ import { IconEye as IconEye3, IconEyeOff as IconEyeOff3 } from "@tabler/icons-react";
1002
1147
  import { useTranslations as useTranslations8 } from "next-intl";
1003
1148
  import { useEffect as useEffect3, useMemo as useMemo4, useState as useState8 } from "react";
1004
1149
  import { useForm as useForm4 } from "react-hook-form";
1005
1150
  import { z as z4 } from "zod";
1006
- import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
1151
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
1007
1152
  var isPhone2 = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
1008
1153
  var SignUp = ({
1009
1154
  onSubmit,
@@ -1063,13 +1208,13 @@ var SignUp = ({
1063
1208
  return t("form.phoneLabel");
1064
1209
  };
1065
1210
  const identifierLabel = getIdentifierLabel();
1066
- return /* @__PURE__ */ jsx11(Form4, { ...form, children: /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1211
+ return /* @__PURE__ */ jsx11(Form4, { ...form, children: /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1067
1212
  /* @__PURE__ */ jsx11(
1068
1213
  FormField4,
1069
1214
  {
1070
1215
  control: form.control,
1071
1216
  name: "fullName",
1072
- render: ({ field }) => /* @__PURE__ */ jsxs7(FormItem4, { children: [
1217
+ render: ({ field }) => /* @__PURE__ */ jsxs8(FormItem4, { children: [
1073
1218
  /* @__PURE__ */ jsx11(FormLabel4, { children: t("form.fullNameLabel") }),
1074
1219
  /* @__PURE__ */ jsx11(FormControl4, { children: /* @__PURE__ */ jsx11(Input4, { placeholder: t("form.fullNamePlaceholder"), ...field }) }),
1075
1220
  /* @__PURE__ */ jsx11(FormMessage4, {})
@@ -1081,7 +1226,7 @@ var SignUp = ({
1081
1226
  {
1082
1227
  control: form.control,
1083
1228
  name: "identifier",
1084
- render: ({ field }) => /* @__PURE__ */ jsxs7(FormItem4, { children: [
1229
+ render: ({ field }) => /* @__PURE__ */ jsxs8(FormItem4, { children: [
1085
1230
  /* @__PURE__ */ jsx11(FormLabel4, { className: hasInitialIdentifier ? "block" : void 0, children: identifierLabel }),
1086
1231
  /* @__PURE__ */ jsx11(FormControl4, { children: /* @__PURE__ */ jsx11(
1087
1232
  Input4,
@@ -1101,9 +1246,9 @@ var SignUp = ({
1101
1246
  {
1102
1247
  control: form.control,
1103
1248
  name: "password",
1104
- render: ({ field }) => /* @__PURE__ */ jsxs7(FormItem4, { children: [
1249
+ render: ({ field }) => /* @__PURE__ */ jsxs8(FormItem4, { children: [
1105
1250
  /* @__PURE__ */ jsx11(FormLabel4, { children: t("form.passwordLabel") }),
1106
- /* @__PURE__ */ jsx11(FormControl4, { children: /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
1251
+ /* @__PURE__ */ jsx11(FormControl4, { children: /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
1107
1252
  /* @__PURE__ */ jsx11(
1108
1253
  Input4,
1109
1254
  {
@@ -1118,7 +1263,7 @@ var SignUp = ({
1118
1263
  type: "button",
1119
1264
  onClick: () => setShowPassword(!showPassword),
1120
1265
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
1121
- children: showPassword ? /* @__PURE__ */ jsx11(EyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx11(Eye3, { className: "h-4 w-4" })
1266
+ children: showPassword ? /* @__PURE__ */ jsx11(IconEyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx11(IconEye3, { className: "h-4 w-4" })
1122
1267
  }
1123
1268
  )
1124
1269
  ] }) }),
@@ -1131,9 +1276,9 @@ var SignUp = ({
1131
1276
  {
1132
1277
  control: form.control,
1133
1278
  name: "confirmPassword",
1134
- render: ({ field }) => /* @__PURE__ */ jsxs7(FormItem4, { children: [
1279
+ render: ({ field }) => /* @__PURE__ */ jsxs8(FormItem4, { children: [
1135
1280
  /* @__PURE__ */ jsx11(FormLabel4, { children: t("form.confirmPasswordLabel") }),
1136
- /* @__PURE__ */ jsx11(FormControl4, { children: /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
1281
+ /* @__PURE__ */ jsx11(FormControl4, { children: /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
1137
1282
  /* @__PURE__ */ jsx11(
1138
1283
  Input4,
1139
1284
  {
@@ -1148,7 +1293,7 @@ var SignUp = ({
1148
1293
  type: "button",
1149
1294
  onClick: () => setShowConfirmPassword(!showConfirmPassword),
1150
1295
  className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
1151
- children: showConfirmPassword ? /* @__PURE__ */ jsx11(EyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx11(Eye3, { className: "h-4 w-4" })
1296
+ children: showConfirmPassword ? /* @__PURE__ */ jsx11(IconEyeOff3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx11(IconEye3, { className: "h-4 w-4" })
1152
1297
  }
1153
1298
  )
1154
1299
  ] }) }),
@@ -1160,10 +1305,11 @@ var SignUp = ({
1160
1305
  ] }) });
1161
1306
  };
1162
1307
 
1163
- // src/components/pages/sign-up-page.tsx
1164
- import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
1308
+ // src/components/auth/pages/sign-up-page.tsx
1309
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
1165
1310
  var isPhone3 = (s) => /^\+?[0-9()[\]\s-]{6,}$/.test(s);
1166
1311
  var SignUpPage = ({
1312
+ redirectUrl,
1167
1313
  onNavigate,
1168
1314
  linkComponent: Link,
1169
1315
  links,
@@ -1207,7 +1353,7 @@ var SignUpPage = ({
1207
1353
  if ("user" in res && "session" in res) {
1208
1354
  setAuth(res);
1209
1355
  }
1210
- onNavigate("/dashboard");
1356
+ onNavigate(redirectUrl || "/");
1211
1357
  } catch (err) {
1212
1358
  handleError(err, setError, t);
1213
1359
  } finally {
@@ -1221,7 +1367,7 @@ var SignUpPage = ({
1221
1367
  description: t("description"),
1222
1368
  error,
1223
1369
  logoImage,
1224
- footer: /* @__PURE__ */ jsxs8("p", { children: [
1370
+ footer: /* @__PURE__ */ jsxs9("p", { children: [
1225
1371
  t("footer.hasAccount"),
1226
1372
  " ",
1227
1373
  Link ? /* @__PURE__ */ jsx12(Link, { href: signInLink, className: "text-primary hover:underline", children: t("footer.signInCta") }) : /* @__PURE__ */ jsx12(
@@ -1249,11 +1395,11 @@ var SignUpPage = ({
1249
1395
  );
1250
1396
  };
1251
1397
 
1252
- // src/components/pages/verify-email-page.tsx
1398
+ // src/components/auth/pages/verify-email-page.tsx
1253
1399
  import { useTranslations as useTranslations11 } from "next-intl";
1254
1400
  import { useState as useState10 } from "react";
1255
1401
 
1256
- // src/components/verification-form.tsx
1402
+ // src/components/auth/verification-form.tsx
1257
1403
  import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
1258
1404
  import { Button as Button6 } from "@mesob/ui/components/button";
1259
1405
  import {
@@ -1268,11 +1414,12 @@ import {
1268
1414
  InputOTPGroup as InputOTPGroup2,
1269
1415
  InputOTPSlot as InputOTPSlot2
1270
1416
  } from "@mesob/ui/components/input-otp";
1417
+ import { Spinner as Spinner5 } from "@mesob/ui/components/spinner";
1271
1418
  import { useTranslations as useTranslations10 } from "next-intl";
1272
1419
  import { useMemo as useMemo5 } from "react";
1273
1420
  import { useForm as useForm5 } from "react-hook-form";
1274
1421
  import { z as z5 } from "zod";
1275
- import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
1422
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1276
1423
  var VerificationForm = ({
1277
1424
  onSubmit,
1278
1425
  onResend,
@@ -1291,38 +1438,30 @@ var VerificationForm = ({
1291
1438
  code: ""
1292
1439
  }
1293
1440
  });
1294
- const handleComplete = async (value) => {
1295
- const valid = await form.trigger("code");
1296
- if (valid) {
1297
- await onSubmit({ code: value });
1298
- }
1299
- };
1300
- return /* @__PURE__ */ jsx13(Form5, { ...form, children: /* @__PURE__ */ jsxs9("form", { className: "space-y-4", children: [
1441
+ return /* @__PURE__ */ jsx13(Form5, { ...form, children: /* @__PURE__ */ jsxs10("form", { className: "space-y-4", children: [
1301
1442
  /* @__PURE__ */ jsx13(
1302
1443
  FormField5,
1303
1444
  {
1304
1445
  control: form.control,
1305
1446
  name: "code",
1306
- render: ({ field }) => /* @__PURE__ */ jsxs9(FormItem5, { children: [
1447
+ render: ({ field }) => /* @__PURE__ */ jsxs10(FormItem5, { children: [
1307
1448
  /* @__PURE__ */ jsx13(FormControl5, { children: /* @__PURE__ */ jsx13("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx13(
1308
1449
  InputOTP2,
1309
1450
  {
1310
1451
  maxLength: 6,
1311
- value: field.value,
1312
- onChange: (value) => {
1313
- field.onChange(value);
1314
- if (value.length === 6) {
1315
- handleComplete(value);
1316
- }
1317
- },
1318
- disabled: isLoading,
1319
- children: /* @__PURE__ */ jsxs9(InputOTPGroup2, { children: [
1320
- /* @__PURE__ */ jsx13(InputOTPSlot2, { index: 0 }),
1321
- /* @__PURE__ */ jsx13(InputOTPSlot2, { index: 1 }),
1322
- /* @__PURE__ */ jsx13(InputOTPSlot2, { index: 2 }),
1323
- /* @__PURE__ */ jsx13(InputOTPSlot2, { index: 3 }),
1324
- /* @__PURE__ */ jsx13(InputOTPSlot2, { index: 4 }),
1325
- /* @__PURE__ */ jsx13(InputOTPSlot2, { index: 5 })
1452
+ id: "otp",
1453
+ required: true,
1454
+ value: field.value ?? "",
1455
+ onChange: field.onChange,
1456
+ onBlur: field.onBlur,
1457
+ containerClassName: "gap-4 justify-center mb-2 flex items-center",
1458
+ children: /* @__PURE__ */ jsxs10(InputOTPGroup2, { 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: [
1459
+ /* @__PURE__ */ jsx13(InputOTPSlot2, { className: "h-12", index: 0 }),
1460
+ /* @__PURE__ */ jsx13(InputOTPSlot2, { className: "h-12", index: 1 }),
1461
+ /* @__PURE__ */ jsx13(InputOTPSlot2, { className: "h-12", index: 2 }),
1462
+ /* @__PURE__ */ jsx13(InputOTPSlot2, { className: "h-12", index: 3 }),
1463
+ /* @__PURE__ */ jsx13(InputOTPSlot2, { className: "h-12", index: 4 }),
1464
+ /* @__PURE__ */ jsx13(InputOTPSlot2, { className: "h-12", index: 5 })
1326
1465
  ] })
1327
1466
  }
1328
1467
  ) }) }),
@@ -1330,9 +1469,9 @@ var VerificationForm = ({
1330
1469
  ] })
1331
1470
  }
1332
1471
  ),
1333
- /* @__PURE__ */ jsxs9("div", { className: "flex justify-between items-center", children: [
1472
+ /* @__PURE__ */ jsxs10("div", { className: "flex justify-between items-center", children: [
1334
1473
  /* @__PURE__ */ jsx13(Countdown, { onResend, resending: isLoading }),
1335
- /* @__PURE__ */ jsx13(
1474
+ /* @__PURE__ */ jsxs10(
1336
1475
  Button6,
1337
1476
  {
1338
1477
  type: "button",
@@ -1342,14 +1481,17 @@ var VerificationForm = ({
1342
1481
  })();
1343
1482
  },
1344
1483
  disabled: isLoading || form.watch("code").length !== 6,
1345
- children: t("form.confirm")
1484
+ children: [
1485
+ isLoading && /* @__PURE__ */ jsx13(Spinner5, {}),
1486
+ t("form.confirm")
1487
+ ]
1346
1488
  }
1347
1489
  )
1348
1490
  ] })
1349
1491
  ] }) });
1350
1492
  };
1351
1493
 
1352
- // src/components/pages/verify-email-page.tsx
1494
+ // src/components/auth/pages/verify-email-page.tsx
1353
1495
  import { jsx as jsx14 } from "react/jsx-runtime";
1354
1496
  var VerifyEmailPage = ({
1355
1497
  verificationId,
@@ -1357,7 +1499,8 @@ var VerifyEmailPage = ({
1357
1499
  linkComponent: Link,
1358
1500
  links,
1359
1501
  email,
1360
- logoImage
1502
+ logoImage,
1503
+ redirectUrl
1361
1504
  }) => {
1362
1505
  const t = useTranslations11("Auth.verification");
1363
1506
  const common = useTranslations11("Common");
@@ -1368,7 +1511,10 @@ var VerifyEmailPage = ({
1368
1511
  const signInLink = links?.signIn || "/auth/sign-in";
1369
1512
  const handleSubmit = async (values) => {
1370
1513
  if (!verificationId) {
1371
- setError(t("errors.missingVerificationId"));
1514
+ setError({
1515
+ title: t("errors.fallback"),
1516
+ description: t("errors.missingVerificationId")
1517
+ });
1372
1518
  return;
1373
1519
  }
1374
1520
  setIsLoading(true);
@@ -1381,7 +1527,7 @@ var VerifyEmailPage = ({
1381
1527
  if ("user" in res && "session" in res) {
1382
1528
  setAuth(res);
1383
1529
  }
1384
- onNavigate("/dashboard");
1530
+ onNavigate(redirectUrl || "/");
1385
1531
  } catch (err) {
1386
1532
  handleError(err, setError, t);
1387
1533
  } finally {
@@ -1397,7 +1543,10 @@ var VerifyEmailPage = ({
1397
1543
  `/auth/verify-email?verificationId=${res.verificationId}&email=${encodeURIComponent(email)}`
1398
1544
  );
1399
1545
  } else {
1400
- setError(t("errors.resendFailed"));
1546
+ setError({
1547
+ title: t("errors.fallback"),
1548
+ description: t("errors.resendFailed")
1549
+ });
1401
1550
  }
1402
1551
  } catch (err) {
1403
1552
  handleError(err, setError, t);
@@ -1458,7 +1607,7 @@ var VerifyEmailPage = ({
1458
1607
  );
1459
1608
  };
1460
1609
 
1461
- // src/components/pages/verify-phone-page.tsx
1610
+ // src/components/auth/pages/verify-phone-page.tsx
1462
1611
  import { useTranslations as useTranslations12 } from "next-intl";
1463
1612
  import { useState as useState11 } from "react";
1464
1613
  import { jsx as jsx15 } from "react/jsx-runtime";
@@ -1469,7 +1618,8 @@ var VerifyPhonePage = ({
1469
1618
  onNavigate,
1470
1619
  linkComponent: Link,
1471
1620
  links,
1472
- logoImage
1621
+ logoImage,
1622
+ redirectUrl
1473
1623
  }) => {
1474
1624
  const t = useTranslations12("Auth.verification");
1475
1625
  const common = useTranslations12("Common");
@@ -1480,7 +1630,10 @@ var VerifyPhonePage = ({
1480
1630
  const signInLink = links?.signIn || "/auth/sign-in";
1481
1631
  const handleSubmit = async (values) => {
1482
1632
  if (!verificationId) {
1483
- setError(t("errors.fallback"));
1633
+ setError({
1634
+ title: t("errors.fallback"),
1635
+ description: t("errors.fallback")
1636
+ });
1484
1637
  return;
1485
1638
  }
1486
1639
  setIsLoading(true);
@@ -1493,11 +1646,11 @@ var VerifyPhonePage = ({
1493
1646
  });
1494
1647
  if (res && "user" in res && "session" in res && res.session) {
1495
1648
  setAuth(res);
1496
- onNavigate("/dashboard");
1649
+ onNavigate(redirectUrl || "/");
1497
1650
  return;
1498
1651
  }
1499
1652
  await refresh();
1500
- onNavigate("/dashboard");
1653
+ onNavigate(redirectUrl || "/");
1501
1654
  } catch (err) {
1502
1655
  handleError(err, setError, t);
1503
1656
  } finally {
@@ -1509,7 +1662,10 @@ var VerifyPhonePage = ({
1509
1662
  try {
1510
1663
  const targetPhone = context === "sign-up" ? phone : null;
1511
1664
  if (!targetPhone) {
1512
- setError(t("phone.missingPhone"));
1665
+ setError({
1666
+ title: t("errors.fallback"),
1667
+ description: t("phone.missingPhone")
1668
+ });
1513
1669
  return;
1514
1670
  }
1515
1671
  const res = await client.requestPhoneOtp({ phone: targetPhone, context });
@@ -1519,7 +1675,10 @@ var VerifyPhonePage = ({
1519
1675
  );
1520
1676
  return;
1521
1677
  }
1522
- setError(t("phone.resendFailed"));
1678
+ setError({
1679
+ title: t("errors.fallback"),
1680
+ description: t("phone.resendFailed")
1681
+ });
1523
1682
  } catch (err) {
1524
1683
  handleError(err, setError, t);
1525
1684
  }
@@ -1634,6 +1793,7 @@ export {
1634
1793
  VerifyEmailPage,
1635
1794
  VerifyPhonePage,
1636
1795
  createAuthClient,
1796
+ normalizePhone,
1637
1797
  useAuth,
1638
1798
  useSession
1639
1799
  };