@mesob/auth-react 0.0.3 → 0.0.5

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