@nocios/crudify-ui 1.0.54 → 1.0.56

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 (3) hide show
  1. package/dist/index.js +369 -204
  2. package/dist/index.mjs +369 -204
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -47,7 +47,7 @@ var import_crudify_browser3 = __toESM(require("@nocios/crudify-browser"));
47
47
  __reExport(index_exports, require("@nocios/crudify-browser"), module.exports);
48
48
 
49
49
  // src/components/CrudifyLogin/index.tsx
50
- var import_react8 = require("react");
50
+ var import_react8 = __toESM(require("react"));
51
51
  var import_material5 = require("@mui/material");
52
52
 
53
53
  // src/components/CrudifyLogin/context/I18nProvider.tsx
@@ -306,7 +306,7 @@ var secureLocalStorage = new SecureStorage("localStorage");
306
306
 
307
307
  // src/components/CrudifyLogin/Forms/LoginForm.tsx
308
308
  var import_jsx_runtime2 = require("react/jsx-runtime");
309
- var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/" }) => {
309
+ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/", searchParams }) => {
310
310
  const [username, setUsername] = (0, import_react4.useState)("");
311
311
  const [password, setPassword] = (0, import_react4.useState)("");
312
312
  const [loading, setLoading] = (0, import_react4.useState)(false);
@@ -319,6 +319,21 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
319
319
  showErrorNotifications: false,
320
320
  showSuccessNotifications: false
321
321
  });
322
+ const getRedirectUrl = () => {
323
+ if (searchParams) {
324
+ const redirectParam = searchParams.get("redirect");
325
+ if (redirectParam) {
326
+ try {
327
+ const decodedPath = decodeURIComponent(redirectParam);
328
+ if (decodedPath.startsWith("/") && !decodedPath.startsWith("//")) {
329
+ return decodedPath;
330
+ }
331
+ } catch (error) {
332
+ }
333
+ }
334
+ }
335
+ return redirectUrl || "/";
336
+ };
322
337
  (0, import_react4.useEffect)(() => {
323
338
  const timer = setTimeout(() => {
324
339
  if (usernameInputRef.current) usernameInputRef.current.focus();
@@ -363,9 +378,12 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
363
378
  setLoading(false);
364
379
  if (response.success) {
365
380
  secureSessionStorage.setToken(response.data.token);
366
- if (onLoginSuccess) {
367
- onLoginSuccess(response.data.token, redirectUrl);
368
- }
381
+ const finalRedirectUrl = getRedirectUrl();
382
+ setTimeout(() => {
383
+ if (onLoginSuccess) {
384
+ onLoginSuccess(response.data.token, finalRedirectUrl);
385
+ }
386
+ }, 50);
369
387
  } else {
370
388
  handleLoginError(response);
371
389
  }
@@ -500,7 +518,19 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
500
518
  }
501
519
  )
502
520
  ] }),
503
- config.loginActions?.includes("forgotPassword") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_material.Box, { sx: { display: "flex", justifyContent: "flex-end", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_material.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/forgotPassword"), variant: "body2", color: "secondary", children: t("login.forgotPasswordLink") }) }),
521
+ config.loginActions?.includes("forgotPassword") && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_material.Box, { sx: { display: "flex", justifyContent: "flex-end", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
522
+ import_material.Link,
523
+ {
524
+ sx: { cursor: "pointer" },
525
+ onClick: () => {
526
+ const searchString = searchParams ? `?${searchParams.toString()}` : "";
527
+ onNavigate?.(`/login/forgotPassword${searchString}`);
528
+ },
529
+ variant: "body2",
530
+ color: "secondary",
531
+ children: t("login.forgotPasswordLink")
532
+ }
533
+ ) }),
504
534
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_material.Button, { disabled: loading, type: "submit", fullWidth: true, variant: "contained", color: "primary", sx: { mt: 1, mb: 2 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_material.CircularProgress, { size: 20 }) : t("login.loginButton") })
505
535
  ]
506
536
  }
@@ -509,7 +539,19 @@ var LoginForm = ({ config, onNavigate, onLoginSuccess, onError, redirectUrl = "/
509
539
  config.loginActions?.includes("createUser") && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_material.Typography, { variant: "body2", align: "center", sx: { color: "text.secondary", mt: 3 }, children: [
510
540
  t("login.noAccountPrompt"),
511
541
  " ",
512
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_material.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/public/users/create"), fontWeight: "medium", color: "secondary", children: t("login.signUpLink") })
542
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
543
+ import_material.Link,
544
+ {
545
+ sx: { cursor: "pointer" },
546
+ onClick: () => {
547
+ const searchString = searchParams ? `?${searchParams.toString()}` : "";
548
+ onNavigate?.(`/public/users/create${searchString}`);
549
+ },
550
+ fontWeight: "medium",
551
+ color: "secondary",
552
+ children: t("login.signUpLink")
553
+ }
554
+ )
513
555
  ] })
514
556
  ] });
515
557
  };
@@ -555,17 +597,26 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
555
597
  setEmailSent(true);
556
598
  }
557
599
  } else {
558
- if (response.errors) {
559
- if (typeof response.errors === "string") {
560
- setErrors([response.errors]);
561
- } else if (response.errors.email) {
562
- setHelperTextEmail(response.errors.email[0]);
600
+ const errorMessages = [];
601
+ if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
602
+ errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
603
+ } else if (response.errors) {
604
+ if (response.errors._error) {
605
+ const errors2 = response.errors._error;
606
+ const translatedErrors = errors2.map((error) => {
607
+ if (error === "TOO_MANY_REQUESTS") {
608
+ return t("errors.auth.TOO_MANY_REQUESTS");
609
+ }
610
+ return error;
611
+ });
612
+ errorMessages.push(...translatedErrors);
563
613
  } else {
564
- setErrors([t("error.unknown")]);
614
+ errorMessages.push(t("error.unknown"));
565
615
  }
566
616
  } else {
567
- setErrors([t("error.unknown")]);
617
+ errorMessages.push(t("error.unknown"));
568
618
  }
619
+ setErrors(errorMessages);
569
620
  }
570
621
  } catch (error) {
571
622
  console.error("Forgot password error:", error);
@@ -577,38 +628,48 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
577
628
  setLoading(false);
578
629
  }
579
630
  };
580
- const handleFormSubmit = (e) => {
581
- e.preventDefault();
582
- handleSubmit();
631
+ const handleBack = () => {
632
+ onNavigate?.("/login");
583
633
  };
584
- if (emailSent) {
585
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { textAlign: "center" }, children: [
586
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Alert, { severity: "success", sx: { mb: 3 }, children: t("forgotPassword.emailSentMessage") }),
587
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { mb: 2 }, children: t("forgotPassword.checkEmailInstructions") }),
588
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/checkCode"), variant: "body2", color: "primary", children: t("forgotPassword.enterCodeLink") }),
589
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", gap: 2, mt: 2 }, children: [
590
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login"), variant: "body2", color: "secondary", children: t("common.back") }),
591
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { color: "grey.400" }, children: "\u2022" }),
592
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/checkCode"), variant: "body2", color: "secondary", children: t("forgotPassword.alreadyHaveCodeLink") })
593
- ] })
594
- ] });
595
- }
596
- if (codeAlreadyExists) {
597
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { textAlign: "center" }, children: [
598
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Alert, { severity: "info", sx: { mb: 3 }, children: t("forgotPassword.codeAlreadyExistsMessage") }),
599
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/checkCode"), variant: "body2", color: "primary", children: t("forgotPassword.enterCodeLink") }),
600
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", gap: 2, mt: 2 }, children: [
601
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login"), variant: "body2", color: "secondary", children: t("common.back") }),
602
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { color: "grey.400" }, children: "\u2022" }),
603
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/checkCode"), variant: "body2", color: "secondary", children: t("forgotPassword.alreadyHaveCodeLink") })
604
- ] })
605
- ] });
634
+ const handleGoToCheckCode = () => {
635
+ console.log("\u{1F680} handleGoToCheckCode called:", { email, emailSent, codeAlreadyExists });
636
+ if (emailSent || codeAlreadyExists) {
637
+ console.log("\u2705 Navigating from success state");
638
+ onNavigate?.(`/login/checkCode?email=${encodeURIComponent(email)}`);
639
+ return;
640
+ }
641
+ if (!email) {
642
+ console.log("\u274C Email required");
643
+ setHelperTextEmail(t("forgotPassword.emailRequired"));
644
+ return;
645
+ }
646
+ if (!validateEmail(email)) {
647
+ console.log("\u274C Invalid email");
648
+ setHelperTextEmail(t("forgotPassword.invalidEmail"));
649
+ return;
650
+ }
651
+ console.log("\u2705 Navigating with valid email");
652
+ onNavigate?.(`/login/checkCode?email=${encodeURIComponent(email)}`);
653
+ };
654
+ if (emailSent || codeAlreadyExists) {
655
+ console.log("\u{1F4E7} Rendering SUCCESS state:", { emailSent, codeAlreadyExists });
656
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2, textAlign: "center" }, children: [
657
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { mb: 2 }, children: [
658
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: codeAlreadyExists ? t("forgotPassword.codeAlreadyExistsMessage") : t("forgotPassword.emailSentMessage") }),
659
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { color: codeAlreadyExists ? "success.main" : "grey.600" }, children: codeAlreadyExists ? t("forgotPassword.checkEmailInstructions") : t("forgotPassword.checkEmailInstructions") })
660
+ ] }),
661
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Button, { type: "button", onClick: handleGoToCheckCode, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: t("forgotPassword.enterCodeLink") }),
662
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
663
+ ] }) });
606
664
  }
665
+ console.log("\u{1F4DD} Rendering FORM state");
607
666
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
608
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "h5", component: "h1", sx: { mb: 3, textAlign: "center" }, children: t("forgotPassword.title") }),
609
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { mb: 3, textAlign: "center", color: "text.secondary" }, children: t("forgotPassword.instructions") }),
610
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { component: "form", noValidate: true, onSubmit: handleFormSubmit, children: [
667
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { component: "form", noValidate: true, sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 }, children: [
611
668
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { mb: 2 }, children: [
669
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("forgotPassword.title") }),
670
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { color: "grey.600" }, children: t("forgotPassword.instructions") })
671
+ ] }),
672
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { mb: 1 }, children: [
612
673
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
613
674
  import_material2.Typography,
614
675
  {
@@ -637,14 +698,14 @@ var ForgotPasswordForm = ({ config, onNavigate, onError }) => {
637
698
  }
638
699
  )
639
700
  ] }),
640
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Button, { disabled: loading, type: "submit", fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.CircularProgress, { size: 20 }) : t("forgotPassword.sendCodeButton") }),
701
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Button, { disabled: loading, type: "button", onClick: handleSubmit, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.CircularProgress, { size: 20 }) : t("forgotPassword.sendCodeButton") }),
641
702
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_material2.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", gap: 2 }, children: [
642
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login"), variant: "body2", color: "secondary", children: t("common.back") }),
703
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }),
643
704
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Typography, { variant: "body2", sx: { color: "grey.400" }, children: "\u2022" }),
644
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/checkCode"), variant: "body2", color: "secondary", children: t("forgotPassword.alreadyHaveCodeLink") })
705
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Link, { sx: { cursor: "pointer" }, onClick: handleGoToCheckCode, variant: "body2", color: "secondary", children: t("login.alreadyHaveCodeLink") })
645
706
  ] })
646
707
  ] }),
647
- errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Box, { sx: { mt: 2 }, children: errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Alert, { variant: "filled", severity: "error", children: error }, index)) })
708
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Box, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_material2.Alert, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) })
648
709
  ] });
649
710
  };
650
711
  var ForgotPasswordForm_default = ForgotPasswordForm;
@@ -653,7 +714,7 @@ var ForgotPasswordForm_default = ForgotPasswordForm;
653
714
  var import_react6 = require("react");
654
715
  var import_material3 = require("@mui/material");
655
716
  var import_jsx_runtime4 = require("react/jsx-runtime");
656
- var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
717
+ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams, onResetSuccess }) => {
657
718
  const [newPassword, setNewPassword] = (0, import_react6.useState)("");
658
719
  const [confirmPassword, setConfirmPassword] = (0, import_react6.useState)("");
659
720
  const [loading, setLoading] = (0, import_react6.useState)(false);
@@ -662,14 +723,15 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
662
723
  const [helperTextConfirmPassword, setHelperTextConfirmPassword] = (0, import_react6.useState)(null);
663
724
  const [email, setEmail] = (0, import_react6.useState)("");
664
725
  const [code, setCode] = (0, import_react6.useState)("");
726
+ const [fromCodeVerification, setFromCodeVerification] = (0, import_react6.useState)(false);
665
727
  const [validatingCode, setValidatingCode] = (0, import_react6.useState)(true);
666
728
  const [codeValidated, setCodeValidated] = (0, import_react6.useState)(false);
667
- const [resetSuccess, setResetSuccess] = (0, import_react6.useState)(false);
668
729
  const { t } = useTranslation();
669
730
  const { crudify: crudify3 } = useCrudifyLogin(config);
670
731
  (0, import_react6.useEffect)(() => {
671
732
  const validateCode = async (emailToValidate, codeToValidate) => {
672
733
  if (!crudify3) return;
734
+ console.log("\u{1F50D} Validating reset code:", { emailToValidate, codeToValidate });
673
735
  try {
674
736
  const data = [
675
737
  {
@@ -677,60 +739,114 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
677
739
  data: { email: emailToValidate, codePassword: codeToValidate }
678
740
  }
679
741
  ];
742
+ console.log("\u{1F4E4} Sending validation request:", data);
680
743
  const response = await crudify3.transaction(data);
744
+ console.log("\u{1F4E5} Validation response:", response);
681
745
  if (response.success) {
746
+ console.log("\u2705 Code validation successful");
682
747
  setCodeValidated(true);
683
748
  } else {
684
- setErrors([t("resetPassword.invalidCode")]);
749
+ console.log("\u274C Code validation failed:", response);
750
+ if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
751
+ setErrors([t("errors.auth.TOO_MANY_REQUESTS")]);
752
+ } else {
753
+ let errorMessage = t("resetPassword.invalidCode");
754
+ if (response.errors?._error) {
755
+ const error = response.errors._error[0];
756
+ if (error === "TOO_MANY_REQUESTS") {
757
+ errorMessage = t("errors.auth.TOO_MANY_REQUESTS");
758
+ } else {
759
+ const errorMsg = error?.toLowerCase() || "";
760
+ if (errorMsg.includes("expired")) {
761
+ errorMessage = t("resetPassword.codeExpiredOrInvalid");
762
+ } else if (errorMsg.includes("invalid")) {
763
+ errorMessage = t("resetPassword.invalidCode");
764
+ }
765
+ }
766
+ }
767
+ setErrors([errorMessage]);
768
+ }
769
+ setTimeout(() => onNavigate?.("/login/forgotPassword"), 3e3);
685
770
  }
686
771
  } catch (error) {
687
772
  console.error("Code validation error:", error);
688
- setErrors([t("error.unknown")]);
773
+ setErrors([t("resetPassword.invalidCode")]);
774
+ setTimeout(() => onNavigate?.("/login/forgotPassword"), 3e3);
689
775
  } finally {
690
776
  setValidatingCode(false);
691
777
  }
692
778
  };
693
779
  if (searchParams) {
780
+ const fromCodeVerificationParam = searchParams.get("fromCodeVerification");
694
781
  const emailParam = searchParams.get("email");
695
782
  const codeParam = searchParams.get("code");
783
+ if (fromCodeVerificationParam === "true" && emailParam && codeParam) {
784
+ setEmail(emailParam);
785
+ setCode(codeParam);
786
+ setFromCodeVerification(true);
787
+ setCodeValidated(true);
788
+ setValidatingCode(false);
789
+ return;
790
+ }
791
+ const linkParam = searchParams.get("link");
792
+ if (linkParam) {
793
+ try {
794
+ const decodedLink = decodeURIComponent(linkParam);
795
+ const [linkCode, linkEmail] = decodedLink.split("/");
796
+ if (linkCode && linkEmail && linkCode.length === 6) {
797
+ console.log("\u{1F517} Reset link detected:", { linkCode, linkEmail });
798
+ setCode(linkCode);
799
+ setEmail(linkEmail);
800
+ setFromCodeVerification(false);
801
+ validateCode(linkEmail, linkCode);
802
+ return;
803
+ }
804
+ } catch (error) {
805
+ console.error("Failed to parse reset link:", error);
806
+ }
807
+ }
696
808
  if (emailParam && codeParam) {
697
809
  setEmail(emailParam);
698
810
  setCode(codeParam);
811
+ setFromCodeVerification(false);
699
812
  validateCode(emailParam, codeParam);
700
- } else {
701
- setValidatingCode(false);
702
- setErrors([t("resetPassword.missingParameters")]);
813
+ return;
703
814
  }
704
- } else {
705
- setValidatingCode(false);
706
- setErrors([t("resetPassword.missingParameters")]);
707
815
  }
708
- }, [searchParams, crudify3, t]);
709
- const validatePasswords = () => {
816
+ setErrors([t("resetPassword.invalidCode")]);
817
+ setValidatingCode(false);
818
+ setTimeout(() => onNavigate?.("/login/forgotPassword"), 3e3);
819
+ }, [searchParams, crudify3, t, onNavigate]);
820
+ const validatePassword = (password) => {
821
+ if (password.length < 8) {
822
+ return t("resetPassword.passwordTooShort");
823
+ }
824
+ return null;
825
+ };
826
+ const handleSubmit = async () => {
827
+ if (loading || !crudify3) return;
828
+ setErrors([]);
710
829
  setHelperTextNewPassword(null);
711
830
  setHelperTextConfirmPassword(null);
831
+ let hasErrors = false;
712
832
  if (!newPassword) {
713
833
  setHelperTextNewPassword(t("resetPassword.newPasswordRequired"));
714
- return false;
715
- }
716
- if (newPassword.length < 8) {
717
- setHelperTextNewPassword(t("resetPassword.passwordTooShort"));
718
- return false;
834
+ hasErrors = true;
835
+ } else {
836
+ const passwordError = validatePassword(newPassword);
837
+ if (passwordError) {
838
+ setHelperTextNewPassword(passwordError);
839
+ hasErrors = true;
840
+ }
719
841
  }
720
842
  if (!confirmPassword) {
721
843
  setHelperTextConfirmPassword(t("resetPassword.confirmPasswordRequired"));
722
- return false;
723
- }
724
- if (newPassword !== confirmPassword) {
844
+ hasErrors = true;
845
+ } else if (newPassword !== confirmPassword) {
725
846
  setHelperTextConfirmPassword(t("resetPassword.passwordsDoNotMatch"));
726
- return false;
847
+ hasErrors = true;
727
848
  }
728
- return true;
729
- };
730
- const handleSubmit = async () => {
731
- if (loading || !crudify3) return;
732
- setErrors([]);
733
- if (!validatePasswords()) return;
849
+ if (hasErrors) return;
734
850
  setLoading(true);
735
851
  try {
736
852
  const data = [
@@ -741,22 +857,57 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
741
857
  ];
742
858
  const response = await crudify3.transaction(data);
743
859
  if (response.success) {
744
- setResetSuccess(true);
860
+ setErrors([]);
861
+ setTimeout(() => {
862
+ onResetSuccess?.();
863
+ }, 1e3);
745
864
  } else {
746
- if (response.errors) {
747
- if (typeof response.errors === "string") {
748
- setErrors([response.errors]);
749
- } else {
750
- if (response.errors.newPassword) {
751
- setHelperTextNewPassword(response.errors.newPassword[0]);
865
+ const errorMessages = [];
866
+ if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
867
+ errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
868
+ } else if (response.errors?._transaction) {
869
+ const transactionErrors = response.errors._transaction;
870
+ if (Array.isArray(transactionErrors) && transactionErrors.length > 0) {
871
+ const firstError = transactionErrors[0];
872
+ let errorMsg = "";
873
+ if (typeof firstError === "string") {
874
+ try {
875
+ const parsed = JSON.parse(firstError);
876
+ if (parsed?.response?.message) {
877
+ errorMsg = parsed.response.message.toLowerCase();
878
+ }
879
+ } catch {
880
+ errorMsg = firstError.toLowerCase();
881
+ }
752
882
  }
753
- if (response.errors._error) {
754
- setErrors(response.errors._error);
883
+ if (errorMsg.includes("expired")) {
884
+ errorMessages.push(t("resetPassword.codeExpiredOrInvalid"));
885
+ } else if (errorMsg.includes("invalid")) {
886
+ errorMessages.push(t("resetPassword.invalidCode"));
887
+ } else {
888
+ errorMessages.push(t("error.unknown"));
889
+ }
890
+ } else {
891
+ errorMessages.push(t("error.unknown"));
892
+ }
893
+ } else if (response.errors?._error) {
894
+ const error = response.errors._error[0];
895
+ if (error === "TOO_MANY_REQUESTS") {
896
+ errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
897
+ } else {
898
+ const errorMsg = error?.toLowerCase() || "";
899
+ if (errorMsg.includes("expired")) {
900
+ errorMessages.push(t("resetPassword.codeExpiredOrInvalid"));
901
+ } else if (errorMsg.includes("invalid")) {
902
+ errorMessages.push(t("resetPassword.invalidCode"));
903
+ } else {
904
+ errorMessages.push(error || t("error.unknown"));
755
905
  }
756
906
  }
757
907
  } else {
758
- setErrors([t("error.unknown")]);
908
+ errorMessages.push(t("error.unknown"));
759
909
  }
910
+ setErrors(errorMessages);
760
911
  }
761
912
  } catch (error) {
762
913
  console.error("Reset password error:", error);
@@ -764,47 +915,26 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
764
915
  if (onError) {
765
916
  onError(typeof error === "string" ? error : t("error.unknown"));
766
917
  }
767
- } finally {
768
- setLoading(false);
769
918
  }
919
+ setLoading(false);
770
920
  };
771
- const handleFormSubmit = (e) => {
772
- e.preventDefault();
773
- handleSubmit();
774
- };
775
- const handleKeyDown = (e) => {
776
- if (e.key === "Enter" && !loading) {
777
- e.preventDefault();
778
- handleSubmit();
779
- }
921
+ const handleBack = () => {
922
+ if (fromCodeVerification) onNavigate?.(`/login/checkCode?email=${encodeURIComponent(email)}`);
923
+ else onNavigate?.("/login/forgotPassword");
780
924
  };
781
925
  if (validatingCode) {
782
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { textAlign: "center", py: 4 }, children: [
783
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.CircularProgress, { size: 40 }),
784
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Typography, { variant: "body2", sx: { mt: 2 }, children: t("resetPassword.validatingCode") })
785
- ] });
786
- }
787
- if (resetSuccess) {
788
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { textAlign: "center" }, children: [
789
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Alert, { severity: "success", sx: { mb: 3 }, children: t("resetPassword.successMessage") }),
790
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Typography, { variant: "body2", sx: { mb: 3 }, children: t("resetPassword.successInstructions") }),
791
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Button, { variant: "contained", color: "primary", onClick: () => onNavigate?.("/login"), fullWidth: true, children: t("resetPassword.goToLoginButton") })
792
- ] });
926
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "300px" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.CircularProgress, {}) });
793
927
  }
794
928
  if (!codeValidated) {
795
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { textAlign: "center" }, children: [
796
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Alert, { severity: "error", sx: { mb: 3 }, children: t("resetPassword.codeExpiredOrInvalid") }),
797
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { display: "flex", flexDirection: "column", gap: 2 }, children: [
798
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Button, { variant: "contained", color: "primary", onClick: () => onNavigate?.("/login/forgotPassword"), fullWidth: true, children: t("resetPassword.requestNewCodeButton") }),
799
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login"), variant: "body2", color: "secondary", children: t("common.backToLogin") })
800
- ] })
801
- ] });
929
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Box, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Alert, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) });
802
930
  }
803
931
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
804
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Typography, { variant: "h5", component: "h1", sx: { mb: 3, textAlign: "center" }, children: t("resetPassword.title") }),
805
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Typography, { variant: "body2", sx: { mb: 3, textAlign: "center", color: "text.secondary" }, children: t("resetPassword.instructions") }),
806
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { component: "form", noValidate: true, onSubmit: handleFormSubmit, onKeyDown: handleKeyDown, children: [
932
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { component: "form", noValidate: true, sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 }, children: [
807
933
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { mb: 2 }, children: [
934
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Typography, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("resetPassword.title") }),
935
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Typography, { variant: "body2", sx: { color: "grey.600" }, children: t("resetPassword.instructions") })
936
+ ] }),
937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { mb: 1 }, children: [
808
938
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
809
939
  import_material3.Typography,
810
940
  {
@@ -833,7 +963,7 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
833
963
  }
834
964
  )
835
965
  ] }),
836
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { mb: 2 }, children: [
966
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_material3.Box, { sx: { mb: 1 }, children: [
837
967
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
838
968
  import_material3.Typography,
839
969
  {
@@ -862,10 +992,10 @@ var ResetPasswordForm = ({ config, onNavigate, onError, searchParams }) => {
862
992
  }
863
993
  )
864
994
  ] }),
865
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Button, { disabled: loading, type: "submit", fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.CircularProgress, { size: 20 }) : t("resetPassword.resetPasswordButton") }),
866
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Box, { sx: { textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login"), variant: "body2", color: "secondary", children: t("common.backToLogin") }) })
995
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Button, { disabled: loading, type: "button", onClick: handleSubmit, fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.CircularProgress, { size: 20 }) : t("resetPassword.resetPasswordButton") }),
996
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Link, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
867
997
  ] }),
868
- errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Box, { sx: { mt: 2 }, children: errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Alert, { variant: "filled", severity: "error", children: error }, index)) })
998
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Box, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_material3.Alert, { variant: "filled", sx: { mt: 2 }, severity: "error", children: error }, index)) })
869
999
  ] });
870
1000
  };
871
1001
  var ResetPasswordForm_default = ResetPasswordForm;
@@ -874,40 +1004,31 @@ var ResetPasswordForm_default = ResetPasswordForm;
874
1004
  var import_react7 = require("react");
875
1005
  var import_material4 = require("@mui/material");
876
1006
  var import_jsx_runtime5 = require("react/jsx-runtime");
877
- var CheckCodeForm = ({ config, onNavigate, onError }) => {
878
- const [email, setEmail] = (0, import_react7.useState)("");
1007
+ var CheckCodeForm = ({ config, onNavigate, onError, searchParams }) => {
879
1008
  const [code, setCode] = (0, import_react7.useState)("");
880
1009
  const [loading, setLoading] = (0, import_react7.useState)(false);
881
1010
  const [errors, setErrors] = (0, import_react7.useState)([]);
882
- const [helperTextEmail, setHelperTextEmail] = (0, import_react7.useState)(null);
883
1011
  const [helperTextCode, setHelperTextCode] = (0, import_react7.useState)(null);
1012
+ const [email, setEmail] = (0, import_react7.useState)("");
884
1013
  const { t } = useTranslation();
885
1014
  const { crudify: crudify3 } = useCrudifyLogin(config);
886
1015
  (0, import_react7.useEffect)(() => {
887
- const timer = setTimeout(() => {
888
- const emailInput = document.getElementById("email");
889
- if (emailInput) emailInput.focus();
890
- }, 100);
891
- return () => clearTimeout(timer);
892
- }, []);
893
- const validateEmail = (email2) => {
894
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
895
- return emailRegex.test(email2);
896
- };
1016
+ const emailParam = searchParams?.get("email");
1017
+ if (emailParam) {
1018
+ setEmail(emailParam);
1019
+ } else {
1020
+ onNavigate?.("/login/forgotPassword");
1021
+ }
1022
+ }, [searchParams, onNavigate]);
897
1023
  const handleSubmit = async () => {
898
1024
  if (loading || !crudify3) return;
899
1025
  setErrors([]);
900
- setHelperTextEmail(null);
901
1026
  setHelperTextCode(null);
902
- if (!email) {
903
- setHelperTextEmail(t("checkCode.emailRequired"));
904
- return;
905
- }
906
- if (!validateEmail(email)) {
907
- setHelperTextEmail(t("checkCode.invalidEmail"));
1027
+ if (!code) {
1028
+ setHelperTextCode(t("checkCode.codeRequired"));
908
1029
  return;
909
1030
  }
910
- if (!code) {
1031
+ if (code.length !== 6) {
911
1032
  setHelperTextCode(t("checkCode.codeRequired"));
912
1033
  return;
913
1034
  }
@@ -921,75 +1042,53 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
921
1042
  ];
922
1043
  const response = await crudify3.transaction(data);
923
1044
  if (response.success) {
924
- const params = new URLSearchParams({ email, code }).toString();
925
- onNavigate?.(`/login/resetPassword?${params}`);
1045
+ onNavigate?.(`/login/resetPassword?email=${encodeURIComponent(email)}&code=${encodeURIComponent(code)}&fromCodeVerification=true`);
926
1046
  } else {
927
- if (response.errors) {
928
- if (typeof response.errors === "string") {
929
- setErrors([response.errors]);
1047
+ const errorMessages = [];
1048
+ if (response.data?.response?.status === "TOO_MANY_REQUESTS") {
1049
+ errorMessages.push(t("errors.auth.TOO_MANY_REQUESTS"));
1050
+ } else if (response.errors) {
1051
+ if (response.errors._error) {
1052
+ const errors2 = response.errors._error;
1053
+ const translatedErrors = errors2.map((error) => {
1054
+ if (error === "TOO_MANY_REQUESTS") {
1055
+ return t("errors.auth.TOO_MANY_REQUESTS");
1056
+ }
1057
+ return error;
1058
+ });
1059
+ errorMessages.push(...translatedErrors);
930
1060
  } else {
931
- if (response.errors.email) setHelperTextEmail(response.errors.email[0]);
932
- if (response.errors.code) setHelperTextCode(response.errors.code[0]);
933
- if (response.errors._error) setErrors(response.errors._error);
1061
+ errorMessages.push(t("error.unknown"));
934
1062
  }
935
1063
  } else {
936
- setErrors([t("error.unknown")]);
1064
+ errorMessages.push(t("checkCode.verifyError"));
937
1065
  }
1066
+ setErrors(errorMessages);
1067
+ setLoading(false);
938
1068
  }
939
1069
  } catch (error) {
940
1070
  console.error("Check code error:", error);
941
1071
  setErrors([t("error.unknown")]);
1072
+ setLoading(false);
942
1073
  if (onError) {
943
1074
  onError(typeof error === "string" ? error : t("error.unknown"));
944
1075
  }
945
- } finally {
946
- setLoading(false);
947
1076
  }
948
1077
  };
949
- const handleFormSubmit = (e) => {
950
- e.preventDefault();
951
- handleSubmit();
1078
+ const handleBack = () => {
1079
+ onNavigate?.("/login/forgotPassword");
952
1080
  };
953
- const handleKeyDown = (e) => {
954
- if (e.key === "Enter" && !loading) {
955
- e.preventDefault();
956
- handleSubmit();
957
- }
1081
+ const handleCodeChange = (event) => {
1082
+ const value = event.target.value.replace(/\D/g, "").slice(0, 6);
1083
+ setCode(value);
958
1084
  };
959
1085
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
960
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Typography, { variant: "h5", component: "h1", sx: { mb: 3, textAlign: "center" }, children: t("checkCode.title") }),
961
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Typography, { variant: "body2", sx: { mb: 3, textAlign: "center", color: "text.secondary" }, children: t("checkCode.instructions") }),
962
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { component: "form", noValidate: true, onSubmit: handleFormSubmit, onKeyDown: handleKeyDown, children: [
1086
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { component: "form", noValidate: true, sx: { width: "100%", display: "flex", flexDirection: "column", gap: 2 }, children: [
963
1087
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { sx: { mb: 2 }, children: [
964
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
965
- import_material4.Typography,
966
- {
967
- variant: "body2",
968
- component: "label",
969
- htmlFor: "email",
970
- sx: { display: "block", fontWeight: 500, color: "grey.700", mb: 0.5 },
971
- children: t("checkCode.emailLabel")
972
- }
973
- ),
974
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
975
- import_material4.TextField,
976
- {
977
- fullWidth: true,
978
- id: "email",
979
- name: "email",
980
- type: "email",
981
- value: email,
982
- disabled: loading,
983
- onChange: (e) => setEmail(e.target.value),
984
- error: !!helperTextEmail,
985
- helperText: helperTextEmail,
986
- autoComplete: "email",
987
- placeholder: t("checkCode.emailPlaceholder"),
988
- required: true
989
- }
990
- )
1088
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Typography, { variant: "h5", component: "h1", sx: { mb: 1, fontWeight: 600 }, children: t("checkCode.title") }),
1089
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Typography, { variant: "body2", sx: { color: "grey.600" }, children: t("checkCode.instructions") })
991
1090
  ] }),
992
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { sx: { mb: 2 }, children: [
1091
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { sx: { mb: 1 }, children: [
993
1092
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
994
1093
  import_material4.Typography,
995
1094
  {
@@ -1009,21 +1108,34 @@ var CheckCodeForm = ({ config, onNavigate, onError }) => {
1009
1108
  type: "text",
1010
1109
  value: code,
1011
1110
  disabled: loading,
1012
- onChange: (e) => setCode(e.target.value),
1111
+ onChange: handleCodeChange,
1013
1112
  error: !!helperTextCode,
1014
1113
  helperText: helperTextCode,
1015
1114
  placeholder: t("checkCode.codePlaceholder"),
1115
+ inputProps: {
1116
+ maxLength: 6,
1117
+ style: { textAlign: "center", fontSize: "1.5rem", letterSpacing: "0.4rem" }
1118
+ },
1016
1119
  required: true
1017
1120
  }
1018
1121
  )
1019
1122
  ] }),
1020
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Button, { disabled: loading, type: "submit", fullWidth: true, variant: "contained", color: "primary", sx: { mt: 2, mb: 2 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.CircularProgress, { size: 20 }) : t("checkCode.verifyButton") }),
1021
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material4.Box, { sx: { textAlign: "center", display: "flex", flexDirection: "column", gap: 1 }, children: [
1022
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login/forgotPassword"), variant: "body2", color: "primary", children: t("checkCode.resendCodeLink") }),
1023
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Link, { sx: { cursor: "pointer" }, onClick: () => onNavigate?.("/login"), variant: "body2", color: "secondary", children: t("common.backToLogin") })
1024
- ] })
1123
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1124
+ import_material4.Button,
1125
+ {
1126
+ disabled: loading || code.length !== 6,
1127
+ type: "button",
1128
+ onClick: handleSubmit,
1129
+ fullWidth: true,
1130
+ variant: "contained",
1131
+ color: "primary",
1132
+ sx: { mt: 2, mb: 2 },
1133
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.CircularProgress, { size: 20 }) : t("checkCode.verifyButton")
1134
+ }
1135
+ ),
1136
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Box, { sx: { display: "flex", justifyContent: "center", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Link, { sx: { cursor: "pointer" }, onClick: handleBack, variant: "body2", color: "secondary", children: t("common.back") }) })
1025
1137
  ] }),
1026
- errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Box, { sx: { mt: 2 }, children: errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Alert, { variant: "filled", severity: "error", children: error }, index)) })
1138
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Box, { children: errors.length > 0 && errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material4.Alert, { sx: { mt: 2 }, severity: "error", children: error }, index)) })
1027
1139
  ] });
1028
1140
  };
1029
1141
  var CheckCodeForm_default = CheckCodeForm;
@@ -1042,6 +1154,25 @@ var CrudifyLoginInternal = ({
1042
1154
  const { t } = useTranslation();
1043
1155
  const [currentScreen, setCurrentScreen] = (0, import_react8.useState)(initialScreen);
1044
1156
  const [searchParams, setSearchParams] = (0, import_react8.useState)();
1157
+ console.log("\u{1F504} CrudifyLoginInternal RENDER:", { currentScreen, initialScreen });
1158
+ import_react8.default.useEffect(() => {
1159
+ const urlParams = new URLSearchParams(window.location.search);
1160
+ if (initialScreen === "checkCode") {
1161
+ const email = urlParams.get("email");
1162
+ const code = urlParams.get("code");
1163
+ console.log("\u{1F517} CheckCode link detected:", { email, code });
1164
+ if (email) {
1165
+ setSearchParams(urlParams);
1166
+ }
1167
+ }
1168
+ if (initialScreen === "resetPassword") {
1169
+ const link = urlParams.get("link");
1170
+ console.log("\u{1F517} ResetPassword link detected:", { link });
1171
+ if (link) {
1172
+ setSearchParams(urlParams);
1173
+ }
1174
+ }
1175
+ }, [initialScreen]);
1045
1176
  const finalConfig = (0, import_react8.useMemo)(() => {
1046
1177
  let cookieConfig = {};
1047
1178
  if (autoReadFromCookies) {
@@ -1085,39 +1216,73 @@ var CrudifyLoginInternal = ({
1085
1216
  };
1086
1217
  }, [providedConfig, autoReadFromCookies]);
1087
1218
  const handleNavigate = (path) => {
1219
+ console.log("\u{1F680} INTERNAL handleNavigate called with:", path);
1088
1220
  const [basePath, queryString] = path.split("?");
1089
1221
  if (queryString) {
1090
1222
  setSearchParams(new URLSearchParams(queryString));
1091
1223
  } else {
1092
1224
  setSearchParams(void 0);
1093
1225
  }
1226
+ let newScreen = "login";
1094
1227
  if (basePath.includes("/forgotPassword")) {
1095
- setCurrentScreen("forgotPassword");
1228
+ newScreen = "forgotPassword";
1096
1229
  } else if (basePath.includes("/checkCode")) {
1097
- setCurrentScreen("checkCode");
1230
+ newScreen = "checkCode";
1098
1231
  } else if (basePath.includes("/resetPassword")) {
1099
- setCurrentScreen("resetPassword");
1232
+ newScreen = "resetPassword";
1100
1233
  } else {
1101
- setCurrentScreen("login");
1234
+ newScreen = "login";
1102
1235
  }
1236
+ console.log("\u{1F3AF} INTERNAL Setting currentScreen from", currentScreen, "to", newScreen);
1237
+ setCurrentScreen(newScreen);
1238
+ console.log("\u{1F512} All navigation handled internally - no external calls");
1239
+ };
1240
+ const notifyExternal = (path, reason) => {
1241
+ console.log(`\u{1F4E2} Notifying external: ${reason} - ${path}`);
1103
1242
  onNavigate?.(path);
1104
1243
  };
1105
1244
  const renderCurrentForm = () => {
1245
+ console.log("\u{1F3A8} renderCurrentForm for screen:", currentScreen);
1106
1246
  const commonProps = {
1107
1247
  config: finalConfig,
1108
1248
  onNavigate: handleNavigate,
1249
+ // Navegación interna
1109
1250
  onError,
1110
1251
  redirectUrl
1111
1252
  };
1112
1253
  switch (currentScreen) {
1113
1254
  case "forgotPassword":
1255
+ console.log("\u{1F4CB} Rendering ForgotPasswordForm");
1114
1256
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ForgotPasswordForm_default, { ...commonProps });
1115
1257
  case "checkCode":
1116
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckCodeForm_default, { ...commonProps });
1258
+ console.log("\u{1F522} Rendering CheckCodeForm");
1259
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckCodeForm_default, { ...commonProps, searchParams });
1117
1260
  case "resetPassword":
1118
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ResetPasswordForm_default, { ...commonProps, searchParams });
1261
+ console.log("\u{1F510} Rendering ResetPasswordForm");
1262
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1263
+ ResetPasswordForm_default,
1264
+ {
1265
+ ...commonProps,
1266
+ searchParams,
1267
+ onResetSuccess: () => {
1268
+ notifyExternal(redirectUrl, "Password reset successful");
1269
+ }
1270
+ }
1271
+ );
1119
1272
  default:
1120
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LoginForm_default, { ...commonProps, onLoginSuccess });
1273
+ console.log("\u{1F511} Rendering LoginForm");
1274
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1275
+ LoginForm_default,
1276
+ {
1277
+ ...commonProps,
1278
+ onLoginSuccess: (result) => {
1279
+ if (onLoginSuccess) {
1280
+ onLoginSuccess(result);
1281
+ }
1282
+ notifyExternal(redirectUrl, "Login successful");
1283
+ }
1284
+ }
1285
+ );
1121
1286
  }
1122
1287
  };
1123
1288
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [