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..7dd0827 100644 --- a/frontend/src/components/Chat/ChatLoading.tsx +++ b/frontend/src/components/Chat/ChatLoading.tsx @@ -2,9 +2,9 @@ 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..415e536 100644 --- a/frontend/src/components/common/html/Input.tsx +++ b/frontend/src/components/common/html/Input.tsx @@ -8,7 +8,11 @@ const Input = forwardRef((props, ref) => { return ( <> diff --git a/frontend/src/components/login/Login.tsx b/frontend/src/components/login/Login.tsx index 72cc280..ea75d44 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,16 @@ const Login = () => { //값 확인용 if (isLoginValid) { - await signInWithCredential(loginData); + await signInWithCredential(loginData) + .then(() => { + closeAll(); + navigate("/"); + }) + .catch(() => { + setEmailError("이메일을 확인해주세요."); + setPasswordError("비밀번호를 확인해주세요."); + }); + // zustand로 관리하는 user가 업데이트가 바로 안이루어져서, // 임시 방편으로 updateUserInfo 가 userData를 반환하게끔 하고 // 반환값을 사용하도록 하자 @@ -96,8 +105,6 @@ const Login = () => { uid: string; username: string; }; - closeAll(); - navigate("/"); // 여기서 맞춤상품 api 호출 처리 try { @@ -118,7 +125,6 @@ const Login = () => { }); } } catch (error) { - console.log(error); const errorMessage = "예기치 못한 에러가 발생하였습니다. 다시 시도해주세요."; if (isLoggedIn) { @@ -137,6 +143,7 @@ const Login = () => { { { 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: "남성" }, @@ -96,74 +97,69 @@ 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; } } + }; - //값 확인용 - if (isSignUpRequiredValid) { + const submitHandle = (e: React.FormEvent) => { + e.preventDefault(); + + 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); @@ -177,7 +173,15 @@ const SignUpRequired = () => { gender: signUpRequired.gender === "남성" ? "male" : "female", username: signUpRequired.username, birthDate: signUpRequired.birthDate, - }).then(updateUserInfo); + }) + .then(updateUserInfo) + .catch((data) => { + if (data.code === "auth/email-already-in-use") + setEmailError("이미 사용중인 이메일입니다"); + else if (data.code === "auth/weak-password") { + setPasswordError("비밀번호는 6자 이상이어야합니다"); + } + }); } }; @@ -200,11 +204,19 @@ const SignUpRequired = () => { type="email" name="email" placeholder={user?.email || "이메일을 입력해주세요"} - className="h-[48px] w-full rounded-[4px] px-4 py-[14px]" + className={`py-[14px h-[48px] w-full rounded-[4px] px-4`} + 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 +225,7 @@ const SignUpRequired = () => { ref={passwordRef} type="password" name="password" + isErrored={passwordError} placeholder={ user?.email ? "소셜 로그인 회원입니다." @@ -231,6 +244,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,18 +267,16 @@ const SignUpRequired = () => {
b.value - a.value)} onChange={(value) => { setBirthYear(value); updateBirthDate(value, birthMonth, birthDay); }} /> { }} /> {
{/*회원가입 다음 페이지로 이동 버튼*/} - +
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"] : [], + }, +}));