이번엔 회원가입이다. 우선 먼저 상황을 보자면
return (
<S.Wrapper>
<S.HeaderWrapper>
<S.BackButton
src="/auth/arrow_back.svg"
alt="arrow"
width={24}
height={24}
onClick={() => router.push("/auth/login")}
/>
<Margin direction="row" size={14} />
<Text.Title2 color="gray900">회원가입</Text.Title2>
</S.HeaderWrapper>
<StudentCard />
<Text.Title1 color="gray900">학생 정보</Text.Title1>
<Margin direction="column" size={16} />
<InputBox getError={getError} />
<DropDown />
<GenderSelectBox />
<AgreeBox getCheck={getCheck} />
<S.CompleteButton
complete={complete}
onClick={() => (complete ? router.replace("complete") : console.log("disabled"))}
>
<Text.Body1 color={complete ? "white" : "gray500"}>작성완료</Text.Body1>
</S.CompleteButton>
</S.Wrapper>
);
이렇게 돼있었다. 즉, 디자인만 돼있어서 여기에 제출버튼을 눌러야하고, 컴포넌트식으로 다 전부 쪼개져있으니 StudentCard
부터 S.CompleteButton
를 form
태그로 묶어 제출 버튼을 누를 때 그 데이터들이 날아가게 변경회원가입은 API도 4개가 있고 FormData로 넣어야하는 등 좀 많아서 기능별로 작성하겠다.
이렇게 노션에 정리돼 있다. auth/signup
도메인에 결과적으로 요청을 하는 것이다.
보내야할 데이터 내용은 다음과 같다.
idCardImage
string, 학생증 이미지
password
string, 비밀번호
name
string, 이름
isNicknameChecked
boolean, 닉네임 중복 검사를 통과했는지
nickname
string, 닉네임
gender
boolean, 성별, 여자가 true
nation
string, 국적
termsOfUse
boolean, 이용약관 동의 여부
termsOfPersonalInformation
boolean, 개인정보 수집 및 이용동의 여부
termsOfPromotion
boolean, 이벤트 프로모션 알림 동의 여부
거기에 아래와 같이 이메일을 검증하고, 인증 받고, 닉네임 중복까지 서버와 통신해야한다.
구현해야할 기능이 벌써 10개가 넘게 생겨버렸다. 디자인을 이제 볼까?
위와 같다. 이미지 업로드, 인풋 6개, 검증 버튼 3개, 국적 드롭다운, 성별 토글, 동의 버튼까지 10개가 넘어간다.. 진짜 보고 어질어질했다.. 어쩌랴 해야지.
우선 먼저 당연히 컴포넌트로 나뉘어서 개발할 것이기에 전역 관리를 해야해서, 리코일 아톰을 쓸 것이다. 이 아톰이 채워지면 작성완료가 돼서 버튼 활성화를 위해 useEffect
를 써서 뭐 complete
같은 상태를 채워줄 것이다.
그다음 학생증 인증 파트 / 인풋 파트 / 국적 드롭다운 파트 / 성별 토글 버튼 / 동의 파트 이렇게 컴포넌트를 나눌 것이다. 아마 인풋 파트가 너무 많아서 코드가 길어질 거 같은데 그건 나중에 리팩토링하면서 바꿀 것이다.
위 기능 구현 계획에서 본 것처럼 데이터들을 각 타입에 맞게 만들 것이다.
export interface SignUpFormData {
idCardImage: string;
email: string;
password: string;
name: string;
isNicknameChecked: boolean;
nickname: string;
nation: string;
gender: boolean;
termsOfUse: boolean;
termsOfPersonalInformation: boolean;
termsOfPromotion: boolean;
}
이런 식으로 말이다.
그다음 아톰을 만들자.
export const signUpFormDataAtom = atom<SignUpFormData>({
key: "signUpFormDataAtom",
default: {
idCardImage: "",
email: "",
password: "",
name: "",
isNicknameChecked: false,
nickname: "",
nation: "Republic of Korea",
gender: true,
termsOfUse: false,
termsOfPersonalInformation: false,
termsOfPromotion: false,
},
});
기본값들이 필요한 것들은 그대로 나두고, 직관적인 변수명과 각 타입에 맞게 저렇게 만들어 놨다.
오늘은 일단 이렇게 끝내겠다. 다음 편인 이미지 담기까지 하면 포스트가 너무 길어져 보기 안좋을 것이다. 다음 편엔 이미지 담기 input을 토대로 그려나가겠다.
++ 디자인은 이미 완성한 형태로 할 것이다. 기능 면에서 중점적으로 기술할 것이다.
열심히 하셨네요 회원가입이 은근 까다로워서 진뺐었는데 고생하셨습니다. Atom 더보고 싶었는데 아쉽네요 ㅎㅎ