{label}}
{tag}
diff --git a/client/src/lib/stores/auth-store.ts b/client/src/lib/stores/auth-store.ts
index 3581a56..2532eab 100644
--- a/client/src/lib/stores/auth-store.ts
+++ b/client/src/lib/stores/auth-store.ts
@@ -1,4 +1,4 @@
-import { createJSONStorage, persist } from "zustand/middleware";
+import { createJSONStorage, devtools, persist } from "zustand/middleware";
import { create } from "zustand";
interface AuthStoreState {
@@ -6,19 +6,29 @@ interface AuthStoreState {
setEmail: (email: string) => void;
authorized: boolean;
setAuthorized: (authorized: boolean) => void;
+ loading: boolean;
+ setLoading: (loading: boolean) => void;
}
-export const useAuthStore = create(
- persist
(
- (set) => ({
- email: "",
- setEmail: (email: string) => set({ email }),
- authorized: false,
- setAuthorized: (authorized: boolean) => set({ authorized }),
- }),
- {
- name: "email",
- storage: createJSONStorage(() => sessionStorage),
- }
+export const useAuthStore = create()(
+ devtools(
+ persist(
+ (set) => ({
+ email: "",
+ setEmail: (email: string) => set({ email }),
+ authorized: false,
+ setAuthorized: (authorized: boolean) => set({ authorized }),
+ loading: false,
+ setLoading: (loading: boolean) => set({ loading }),
+ }),
+ {
+ name: "go-react-auth",
+ partialize: (state) => ({
+ email: state.email,
+ authorized: state.authorized,
+ }),
+ storage: createJSONStorage(() => sessionStorage),
+ }
+ )
)
);
diff --git a/client/src/pages/forgot-password/_components/forgot-password-back.tsx b/client/src/pages/forgot-password/_components/forgot-password-back.tsx
new file mode 100644
index 0000000..33c53a1
--- /dev/null
+++ b/client/src/pages/forgot-password/_components/forgot-password-back.tsx
@@ -0,0 +1,11 @@
+import { useAuthStore } from "@/lib/stores/auth-store";
+import { SwitchAuth } from "@/components/switch-auth";
+import { AppRoutes } from "@/constants/routes";
+
+const ForgotPasswordBack = () => {
+ const { loading } = useAuthStore();
+
+ return ;
+};
+
+export { ForgotPasswordBack };
diff --git a/client/src/pages/forgot-password/_components/forgot-password-form.tsx b/client/src/pages/forgot-password/_components/forgot-password-form.tsx
index a841d7e..7696de5 100644
--- a/client/src/pages/forgot-password/_components/forgot-password-form.tsx
+++ b/client/src/pages/forgot-password/_components/forgot-password-form.tsx
@@ -7,21 +7,28 @@ import { GenericResponse } from "@/lib/classes/generic-response-class";
import { ErrorResponse } from "@/lib/classes/error-response-class";
import { AuthService } from "@/lib/services/auth-service";
import { ValidateEmail } from "@/lib/utils/validations";
+import { useAuthStore } from "@/lib/stores/auth-store";
import { FORGOTPASSWORDKEY } from "@/constants/keys";
import { Button } from "@/components/text-button";
import { Input } from "@/components/input";
const ForgotPasswordForm = () => {
+ const { setLoading: setGlobalLoading } = useAuthStore();
const [submitted, setSubmitted] = useState(false);
const [email, setEmail] = useState("");
+
const { mutate, isPending } = useMutation({
mutationKey: [FORGOTPASSWORDKEY],
mutationFn: AuthService.forgotPassword,
onSuccess: (res: GenericResponse) => {
toast.success(res.message);
setSubmitted(true);
+ setGlobalLoading(false);
+ },
+ onError: (error: ErrorResponse) => {
+ toast.error(error.message);
+ setGlobalLoading(false);
},
- onError: (error: ErrorResponse) => toast.error(error.message),
});
const onSubmit = (e: FormEvent) => {
@@ -34,6 +41,7 @@ const ForgotPasswordForm = () => {
const emailData = forgotPasswordData["email"] as string;
setEmail(emailData);
+ setGlobalLoading(true);
mutate(emailData);
};
diff --git a/client/src/pages/forgot-password/page.tsx b/client/src/pages/forgot-password/page.tsx
index bd4dbe2..ab82818 100644
--- a/client/src/pages/forgot-password/page.tsx
+++ b/client/src/pages/forgot-password/page.tsx
@@ -1,8 +1,8 @@
-import { SwitchAuth } from "@/components/switch-auth";
-import { ForgotPasswordForm } from "./_components/forgot-password-form";
-import { AppRoutes } from "@/constants/routes";
import { AuthTitle } from "@/components/auth-title";
+import { ForgotPasswordForm } from "./_components/forgot-password-form";
+import { ForgotPasswordBack } from "./_components/forgot-password-back";
+
const ForgotPasswordPage = () => {
return (
@@ -13,7 +13,7 @@ const ForgotPasswordPage = () => {
-
+
);
};
diff --git a/client/src/pages/resend-verify/page.tsx b/client/src/pages/resend-verify/page.tsx
deleted file mode 100644
index 595a57e..0000000
--- a/client/src/pages/resend-verify/page.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { AuthTitle } from "@/components/auth-title";
-
-const ResendVerifyPage = () => {
- return (
-
- );
-};
-
-export { ResendVerifyPage };
diff --git a/client/src/pages/reset-password/_components/reset-password-back.tsx b/client/src/pages/reset-password/_components/reset-password-back.tsx
new file mode 100644
index 0000000..83b0ae0
--- /dev/null
+++ b/client/src/pages/reset-password/_components/reset-password-back.tsx
@@ -0,0 +1,11 @@
+import { useAuthStore } from "@/lib/stores/auth-store";
+import { SwitchAuth } from "@/components/switch-auth";
+import { AppRoutes } from "@/constants/routes";
+
+const ResetPasswordBack = () => {
+ const { loading } = useAuthStore();
+
+ return ;
+};
+
+export { ResetPasswordBack };
diff --git a/client/src/pages/reset-password/_components/reset-password-form.tsx b/client/src/pages/reset-password/_components/reset-password-form.tsx
index cfc939b..2e121e2 100644
--- a/client/src/pages/reset-password/_components/reset-password-form.tsx
+++ b/client/src/pages/reset-password/_components/reset-password-form.tsx
@@ -7,6 +7,7 @@ import { GenericResponse } from "@/lib/classes/generic-response-class";
import { ErrorResponse } from "@/lib/classes/error-response-class";
import { RESET_PASSWORD_INPUTS } from "@/constants/collections";
import { AuthService } from "@/lib/services/auth-service";
+import { useAuthStore } from "@/lib/stores/auth-store";
import { RESETPASSWORDKEY } from "@/constants/keys";
import { Button } from "@/components/text-button";
import { AppRoutes } from "@/constants/routes";
@@ -14,17 +15,23 @@ import { ResetDTO } from "@/lib/DTO/reset-dto";
import { Input } from "@/components/input";
const ResetPasswordForm = () => {
+ const { setLoading: setGlobalLoading } = useAuthStore();
const navigate = useNavigate();
const { token } = useParams();
const [confirmPassword, setConfirmPassword] = useState("");
+
const { mutate, isPending } = useMutation({
mutationKey: [RESETPASSWORDKEY],
mutationFn: AuthService.resetPassword,
onSuccess: (res: GenericResponse) => {
toast.success(res.message);
+ setGlobalLoading(false);
navigate(AppRoutes.SignIn);
},
- onError: (error: ErrorResponse) => toast.error(error.message),
+ onError: (error: ErrorResponse) => {
+ toast.error(error.message);
+ setGlobalLoading(false);
+ },
});
const onSubmit = (e: FormEvent) => {
@@ -40,6 +47,8 @@ const ResetPasswordForm = () => {
resetPasswordData.token = token;
+ setGlobalLoading(true);
+
mutate(resetPasswordData);
};
diff --git a/client/src/pages/reset-password/page.tsx b/client/src/pages/reset-password/page.tsx
index 91ede2b..621a711 100644
--- a/client/src/pages/reset-password/page.tsx
+++ b/client/src/pages/reset-password/page.tsx
@@ -1,8 +1,7 @@
-import { SwitchAuth } from "@/components/switch-auth";
import { AuthTitle } from "@/components/auth-title";
-import { AppRoutes } from "@/constants/routes";
import { ResetPasswordForm } from "./_components/reset-password-form";
+import { ResetPasswordBack } from "./_components/reset-password-back";
const ResetPasswordPage = () => {
return (
@@ -11,7 +10,7 @@ const ResetPasswordPage = () => {
-
+
);
};
diff --git a/client/src/pages/sign-in/_components/no-account-yet.tsx b/client/src/pages/sign-in/_components/no-account-yet.tsx
new file mode 100644
index 0000000..14c0704
--- /dev/null
+++ b/client/src/pages/sign-in/_components/no-account-yet.tsx
@@ -0,0 +1,18 @@
+import { useAuthStore } from "@/lib/stores/auth-store";
+import { SwitchAuth } from "@/components/switch-auth";
+import { AppRoutes } from "@/constants/routes";
+
+const NoAccountYet = () => {
+ const { loading } = useAuthStore();
+
+ return (
+
+ );
+};
+
+export { NoAccountYet };
diff --git a/client/src/pages/sign-in/_components/sign-in-form.tsx b/client/src/pages/sign-in/_components/sign-in-form.tsx
index 3ed588d..afdb1fa 100644
--- a/client/src/pages/sign-in/_components/sign-in-form.tsx
+++ b/client/src/pages/sign-in/_components/sign-in-form.tsx
@@ -16,21 +16,29 @@ import { Input } from "@/components/input";
const SignInForm = () => {
const navigate = useNavigate();
- const { setEmail, setAuthorized } = useAuthStore();
+ const {
+ setEmail,
+ setAuthorized,
+ setLoading: setGlobalLoading,
+ } = useAuthStore();
+
const { mutate, isPending } = useMutation({
mutationKey: [SIGNINKEY],
mutationFn: AuthService.signIn,
onSuccess: (res: GenericResponse) => {
toast.success(res.message);
setAuthorized(true);
+ setGlobalLoading(false);
},
onError: (error: ErrorResponse) => {
if (error.status == 403) {
toast.error("Please verify to sign in");
+ setGlobalLoading(false);
navigate(AppRoutes.VerifyEmail);
} else {
toast.error(error.message);
setAuthorized(false);
+ setGlobalLoading(false);
}
},
});
@@ -43,6 +51,7 @@ const SignInForm = () => {
const signInData = Object.fromEntries(formData.entries()) as SignInDTO;
setEmail(signInData.email);
+ setGlobalLoading(true);
mutate(signInData);
};
diff --git a/client/src/pages/sign-in/page.tsx b/client/src/pages/sign-in/page.tsx
index 10837dd..f8d4317 100644
--- a/client/src/pages/sign-in/page.tsx
+++ b/client/src/pages/sign-in/page.tsx
@@ -1,8 +1,7 @@
-import { SwitchAuth } from "@/components/switch-auth";
import { AuthTitle } from "@/components/auth-title";
-import { AppRoutes } from "@/constants/routes";
import { Or } from "@/components/or";
+import { NoAccountYet } from "./_components/no-account-yet";
import { SignInForm } from "./_components/sign-in-form";
const SignInPage = () => {
@@ -14,11 +13,7 @@ const SignInPage = () => {
-
+
);
};
diff --git a/client/src/pages/sign-up/_components/already-have-account.tsx b/client/src/pages/sign-up/_components/already-have-account.tsx
new file mode 100644
index 0000000..50e7999
--- /dev/null
+++ b/client/src/pages/sign-up/_components/already-have-account.tsx
@@ -0,0 +1,18 @@
+import { useAuthStore } from "@/lib/stores/auth-store";
+import { SwitchAuth } from "@/components/switch-auth";
+import { AppRoutes } from "@/constants/routes";
+
+const AlreadyHaveAccount = () => {
+ const { loading } = useAuthStore();
+
+ return (
+
+ );
+};
+
+export { AlreadyHaveAccount };
diff --git a/client/src/pages/sign-up/_components/sign-up-form.tsx b/client/src/pages/sign-up/_components/sign-up-form.tsx
index 338d88e..2c296ca 100644
--- a/client/src/pages/sign-up/_components/sign-up-form.tsx
+++ b/client/src/pages/sign-up/_components/sign-up-form.tsx
@@ -6,6 +6,7 @@ import { toast } from "sonner";
import { ErrorResponse } from "@/lib/classes/error-response-class";
import { AuthService } from "@/lib/services/auth-service";
import { SIGNUP_INPUTS } from "@/constants/collections";
+import { useAuthStore } from "@/lib/stores/auth-store";
import { SignUpDTO } from "@/lib/DTO/sign-up-dto";
import { Button } from "@/components/text-button";
import { AppRoutes } from "@/constants/routes";
@@ -13,6 +14,7 @@ import { SIGNUPKEY } from "@/constants/keys";
import { Input } from "@/components/input";
const SignUpForm = () => {
+ const { setLoading: setGlobalLoading } = useAuthStore();
const [confirmPassword, setConfirmPassword] = useState("");
const navigate = useNavigate();
@@ -21,9 +23,13 @@ const SignUpForm = () => {
mutationFn: AuthService.signUp,
onSuccess: () => {
toast.success("Registered successfully");
+ setGlobalLoading(false);
navigate(AppRoutes.SignIn);
},
- onError: (error: ErrorResponse) => toast.error(error.message),
+ onError: (error: ErrorResponse) => {
+ toast.error(error.message);
+ setGlobalLoading(false);
+ },
});
const onSubmit = (e: FormEvent) => {
@@ -33,6 +39,8 @@ const SignUpForm = () => {
const signUpData = Object.fromEntries(formData.entries()) as SignUpDTO;
+ setGlobalLoading(true);
+
mutate(signUpData);
};
diff --git a/client/src/pages/sign-up/page.tsx b/client/src/pages/sign-up/page.tsx
index 2cf996c..7aef38e 100644
--- a/client/src/pages/sign-up/page.tsx
+++ b/client/src/pages/sign-up/page.tsx
@@ -1,8 +1,7 @@
-import { SwitchAuth } from "@/components/switch-auth";
import { AuthTitle } from "@/components/auth-title";
-import { AppRoutes } from "@/constants/routes";
import { Or } from "@/components/or";
+import { AlreadyHaveAccount } from "./_components/already-have-account";
import { SignUpForm } from "./_components/sign-up-form";
const SignUpPage = () => {
@@ -14,11 +13,7 @@ const SignUpPage = () => {
-
+
);
};
diff --git a/client/src/pages/verify-email/_components/resend-code.tsx b/client/src/pages/verify-email/_components/resend-code.tsx
index 83c8a16..c83dba2 100644
--- a/client/src/pages/verify-email/_components/resend-code.tsx
+++ b/client/src/pages/verify-email/_components/resend-code.tsx
@@ -8,16 +8,31 @@ import { useAuthStore } from "@/lib/stores/auth-store";
import { RESENDVERIFYKEY } from "@/constants/keys";
const ResendCode = () => {
- const { email } = useAuthStore();
+ const {
+ email,
+ loading: globalLoading,
+ setLoading: setGlobalLoading,
+ } = useAuthStore();
const { mutate, isPending } = useMutation({
mutationKey: [RESENDVERIFYKEY],
mutationFn: AuthService.resendVerify,
- onSuccess: (res: GenericResponse) => toast.success(res.message),
- onError: (error: ErrorResponse) => toast.error(error.message),
+ onSuccess: (res: GenericResponse) => {
+ toast.success(res.message);
+ setGlobalLoading(false);
+ },
+ onError: (error: ErrorResponse) => {
+ toast.error(error.message);
+ setGlobalLoading(false);
+ },
});
- const onClick = () => mutate(email);
+ const onClick = () => {
+ setGlobalLoading(true);
+ mutate(email);
+ };
+
+ const loading = isPending || globalLoading;
return (
{
disabled:text-secondary/50 disabled:pointer-events-none"
type="button"
onClick={onClick}
- disabled={isPending}
+ disabled={loading}
>
- {isPending ? "Resending..." : "Resend"}
+ {loading ? "Resending..." : "Resend"}
);
diff --git a/client/src/pages/verify-email/_components/verify-email-form.tsx b/client/src/pages/verify-email/_components/verify-email-form.tsx
index fca6e28..2e78950 100644
--- a/client/src/pages/verify-email/_components/verify-email-form.tsx
+++ b/client/src/pages/verify-email/_components/verify-email-form.tsx
@@ -6,6 +6,7 @@ import { toast } from "sonner";
import { GenericResponse } from "@/lib/classes/generic-response-class";
import { ErrorResponse } from "@/lib/classes/error-response-class";
import { AuthService } from "@/lib/services/auth-service";
+import { useAuthStore } from "@/lib/stores/auth-store";
import { Button } from "@/components/text-button";
import { VERIFYEMAILKEY } from "@/constants/keys";
import { AppRoutes } from "@/constants/routes";
@@ -13,6 +14,8 @@ import { AppRoutes } from "@/constants/routes";
import { SingleInput } from "./single-input";
const VerifyEmailForm = () => {
+ const { loading: globalLoading, setLoading: setGlobalLoading } =
+ useAuthStore();
const [code, setCode] = useState(["", "", "", ""]);
const inputRef = useRef([]);
const formRef = useRef(null);
@@ -23,9 +26,13 @@ const VerifyEmailForm = () => {
mutationFn: AuthService.verifyEmail,
onSuccess: (res: GenericResponse) => {
toast.success(res.message);
+ setGlobalLoading(false);
navigate(AppRoutes.SignIn);
},
- onError: (error: ErrorResponse) => toast.error(error.message),
+ onError: (error: ErrorResponse) => {
+ toast.error(error.message);
+ setGlobalLoading(false);
+ },
});
const onChange = (value: string, index: number) => {
@@ -73,6 +80,8 @@ const VerifyEmailForm = () => {
const verificationCode = code.join("");
+ setGlobalLoading(true);
+
mutate(verificationCode);
};
@@ -83,6 +92,8 @@ const VerifyEmailForm = () => {
}
}, [code]);
+ const loading = isPending || globalLoading;
+
return (