Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions frontend/src/apis/firebase/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import {
doc,
getDoc,
getDocs,
query,
setDoc,
updateDoc,
where,
} from "firebase/firestore";

interface UserTypeforSignup {
Expand Down Expand Up @@ -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 () => {
Expand All @@ -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: "",
Expand All @@ -120,11 +122,20 @@ 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,
signUpWithCredential,
signInWithCredential,
signInWithGoogle,
logOut,
availableAccount,
};
6 changes: 3 additions & 3 deletions frontend/src/components/Chat/ChatLoading.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const ChatLoading = () => {
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-gray-800 bg-opacity-15">

Check warning on line 3 in frontend/src/components/Chat/ChatLoading.tsx

View workflow job for this annotation

GitHub Actions / continuous-integration

Classname 'bg-opacity-15' should be replaced by an opacity suffix (eg. '/15')

Check warning on line 3 in frontend/src/components/Chat/ChatLoading.tsx

View workflow job for this annotation

GitHub Actions / continuous-integration

Classname 'bg-opacity-15' should be replaced by an opacity suffix (eg. '/15')
<div className="flex space-x-6">
<div className="h-3 w-3 animate-pulse rounded-full bg-gray-400" />
<div className="animation-delay-200 h-3 w-3 animate-pulse rounded-full bg-gray-500" />
<div className="animation-delay-400 h-3 w-3 animate-pulse rounded-full bg-gray-600" />
<div className="size-3 animate-pulse rounded-full bg-gray-400" />
<div className="animation-delay-200 size-3 animate-pulse rounded-full bg-gray-500" />

Check warning on line 6 in frontend/src/components/Chat/ChatLoading.tsx

View workflow job for this annotation

GitHub Actions / continuous-integration

Classname 'animation-delay-200' is not a Tailwind CSS class!

Check warning on line 6 in frontend/src/components/Chat/ChatLoading.tsx

View workflow job for this annotation

GitHub Actions / continuous-integration

Classname 'animation-delay-200' is not a Tailwind CSS class!
<div className="animation-delay-400 size-3 animate-pulse rounded-full bg-gray-600" />

Check warning on line 7 in frontend/src/components/Chat/ChatLoading.tsx

View workflow job for this annotation

GitHub Actions / continuous-integration

Classname 'animation-delay-400' is not a Tailwind CSS class!

Check warning on line 7 in frontend/src/components/Chat/ChatLoading.tsx

View workflow job for this annotation

GitHub Actions / continuous-integration

Classname 'animation-delay-400' is not a Tailwind CSS class!
</div>
</div>
);
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/common/html/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const DropDown = forwardRef<DropDownRef, DropDownProps>((props, ref) => {
setIsOpen(false);
if (onChange) {
onChange(value);
console.log(value);
}
};

Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/common/html/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
return (
<>
<input
className={twMerge("border text-body2", className)}
className={twMerge(
"border text-body2 focus:border-grey-600",
className,
rest.isErrored && "border-red-300 text-red"
)}
ref={ref}
{...rest}
></input>
Expand Down
20 changes: 14 additions & 6 deletions frontend/src/components/login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ const Login = () => {
[name]: value,
});

if (name === "email") setEmailError("");
if (name === "password") setPasswordError("");
setEmailError("");
setPasswordError("");
};

const submitHandle = async (e: React.FormEvent) => {
Expand Down Expand Up @@ -87,7 +87,16 @@ const Login = () => {

//값 확인용
if (isLoginValid) {
await signInWithCredential(loginData);
await signInWithCredential(loginData)
.then(() => {
closeAll();
navigate("/");
})
.catch(() => {
setEmailError("이메일을 확인해주세요.");
setPasswordError("비밀번호를 확인해주세요.");
});

// zustand로 관리하는 user가 업데이트가 바로 안이루어져서,
// 임시 방편으로 updateUserInfo 가 userData를 반환하게끔 하고
// 반환값을 사용하도록 하자
Expand All @@ -96,8 +105,6 @@ const Login = () => {
uid: string;
username: string;
};
closeAll();
navigate("/");

// 여기서 맞춤상품 api 호출 처리
try {
Expand All @@ -118,7 +125,6 @@ const Login = () => {
});
}
} catch (error) {
console.log(error);
const errorMessage =
"예기치 못한 에러가 발생하였습니다. 다시 시도해주세요.";
if (isLoggedIn) {
Expand All @@ -137,6 +143,7 @@ const Login = () => {
<InputField title="아이디" error={emailError}>
<Input
ref={emailRef}
isErrored={emailError}
type="email"
name="email"
placeholder="이메일을 입력해주세요"
Expand All @@ -150,6 +157,7 @@ const Login = () => {
<InputField title="비밀번호" error={passwordError}>
<Input
ref={passwordRef}
isErrored={passwordError}
type="password"
name="password"
placeholder="비밀번호를 입력해주세요"
Expand Down
99 changes: 55 additions & 44 deletions frontend/src/components/signup/SignUpRequired.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -39,9 +43,6 @@ const SignUpRequired = () => {
const [userNameRef, focusUserName, handleUserNamePress] =
useFocus<HTMLInputElement>();
const [genderRef, focusGender] = useFocus<DropDownRef>();
const [birthYearRef, focusBirthYear] = useFocus<DropDownRef>();
const [birthMonthRef, focusBirthMonth] = useFocus<DropDownRef>();
const [birthDayRef, focusBirthDay] = useFocus<DropDownRef>();

const genderOptions: { value: string; label: string }[] = [
{ value: "남성", label: "남성" },
Expand Down Expand Up @@ -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);
Expand All @@ -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자 이상이어야합니다");
}
});
}
};

Expand All @@ -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("이미 사용중인 이메일입니다");
}
}}
/>
</InputField>
{/*패스워드 입력 필드*/}
Expand All @@ -213,6 +225,7 @@ const SignUpRequired = () => {
ref={passwordRef}
type="password"
name="password"
isErrored={passwordError}
placeholder={
user?.email
? "소셜 로그인 회원입니다."
Expand All @@ -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}
Expand All @@ -253,18 +267,16 @@ const SignUpRequired = () => {
<InputField title="생년월일" error={birthDateError}>
<div className="flex w-full justify-between space-x-1">
<DropDown
ref={birthYearRef}
className="h-[45px] gap-2 rounded-[6px] border-[#E4E4E7] px-[10px] py-[14px]"
menuPlacement="top"
placeholder="년"
options={birthYearOptions}
options={birthYearOptions.sort((a, b) => b.value - a.value)}
onChange={(value) => {
setBirthYear(value);
updateBirthDate(value, birthMonth, birthDay);
}}
/>
<DropDown
ref={birthMonthRef}
className="h-[45px] gap-2 rounded-[6px] border-[#E4E4E7] px-[10px] py-[14px]"
menuPlacement="top"
placeholder="월"
Expand All @@ -275,7 +287,6 @@ const SignUpRequired = () => {
}}
/>
<DropDown
ref={birthDayRef}
className="h-[45px] gap-2 rounded-[6px] border-[#E4E4E7] px-[10px] py-[14px]"
menuPlacement="top"
placeholder="일"
Expand All @@ -296,7 +307,7 @@ const SignUpRequired = () => {
</div>
<div className="mt-4 px-5">
{/*회원가입 다음 페이지로 이동 버튼*/}
<BottomButton title="다음" type="submit" />
<BottomButton title="다음" type="submit" onClick={checkValidate} />
</div>
</form>
</>
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/styles/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
html {
font-family: "Pretendard Variable", system-ui, sans-serif;
}
input{
outline: none;
}
}

/* Custom CSS */
Expand Down
Loading
Loading