diff --git a/frontend/src/apis/firebase/auth.ts b/frontend/src/apis/firebase/auth.ts
index e583fb1..78ca45d 100644
--- a/frontend/src/apis/firebase/auth.ts
+++ b/frontend/src/apis/firebase/auth.ts
@@ -12,8 +12,10 @@ import {
doc,
getDoc,
getDocs,
+ query,
setDoc,
updateDoc,
+ where,
} from "firebase/firestore";
interface UserTypeforSignup {
@@ -69,25 +71,24 @@ const updateUserData = async (key: string, value: string | number) => {
const signUpWithCredential = async (user: UserTypeforSignup & TUser) => {
const { email, password, ...rest } = user;
- await createUserWithEmailAndPassword(auth, email, password)
- .then((credential) => {
+ await createUserWithEmailAndPassword(auth, email, password).then(
+ (credential) => {
setDoc(doc(db, "users", credential.user.uid), {
...rest,
+ email: email,
imgUrl: "",
sizeType: null,
sneakerSize: 0,
});
- })
- .catch((e) => alert(e));
+ }
+ );
};
const signInWithCredential = async (user: {
email: string;
password: string;
}) => {
- await signInWithEmailAndPassword(auth, user.email, user.password)
- .then()
- .catch((e) => alert(e.message));
+ await signInWithEmailAndPassword(auth, user.email, user.password);
};
const signInWithGoogle = async () => {
@@ -96,6 +97,7 @@ const signInWithGoogle = async () => {
const isNew = await signInWithPopup(auth, provider)
.then((credential) => {
setDoc(doc(db, "users", credential.user.uid), {
+ email: credential.user.email,
username: credential.user.displayName,
gender: null,
birthDate: "",
@@ -120,6 +122,14 @@ const logOut = async () => {
.catch((e) => alert(e.message));
};
+const availableAccount = async (email: string) => {
+ const docRef = collection(db, "users");
+ const q = query(docRef, where("email", "==", email));
+ const querySnapshot = await getDocs(q);
+
+ return querySnapshot.empty;
+};
+
export {
getUserData,
updateUserData,
@@ -127,4 +137,5 @@ export {
signInWithCredential,
signInWithGoogle,
logOut,
+ availableAccount,
};
diff --git a/frontend/src/components/Chat/ChatLoading.tsx b/frontend/src/components/Chat/ChatLoading.tsx
index 087b3f5..09482b0 100644
--- a/frontend/src/components/Chat/ChatLoading.tsx
+++ b/frontend/src/components/Chat/ChatLoading.tsx
@@ -1,10 +1,10 @@
const ChatLoading = () => {
return (
-
+
);
diff --git a/frontend/src/components/common/html/DropDown.tsx b/frontend/src/components/common/html/DropDown.tsx
index e8e92d9..d27336e 100644
--- a/frontend/src/components/common/html/DropDown.tsx
+++ b/frontend/src/components/common/html/DropDown.tsx
@@ -41,7 +41,6 @@ const DropDown = forwardRef
((props, ref) => {
setIsOpen(false);
if (onChange) {
onChange(value);
- console.log(value);
}
};
diff --git a/frontend/src/components/common/html/Input.tsx b/frontend/src/components/common/html/Input.tsx
index d98f055..86b6ae9 100644
--- a/frontend/src/components/common/html/Input.tsx
+++ b/frontend/src/components/common/html/Input.tsx
@@ -1,17 +1,21 @@
import { ComponentPropsWithoutRef, forwardRef } from "react";
import { twMerge } from "tailwind-merge";
-type InputProps = ComponentPropsWithoutRef<"input">;
+type InputProps = ComponentPropsWithoutRef<"input"> & { isErrored?: boolean };
const Input = forwardRef((props, ref) => {
const { className, ...rest } = props;
return (
<>
+ />
>
);
});
diff --git a/frontend/src/components/login/Login.tsx b/frontend/src/components/login/Login.tsx
index 72cc280..ef03017 100644
--- a/frontend/src/components/login/Login.tsx
+++ b/frontend/src/components/login/Login.tsx
@@ -45,8 +45,8 @@ const Login = () => {
[name]: value,
});
- if (name === "email") setEmailError("");
- if (name === "password") setPasswordError("");
+ setEmailError("");
+ setPasswordError("");
};
const submitHandle = async (e: React.FormEvent) => {
@@ -87,7 +87,15 @@ const Login = () => {
//값 확인용
if (isLoginValid) {
- await signInWithCredential(loginData);
+ await signInWithCredential(loginData)
+ .then(() => {
+ closeAll();
+ navigate("/");
+ })
+ .catch(() => {
+ setEmailError("이메일을 확인해주세요.");
+ setPasswordError("비밀번호를 확인해주세요.");
+ });
// zustand로 관리하는 user가 업데이트가 바로 안이루어져서,
// 임시 방편으로 updateUserInfo 가 userData를 반환하게끔 하고
// 반환값을 사용하도록 하자
@@ -96,8 +104,6 @@ const Login = () => {
uid: string;
username: string;
};
- closeAll();
- navigate("/");
// 여기서 맞춤상품 api 호출 처리
try {
@@ -137,6 +143,7 @@ const Login = () => {
{
{
const location = useLocation();
diff --git a/frontend/src/components/signup/SignUp.tsx b/frontend/src/components/signup/SignUp.tsx
index 78e7add..7b53068 100644
--- a/frontend/src/components/signup/SignUp.tsx
+++ b/frontend/src/components/signup/SignUp.tsx
@@ -1,5 +1,5 @@
-import SignUpRequired from "./SignUpRequired";
-import SignUpAdditional from "./SignUpAdditional";
+import SignUpRequired from "@components/signUp/SignUpRequired";
+import SignUpAdditional from "@components/signUp/SignUpAdditional";
import userStore from "@store/auth.store.ts";
import { redirect } from "react-router-dom";
diff --git a/frontend/src/components/signup/SignUpRequired.tsx b/frontend/src/components/signup/SignUpRequired.tsx
index 5a40306..873831d 100644
--- a/frontend/src/components/signup/SignUpRequired.tsx
+++ b/frontend/src/components/signup/SignUpRequired.tsx
@@ -3,7 +3,11 @@ import InputField from "@common/InputField";
import Input from "@common/html/Input";
import BottomButton from "@common/BottomButton";
import DropDown, { DropDownRef } from "@common/html/DropDown";
-import { signUpWithCredential, updateUserData } from "@apis/firebase/auth";
+import {
+ availableAccount,
+ signUpWithCredential,
+ updateUserData,
+} from "@apis/firebase/auth";
import { useInput } from "@hooks/useInput";
import userStore from "@store/auth.store";
import { auth } from "@/firebase";
@@ -39,9 +43,6 @@ const SignUpRequired = () => {
const [userNameRef, focusUserName, handleUserNamePress] =
useFocus();
const [genderRef, focusGender] = useFocus();
- const [birthYearRef, focusBirthYear] = useFocus();
- const [birthMonthRef, focusBirthMonth] = useFocus();
- const [birthDayRef, focusBirthDay] = useFocus();
const genderOptions: { value: string; label: string }[] = [
{ value: "남성", label: "남성" },
@@ -55,7 +56,7 @@ const SignUpRequired = () => {
const generateYearOptions = (startYear: number, endYear: number) => {
const options: { value: string; label: string }[] = [];
- for (let year = startYear; year <= endYear; year++) {
+ for (let year = endYear; year >= startYear; year--) {
options.push({ value: year.toString(), label: year.toString() });
}
return options;
@@ -96,78 +97,73 @@ const SignUpRequired = () => {
if (name === "username") setnameError("");
};
- const submitHandle = (e: React.FormEvent) => {
- e.preventDefault();
-
+ const checkValidate = () => {
+ let isvalid = true;
const validateEmail = (email: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
focusEmail(); // 이메일 필드 자동 포커스
setEmailError("이메일 형식을 확인해주세요");
- isSignUpRequiredValid = false;
- return false;
- } else {
- setEmailError("");
- return true;
}
};
- let isSignUpRequiredValid = true;
-
if (!signUpRequired.email) {
//아이디 비어있을 때
- if (isSignUpRequiredValid) focusEmail(); // 이메일 필드 자동 포커스
-
+ focusEmail(); // 이메일 필드 자동 포커스
setEmailError("아이디를 입력하세요");
- isSignUpRequiredValid = false;
- } else if (validateEmail(signUpRequired.email)) {
- isSignUpRequiredValid = true;
- }
+ isvalid = false;
+ } else if (emailError.length > 0) {
+ focusEmail();
+ isvalid = false;
+ } else validateEmail(signUpRequired.email);
if (!signUpRequired.password) {
//비밀번호 비어있을 때
- if (isSignUpRequiredValid) focusPassword(); // 비밀번호 필드 자동 포커스
-
+ if (isvalid) focusPassword(); // 비밀번호 필드 자동 포커스
+ isvalid = false;
setPasswordError("비밀번호를 입력하세요");
- isSignUpRequiredValid = false;
}
if (!signUpRequired.username) {
- if (isSignUpRequiredValid) focusUserName(); // 이름 필드 자동 포커스
-
+ if (isvalid) focusUserName(); // 이름 필드 자동 포커스
+ isvalid = false;
setnameError("이름을 입력하세요");
- isSignUpRequiredValid = false;
}
if (!signUpRequired.gender) {
- if (isSignUpRequiredValid) focusGender(); // 성별 필드 자동 포커스
-
+ if (isvalid) focusGender(); // 성별 필드 자동 포커스
+ isvalid = false;
setGenderError("성별을 입력하세요");
- isSignUpRequiredValid = false;
}
if (!signUpRequired.birthDate) {
if (!birthYear) {
- focusBirthYear(); // 년도 필드에 포커스
+ // focusBirthYear(); // 년도 필드에 포커스
setBirthDateError("년도를 선택하세요");
- isSignUpRequiredValid = false;
} else if (!birthMonth) {
- focusBirthMonth(); // 월 필드에 포커스
+ // focusBirthMonth(); // 월 필드에 포커스
setBirthDateError("월을 선택하세요");
- isSignUpRequiredValid = false;
} else if (!birthDay) {
- focusBirthDay(); // 일 필드에 포커스
+ // focusBirthDay(); // 일 필드에 포커스
setBirthDateError("일을 선택하세요");
- isSignUpRequiredValid = false;
}
}
+ };
+
+ const submitHandle = (e: React.FormEvent) => {
+ e.preventDefault();
- //값 확인용
- if (isSignUpRequiredValid) {
+ if (
+ emailError.length === 0 &&
+ passwordError.length === 0 &&
+ genderError.length === 0 &&
+ birthDateError.length === 0 &&
+ nameError.length === 0
+ ) {
if (user) {
updateUserData("gender", signUpRequired.gender);
updateUserData("birthDate", signUpRequired.birthDate);
-
+ console.log(166);
updateUserInfo();
} else
signUpWithCredential({
@@ -177,7 +173,18 @@ const SignUpRequired = () => {
gender: signUpRequired.gender === "남성" ? "male" : "female",
username: signUpRequired.username,
birthDate: signUpRequired.birthDate,
- }).then(updateUserInfo);
+ })
+ .then(() => {
+ updateUserInfo();
+ console.log(179);
+ })
+ .catch((data) => {
+ if (data.code === "auth/email-already-in-use")
+ setEmailError("이미 사용중인 이메일입니다");
+ else if (data.code === "auth/weak-password") {
+ setPasswordError("비밀번호는 6자 이상이어야합니다");
+ }
+ });
}
};
@@ -200,11 +207,19 @@ const SignUpRequired = () => {
type="email"
name="email"
placeholder={user?.email || "이메일을 입력해주세요"}
- className="h-[48px] w-full rounded-[4px] px-4 py-[14px]"
+ className={`h-[48px] w-full rounded-[4px] px-4 py-[14px]`}
+ isErrored={!!emailError}
value={user?.email ? "" : signUpRequired.email}
onChange={handleInputChange}
disabled={user?.email ? true : false}
onKeyDown={(e) => handleEmailPress(e, focusPassword)} // 다음 패스워드 포커스
+ onBlur={async (e) => {
+ const isAvailable = await availableAccount(e.target.value);
+
+ if (!isAvailable) {
+ setEmailError("이미 사용중인 이메일입니다");
+ }
+ }}
/>
{/*패스워드 입력 필드*/}
@@ -213,6 +228,7 @@ const SignUpRequired = () => {
ref={passwordRef}
type="password"
name="password"
+ isErrored={!!passwordError}
placeholder={
user?.email
? "소셜 로그인 회원입니다."
@@ -231,6 +247,7 @@ const SignUpRequired = () => {
ref={userNameRef}
type="text"
name="username"
+ isErrored={!!nameError}
placeholder={user?.displayName || "이름을 입력해주세요"}
className="h-[48px] w-full rounded-[4px] px-4 py-[14px]"
value={user?.displayName ? "" : signUpRequired.username}
@@ -253,7 +270,6 @@ const SignUpRequired = () => {
{
}}
/>
{
}}
/>
{
{/*회원가입 다음 페이지로 이동 버튼*/}
-
+
>
diff --git a/frontend/src/styles/tailwind.css b/frontend/src/styles/tailwind.css
index 2881ba1..7994839 100644
--- a/frontend/src/styles/tailwind.css
+++ b/frontend/src/styles/tailwind.css
@@ -8,6 +8,9 @@
html {
font-family: "Pretendard Variable", system-ui, sans-serif;
}
+ input{
+ outline: none;
+ }
}
/* Custom CSS */
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 53cab5c..4af401e 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -4,7 +4,11 @@ import tsconfigPaths from "vite-tsconfig-paths";
import svgr from "vite-plugin-svgr";
// https://vitejs.dev/config/
-export default defineConfig({
+export default defineConfig(({ mode }) => ({
plugins: [react(), tsconfigPaths(), svgr()],
base: "/stepup_front",
-});
+ esbuild: {
+ drop: ["debugger"],
+ pure: mode === "production" ? ["console.log"] : [],
+ },
+}));