diff --git a/src/pages/SigninPage.tsx b/src/pages/AuthPage/SigninPage.tsx
similarity index 74%
rename from src/pages/SigninPage.tsx
rename to src/pages/AuthPage/SigninPage.tsx
index 3085cc7..3e994bb 100644
--- a/src/pages/SigninPage.tsx
+++ b/src/pages/AuthPage/SigninPage.tsx
@@ -1,8 +1,12 @@
+import { useState, useEffect } from "react";
+
import { AxiosError } from "axios";
import { useNavigate, Link } from "react-router-dom";
-import Logo from "../assets/logo/thejulge.svg?react";
-import { useAuthForm } from "../hooks/useAuthForm";
+import Logo from "../../assets/logo/thejulge.svg?react";
+
+import Spinner from "./components/Spinner";
+import { useAuthForm } from "./hooks/useAuthForm";
import { postAuthentication } from "@/apis/services/authenticationService";
import Button from "@/components/Button";
@@ -13,13 +17,28 @@ import { useModalStore } from "@/store/useModalStore";
export default function SigninPage() {
const navigate = useNavigate();
- const { setUserAndToken } = useUserStore();
+ const { user, setUserAndToken } = useUserStore();
const { openModal, closeModal } = useModalStore();
const { formData, errors, isFormValid, handleChange, resetForm } =
useAuthForm("signin");
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ useEffect(() => {
+ if (user) {
+ if (user.type === "employer") {
+ navigate(ROUTES.SHOP.ROOT);
+ } else if (user.type === "employee") {
+ navigate(ROUTES.PROFILE.ROOT);
+ }
+ }
+ }, [user, navigate]);
+
const handleSubmit = async () => {
+ if (isSubmitting) return;
+ setIsSubmitting(true);
+
try {
const res = await postAuthentication({
email: formData.email,
@@ -72,13 +91,15 @@ export default function SigninPage() {
},
],
});
+ } finally {
+ setIsSubmitting(false);
}
};
return (
-
+
-
+
diff --git a/src/pages/SignupPage.tsx b/src/pages/AuthPage/SignupPage.tsx
similarity index 84%
rename from src/pages/SignupPage.tsx
rename to src/pages/AuthPage/SignupPage.tsx
index b3460b3..7c9f2dc 100644
--- a/src/pages/SignupPage.tsx
+++ b/src/pages/AuthPage/SignupPage.tsx
@@ -1,10 +1,14 @@
+import { useState, useEffect } from "react";
+
import { AxiosError } from "axios";
import clsx from "clsx";
import { useNavigate, Link } from "react-router-dom";
-import IconCheck from "../assets/icon/check.svg?react";
-import Logo from "../assets/logo/thejulge.svg?react";
-import { useAuthForm } from "../hooks/useAuthForm";
+import IconCheck from "../../assets/icon/check.svg?react";
+import Logo from "../../assets/logo/thejulge.svg?react";
+
+import Spinner from "./components/Spinner";
+import { useAuthForm } from "./hooks/useAuthForm";
import { postAuthentication } from "@/apis/services/authenticationService";
import { postUser } from "@/apis/services/userService";
@@ -16,7 +20,7 @@ import { useModalStore } from "@/store/useModalStore";
export default function SignupPage() {
const navigate = useNavigate();
- const { setUserAndToken } = useUserStore();
+ const { user, setUserAndToken } = useUserStore();
const { openModal, closeModal } = useModalStore();
const {
@@ -28,7 +32,22 @@ export default function SignupPage() {
resetForm,
} = useAuthForm("signup");
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ useEffect(() => {
+ if (user) {
+ if (user.type === "employer") {
+ navigate(ROUTES.SHOP.ROOT);
+ } else if (user.type === "employee") {
+ navigate(ROUTES.PROFILE.ROOT);
+ }
+ }
+ }, [user, navigate]);
+
const handleSubmit = async () => {
+ if (isSubmitting) return;
+ setIsSubmitting(true);
+
try {
const response = await postUser({
email: formData.email,
@@ -90,13 +109,15 @@ export default function SignupPage() {
},
],
});
+ } finally {
+ setIsSubmitting(false);
}
};
return (
-
+
-
+
diff --git a/src/pages/AuthPage/components/Spinner.tsx b/src/pages/AuthPage/components/Spinner.tsx
new file mode 100644
index 0000000..05120ab
--- /dev/null
+++ b/src/pages/AuthPage/components/Spinner.tsx
@@ -0,0 +1,5 @@
+export default function Spinner() {
+ return (
+
+ );
+}
diff --git a/src/hooks/useAuthForm.ts b/src/pages/AuthPage/hooks/useAuthForm.ts
similarity index 76%
rename from src/hooks/useAuthForm.ts
rename to src/pages/AuthPage/hooks/useAuthForm.ts
index 630e387..73dc105 100644
--- a/src/hooks/useAuthForm.ts
+++ b/src/pages/AuthPage/hooks/useAuthForm.ts
@@ -41,24 +41,34 @@ export function useAuthForm(mode: Mode) {
(field: keyof FormData) => (e: React.ChangeEvent
) => {
const value = e.target.value;
setFormData((prev) => ({ ...prev, [field]: value }));
-
if (field === "email") {
- const isValidEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
setErrors((prev) => ({
...prev,
- email: isValidEmail ? undefined : "올바른 이메일 형식이 아닙니다.",
+ email:
+ value.length === 0
+ ? undefined
+ : value.includes("@")
+ ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
+ ? undefined
+ : "올바른 이메일 형식이 아닙니다."
+ : undefined,
}));
}
if (field === "password") {
+ const trimmed = value.trim();
setErrors((prev) => ({
...prev,
password:
- value.length >= 8 ? undefined : "비밀번호는 8자 이상이어야 합니다.",
+ value.length > 0 && trimmed.length === 0
+ ? "비밀번호에 공백만 입력할 수 없습니다."
+ : trimmed.length > 0 && trimmed.length < 8
+ ? "비밀번호는 최소 8자 이상이어야 합니다."
+ : undefined,
...(mode === "signup" &&
formData.confirmPassword && {
confirmPassword:
- value !== formData.confirmPassword
+ trimmed !== formData.confirmPassword
? "비밀번호가 일치하지 않습니다."
: undefined,
}),