From 9f769a7486149251d07905fac4a98cb814ab2be3 Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Thu, 17 Jul 2025 12:47:57 +0545 Subject: [PATCH 1/9] refactor: replace toast message with Message component for login error --- packages/user/src/components/Login/LoginWrapper.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/user/src/components/Login/LoginWrapper.tsx b/packages/user/src/components/Login/LoginWrapper.tsx index e192c0b7d..7f7cbecb7 100644 --- a/packages/user/src/components/Login/LoginWrapper.tsx +++ b/packages/user/src/components/Login/LoginWrapper.tsx @@ -1,4 +1,5 @@ import { useTranslation } from "@dzangolab/react-i18n"; +import { Message } from "@dzangolab/react-ui"; import { FC, useState } from "react"; import { toast } from "react-toastify"; @@ -34,6 +35,7 @@ export const LoginWrapper: FC = ({ const { setUser } = useUser(); const config = useConfig(); const [loginLoading, setLoginLoading] = useState(false); + const [loginError, setLoginError] = useState(null); const links: Array = [ { @@ -74,7 +76,7 @@ export const LoginWrapper: FC = ({ onLoginFailed && (await onLoginFailed(error)); - toast.error(t(errorMessage, { ns: "errors" })); + setLoginError(t(errorMessage, { ns: "errors" })); }); setLoginLoading(false); @@ -83,6 +85,14 @@ export const LoginWrapper: FC = ({ return ( <> + {loginError && ( + setLoginError(null)} + severity="danger" + /> + )} Date: Thu, 17 Jul 2025 15:35:46 +0545 Subject: [PATCH 2/9] refactor: update signup error --- .../src/components/Signup/SignupWrapper.tsx | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/user/src/components/Signup/SignupWrapper.tsx b/packages/user/src/components/Signup/SignupWrapper.tsx index 2ae835089..81428d847 100644 --- a/packages/user/src/components/Signup/SignupWrapper.tsx +++ b/packages/user/src/components/Signup/SignupWrapper.tsx @@ -1,17 +1,18 @@ import { useTranslation } from "@dzangolab/react-i18n"; +import { Message } from "@dzangolab/react-ui"; import React, { useState } from "react"; import { toast } from "react-toastify"; -import { DEFAULT_PATHS } from "@/constants"; -import { signup } from "@/supertokens"; -import { LinkType } from "@/types/types"; - import { AuthLinks } from "../AuthLinks"; import { SignupForm } from "./SignupForm"; import { useConfig, useUser } from "../../hooks"; import type { LoginCredentials, SignInUpPromise } from "../../types"; +import { DEFAULT_PATHS } from "@/constants"; +import { signup } from "@/supertokens"; +import { LinkType } from "@/types/types"; + interface IProperties { loading?: boolean; showForgotPasswordLink?: boolean; @@ -33,6 +34,8 @@ export const SignupWrapper: React.FC = ({ }) => { const { t } = useTranslation("user"); const [signupLoading, setSignupLoading] = useState(false); + const [signupError, setSignupError] = useState(null); + const { setUser } = useUser(); const config = useConfig(); @@ -84,15 +87,15 @@ export const SignupWrapper: React.FC = ({ } }) .catch(async (error) => { - const errorMessage = t("errors.otherErrors", { ns: "errors" }); - onSignupFailed && (await onSignupFailed(error)); - if (error.status === "FIELD_ERROR") { - throw error as Error; + if (error.message.includes("email already exists")) { + setSignupError(t("errors.emailAlreadyExists", { ns: "errors" })); + + return; } - toast.error(error.message || errorMessage); + setSignupError(t("errors.otherErrors", { ns: "errors" })); }) .finally(() => { setSignupLoading(false); @@ -102,6 +105,14 @@ export const SignupWrapper: React.FC = ({ return ( <> + {signupError && ( + setSignupError(null)} + severity="danger" + /> + )} Date: Thu, 17 Jul 2025 17:58:19 +0545 Subject: [PATCH 3/9] refactor: dynamic translation logic --- packages/i18n/src/locales/en/errors.json | 3 ++- packages/i18n/src/locales/fr/errors.json | 3 ++- .../user/src/components/Login/LoginWrapper.tsx | 17 ++++++++++------- .../src/components/Signup/SignupWrapper.tsx | 18 ++++++++++++------ 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/packages/i18n/src/locales/en/errors.json b/packages/i18n/src/locales/en/errors.json index 20dbad38d..6d48a27f3 100644 --- a/packages/i18n/src/locales/en/errors.json +++ b/packages/i18n/src/locales/en/errors.json @@ -1,6 +1,7 @@ { "errors": { - "401": "The credentials you input are invalid.", + "401": "Invalid credentials. Please check your email or password and try again.", + "emailAlreadyExists": "This email already exists. Please sign in instead.", "otherErrors": "Oops! Something went wrong." } } diff --git a/packages/i18n/src/locales/fr/errors.json b/packages/i18n/src/locales/fr/errors.json index 421d7675b..465e8f795 100644 --- a/packages/i18n/src/locales/fr/errors.json +++ b/packages/i18n/src/locales/fr/errors.json @@ -1,6 +1,7 @@ { "errors": { - "401": "The credentials you input are invalid (fr).", + "401": "Invalid credentials. Please check your email or password and try again. (fr)", + "emailAlreadyExists": "This email already exists. Please sign in instead. (fr)", "otherErrors": "Oops! Something went wrong (fr)." } } diff --git a/packages/user/src/components/Login/LoginWrapper.tsx b/packages/user/src/components/Login/LoginWrapper.tsx index 7f7cbecb7..4fb1d4b40 100644 --- a/packages/user/src/components/Login/LoginWrapper.tsx +++ b/packages/user/src/components/Login/LoginWrapper.tsx @@ -35,7 +35,8 @@ export const LoginWrapper: FC = ({ const { setUser } = useUser(); const config = useConfig(); const [loginLoading, setLoginLoading] = useState(false); - const [loginError, setLoginError] = useState(null); + const [loginError, setLoginError] = useState(false); + const [loginErrorKey, setLoginErrorKey] = useState(null); const links: Array = [ { @@ -72,11 +73,10 @@ export const LoginWrapper: FC = ({ } }) .catch(async (error) => { - const errorMessage = `errors.${error.message}`; - onLoginFailed && (await onLoginFailed(error)); - setLoginError(t(errorMessage, { ns: "errors" })); + setLoginError(true); + setLoginErrorKey(`errors.${error.message}`); }); setLoginLoading(false); @@ -85,11 +85,14 @@ export const LoginWrapper: FC = ({ return ( <> - {loginError && ( + {loginError && loginErrorKey && ( setLoginError(null)} + message={t(loginErrorKey, { ns: "errors" })} + onClose={() => { + setLoginError(false); + setLoginErrorKey(null); + }} severity="danger" /> )} diff --git a/packages/user/src/components/Signup/SignupWrapper.tsx b/packages/user/src/components/Signup/SignupWrapper.tsx index 81428d847..5eafabd7d 100644 --- a/packages/user/src/components/Signup/SignupWrapper.tsx +++ b/packages/user/src/components/Signup/SignupWrapper.tsx @@ -34,7 +34,8 @@ export const SignupWrapper: React.FC = ({ }) => { const { t } = useTranslation("user"); const [signupLoading, setSignupLoading] = useState(false); - const [signupError, setSignupError] = useState(null); + const [signupError, setSignupError] = useState(false); + const [signupErrorKey, setSignupErrorKey] = useState(null); const { setUser } = useUser(); const config = useConfig(); @@ -89,13 +90,15 @@ export const SignupWrapper: React.FC = ({ .catch(async (error) => { onSignupFailed && (await onSignupFailed(error)); + setSignupError(true); + if (error.message.includes("email already exists")) { - setSignupError(t("errors.emailAlreadyExists", { ns: "errors" })); + setSignupErrorKey("errors.emailAlreadyExists"); return; } - setSignupError(t("errors.otherErrors", { ns: "errors" })); + setSignupErrorKey("errors.otherErrors"); }) .finally(() => { setSignupLoading(false); @@ -105,11 +108,14 @@ export const SignupWrapper: React.FC = ({ return ( <> - {signupError && ( + {signupError && signupErrorKey && ( setSignupError(null)} + message={t(signupErrorKey, { ns: "errors" })} + onClose={() => { + setSignupError(false); + setSignupErrorKey(null); + }} severity="danger" /> )} From 7db68739ff1f4b8d7425e6de075d0fa25f8a906d Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Mon, 21 Jul 2025 15:31:32 +0545 Subject: [PATCH 4/9] refactor: login and signup error message --- .../src/components/Login/LoginWrapper.tsx | 32 ++++++++++++------- .../src/components/Signup/SignupWrapper.tsx | 23 +++++++------ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/packages/user/src/components/Login/LoginWrapper.tsx b/packages/user/src/components/Login/LoginWrapper.tsx index 4fb1d4b40..86e074e0d 100644 --- a/packages/user/src/components/Login/LoginWrapper.tsx +++ b/packages/user/src/components/Login/LoginWrapper.tsx @@ -3,10 +3,6 @@ import { Message } from "@dzangolab/react-ui"; import { FC, useState } from "react"; import { toast } from "react-toastify"; -import { DEFAULT_PATHS } from "@/constants"; -import { login } from "@/supertokens"; -import { LinkType } from "@/types/types"; - import { LoginForm } from "./LoginForm"; import { useConfig, useUser } from "../../hooks"; import { verifySessionRoles } from "../../supertokens/helpers"; @@ -14,6 +10,10 @@ import { AuthLinks } from "../AuthLinks"; import type { LoginCredentials, SignInUpPromise } from "../../types"; +import { DEFAULT_PATHS } from "@/constants"; +import { login } from "@/supertokens"; +import { LinkType } from "@/types/types"; + interface IProperties { handleSubmit?: (credential: LoginCredentials) => void; onLoginFailed?: (error: Error) => void; @@ -35,8 +35,9 @@ export const LoginWrapper: FC = ({ const { setUser } = useUser(); const config = useConfig(); const [loginLoading, setLoginLoading] = useState(false); - const [loginError, setLoginError] = useState(false); - const [loginErrorKey, setLoginErrorKey] = useState(null); + const [loginError, setLoginError] = useState< + null | "invalidCredentials" | "other" + >(null); const links: Array = [ { @@ -75,23 +76,30 @@ export const LoginWrapper: FC = ({ .catch(async (error) => { onLoginFailed && (await onLoginFailed(error)); - setLoginError(true); - setLoginErrorKey(`errors.${error.message}`); + if (error.message === "401") { + setLoginError("invalidCredentials"); + } else { + setLoginError("other"); + } }); setLoginLoading(false); } }; + const message = + loginError === "invalidCredentials" + ? t("errors.401", { ns: "errors" }) + : t("errors.otherErrors", { ns: "errors" }); + return ( <> - {loginError && loginErrorKey && ( + {loginError && ( { - setLoginError(false); - setLoginErrorKey(null); + setLoginError(null); }} severity="danger" /> diff --git a/packages/user/src/components/Signup/SignupWrapper.tsx b/packages/user/src/components/Signup/SignupWrapper.tsx index 5eafabd7d..03ff97a2c 100644 --- a/packages/user/src/components/Signup/SignupWrapper.tsx +++ b/packages/user/src/components/Signup/SignupWrapper.tsx @@ -34,8 +34,9 @@ export const SignupWrapper: React.FC = ({ }) => { const { t } = useTranslation("user"); const [signupLoading, setSignupLoading] = useState(false); - const [signupError, setSignupError] = useState(false); - const [signupErrorKey, setSignupErrorKey] = useState(null); + const [signupError, setSignupError] = useState< + null | "emailAlreadyExists" | "other" + >(null); const { setUser } = useUser(); const config = useConfig(); @@ -90,15 +91,13 @@ export const SignupWrapper: React.FC = ({ .catch(async (error) => { onSignupFailed && (await onSignupFailed(error)); - setSignupError(true); - if (error.message.includes("email already exists")) { - setSignupErrorKey("errors.emailAlreadyExists"); + setSignupError("emailAlreadyExists"); return; } - setSignupErrorKey("errors.otherErrors"); + setSignupError("other"); }) .finally(() => { setSignupLoading(false); @@ -106,15 +105,19 @@ export const SignupWrapper: React.FC = ({ } }; + const message = + signupError === "emailAlreadyExists" + ? t("errors.emailAlreadyExists", { ns: "errors" }) + : t("errors.otherErrors", { ns: "errors" }); + return ( <> - {signupError && signupErrorKey && ( + {signupError && ( { - setSignupError(false); - setSignupErrorKey(null); + setSignupError(null); }} severity="danger" /> From 1549cd619e67fd92a57980b7f9b7724b19bf1717 Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Mon, 21 Jul 2025 16:37:25 +0545 Subject: [PATCH 5/9] refactor: update the width of first user signup page --- packages/user/src/views/SignupFirstUser.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/user/src/views/SignupFirstUser.tsx b/packages/user/src/views/SignupFirstUser.tsx index 103788701..44a2d8063 100644 --- a/packages/user/src/views/SignupFirstUser.tsx +++ b/packages/user/src/views/SignupFirstUser.tsx @@ -1,17 +1,17 @@ import { useTranslation } from "@dzangolab/react-i18n"; -import { Card, CardBody, Page } from "@dzangolab/react-ui"; +import { AuthPage, Card, CardBody } from "@dzangolab/react-ui"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; -import { getIsFirstUser, signUpFirstUser } from "@/api/user"; -import { DEFAULT_PATHS } from "@/constants"; -import { useConfig, useUser } from "@/hooks"; - import { login, SignupForm } from ".."; import type { LoginCredentials } from "@/types"; +import { getIsFirstUser, signUpFirstUser } from "@/api/user"; +import { DEFAULT_PATHS } from "@/constants"; +import { useConfig, useUser } from "@/hooks"; + export const SignUpFirstUser = ({ centered = true, }: { @@ -99,13 +99,13 @@ export const SignUpFirstUser = ({ }; return ( - {renderPageContent()} - + ); }; From 660294220dccdb11f58a44c7d73e7d953b024b0a Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Mon, 21 Jul 2025 17:08:36 +0545 Subject: [PATCH 6/9] refactor: update signup first user page --- packages/user/src/views/SignupFirstUser.tsx | 36 +++++++++++---------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/user/src/views/SignupFirstUser.tsx b/packages/user/src/views/SignupFirstUser.tsx index 44a2d8063..28952c4b8 100644 --- a/packages/user/src/views/SignupFirstUser.tsx +++ b/packages/user/src/views/SignupFirstUser.tsx @@ -1,5 +1,5 @@ import { useTranslation } from "@dzangolab/react-i18n"; -import { AuthPage, Card, CardBody } from "@dzangolab/react-ui"; +import { AuthPage, Message } from "@dzangolab/react-ui"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; @@ -74,27 +74,29 @@ export const SignUpFirstUser = ({ }) .catch(() => { setSignUpFirstUserLoading(false); - toast.error(`${t("firstUser.signup.messages.error")}`); + setIsError(true); }); }; const renderPageContent = () => { - if (isError) { - return ( - - -

{t(`errors:errors.otherErrors`)}

-
-
- ); - } - return ( - + <> + {isError && ( + { + setIsError(false); + }} + severity="danger" + /> + )} + + ); }; From 5a8efe54230804186b41e7c4230716fcfa818d89 Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Thu, 24 Jul 2025 15:17:33 +0545 Subject: [PATCH 7/9] fix: fix issue to login app user using first signup form in admin app --- packages/user/src/api/user/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/user/src/api/user/index.ts b/packages/user/src/api/user/index.ts index 4f3b33fa3..e0d4528e5 100644 --- a/packages/user/src/api/user/index.ts +++ b/packages/user/src/api/user/index.ts @@ -28,7 +28,7 @@ export const signUpFirstUser = async ( withCredentials: true, }); - if (response.data.status === "ERROR") { + if (response.data.status === "EMAIL_ALREADY_EXISTS_ERROR") { throw new Error(response.data.message); } else { return response.data; From 10d69f539c171dbd191a04a5b4c67a6cc894336f Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Thu, 24 Jul 2025 15:18:51 +0545 Subject: [PATCH 8/9] style: fix coding standard --- packages/user/src/components/Login/LoginWrapper.tsx | 8 ++++---- packages/user/src/components/Signup/SignupWrapper.tsx | 8 ++++---- packages/user/src/views/SignupFirstUser.tsx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/user/src/components/Login/LoginWrapper.tsx b/packages/user/src/components/Login/LoginWrapper.tsx index 86e074e0d..b1f807acd 100644 --- a/packages/user/src/components/Login/LoginWrapper.tsx +++ b/packages/user/src/components/Login/LoginWrapper.tsx @@ -3,6 +3,10 @@ import { Message } from "@dzangolab/react-ui"; import { FC, useState } from "react"; import { toast } from "react-toastify"; +import { DEFAULT_PATHS } from "@/constants"; +import { login } from "@/supertokens"; +import { LinkType } from "@/types/types"; + import { LoginForm } from "./LoginForm"; import { useConfig, useUser } from "../../hooks"; import { verifySessionRoles } from "../../supertokens/helpers"; @@ -10,10 +14,6 @@ import { AuthLinks } from "../AuthLinks"; import type { LoginCredentials, SignInUpPromise } from "../../types"; -import { DEFAULT_PATHS } from "@/constants"; -import { login } from "@/supertokens"; -import { LinkType } from "@/types/types"; - interface IProperties { handleSubmit?: (credential: LoginCredentials) => void; onLoginFailed?: (error: Error) => void; diff --git a/packages/user/src/components/Signup/SignupWrapper.tsx b/packages/user/src/components/Signup/SignupWrapper.tsx index 03ff97a2c..ef7bae56b 100644 --- a/packages/user/src/components/Signup/SignupWrapper.tsx +++ b/packages/user/src/components/Signup/SignupWrapper.tsx @@ -3,16 +3,16 @@ import { Message } from "@dzangolab/react-ui"; import React, { useState } from "react"; import { toast } from "react-toastify"; +import { DEFAULT_PATHS } from "@/constants"; +import { signup } from "@/supertokens"; +import { LinkType } from "@/types/types"; + import { AuthLinks } from "../AuthLinks"; import { SignupForm } from "./SignupForm"; import { useConfig, useUser } from "../../hooks"; import type { LoginCredentials, SignInUpPromise } from "../../types"; -import { DEFAULT_PATHS } from "@/constants"; -import { signup } from "@/supertokens"; -import { LinkType } from "@/types/types"; - interface IProperties { loading?: boolean; showForgotPasswordLink?: boolean; diff --git a/packages/user/src/views/SignupFirstUser.tsx b/packages/user/src/views/SignupFirstUser.tsx index 28952c4b8..f42274ed9 100644 --- a/packages/user/src/views/SignupFirstUser.tsx +++ b/packages/user/src/views/SignupFirstUser.tsx @@ -4,14 +4,14 @@ import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; -import { login, SignupForm } from ".."; - -import type { LoginCredentials } from "@/types"; - import { getIsFirstUser, signUpFirstUser } from "@/api/user"; import { DEFAULT_PATHS } from "@/constants"; import { useConfig, useUser } from "@/hooks"; +import { login, SignupForm } from ".."; + +import type { LoginCredentials } from "@/types"; + export const SignUpFirstUser = ({ centered = true, }: { From 9ef63fe4a1fe6778bd0ee66ef5f78fc93c1b19ba Mon Sep 17 00:00:00 2001 From: Bishal Shrestha Date: Thu, 24 Jul 2025 16:06:46 +0545 Subject: [PATCH 9/9] style: fix coding standard --- packages/user/src/components/Login/LoginWrapper.tsx | 8 ++++---- packages/user/src/components/Signup/SignupWrapper.tsx | 2 +- packages/user/src/views/SignupFirstUser.tsx | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/user/src/components/Login/LoginWrapper.tsx b/packages/user/src/components/Login/LoginWrapper.tsx index 68c0727ac..35652790a 100644 --- a/packages/user/src/components/Login/LoginWrapper.tsx +++ b/packages/user/src/components/Login/LoginWrapper.tsx @@ -3,6 +3,10 @@ import { Message } from "@prefabs.tech/react-ui"; import { FC, useState } from "react"; import { toast } from "react-toastify"; +import { DEFAULT_PATHS } from "@/constants"; +import { login } from "@/supertokens"; +import { LinkType } from "@/types/types"; + import { LoginForm } from "./LoginForm"; import { useConfig, useUser } from "../../hooks"; import { verifySessionRoles } from "../../supertokens/helpers"; @@ -10,10 +14,6 @@ import { AuthLinks } from "../AuthLinks"; import type { LoginCredentials, SignInUpPromise } from "../../types"; -import { DEFAULT_PATHS } from "@/constants"; -import { login } from "@/supertokens"; -import { LinkType } from "@/types/types"; - interface IProperties { handleSubmit?: (credential: LoginCredentials) => void; onLoginFailed?: (error: Error) => void; diff --git a/packages/user/src/components/Signup/SignupWrapper.tsx b/packages/user/src/components/Signup/SignupWrapper.tsx index d83c7b3b6..69124249a 100644 --- a/packages/user/src/components/Signup/SignupWrapper.tsx +++ b/packages/user/src/components/Signup/SignupWrapper.tsx @@ -1,5 +1,5 @@ -import { Message } from "@prefabs.tech/react-ui"; import { useTranslation } from "@prefabs.tech/react-i18n"; +import { Message } from "@prefabs.tech/react-ui"; import React, { useState } from "react"; import { toast } from "react-toastify"; diff --git a/packages/user/src/views/SignupFirstUser.tsx b/packages/user/src/views/SignupFirstUser.tsx index eac9c5471..cf75d69bc 100644 --- a/packages/user/src/views/SignupFirstUser.tsx +++ b/packages/user/src/views/SignupFirstUser.tsx @@ -4,14 +4,14 @@ import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { toast } from "react-toastify"; -import { login, SignupForm } from ".."; - -import type { LoginCredentials } from "@/types"; - import { getIsFirstUser, signUpFirstUser } from "@/api/user"; import { DEFAULT_PATHS } from "@/constants"; import { useConfig, useUser } from "@/hooks"; +import { login, SignupForm } from ".."; + +import type { LoginCredentials } from "@/types"; + export const SignUpFirstUser = ({ centered = true, }: {