TIL_58_2차 프로젝트 회원가입
내가 구현한 회원가입 페이지.
- 이메일 주소와 비밀번호가 조건에 부합할 경우, 밑에 뜨는 빨간 글씨 경고가 사라지도록 했다.
- 사이즈 선택 모달창을 구현했고, 자식 컴퍼넌트인 모달창에서 얻은 데이터를 부모 컴퍼넌트인 회원가입 페이지에 전달하였다.
- 동의를 구하는 체크박스를 구현. true/ false 로 한번 클릭하면 true -> 한번 더 클릭하면 false를 지정해, 색깔이 바뀌도록 하는 건 당연히 알고있었지만.. styled component로는 처음 구현해보는거여서 좀 헷갈렸다.
- 아이디와 비밀번호의 형식이 부합할 경우에 회원가입 버튼이 활성화 되도록 구현.
- 백엔드 Api 통신도 완료. 서버에 연결되어있을 경우, 회원가입 성공 alert 메세지가 뜨면서 로그인 페이지로 바로 연결되도록 구현했다.
this.state = {
email: "",
pw: "",
//emailCheck: false,
//multiCheckEmail: false,
//pwCheck: false,
//아이디 비밀번호 유효성 확인을 위해 넣어놨던 것..
modalOn: false,
checkOn: false,
checkOnSecond: false,
sizeClick: "",
};
handleModal = e => {
this.setState({ modalOn: !this.state.modalOn,
sizeClick: e.target.name });
};
//모달창과 사이즈 선택의 state 값을 업데이트 시켜주기 위한 함수.
boxClick = () => {
this.setState({
checkOn: !this.state.checkOn,
});
};
boxClickSecond = () => {
this.setState({
checkOnSecond: !this.state.checkOnSecond,
});
};
//동의를 구하는 체크박스를 위한 함수.
handleInputValue = e => {
const { name, value } = e.target;
this.setState({
[name]: value,
});
};
//아이디와 비밀번호를 입력했을 때를 위한 함수.
signUp = () => {
fetch("http://10.58.1.71:8000/account/signup", {
method: "POST",
body: JSON.stringify({
email: this.state.email,
password: this.state.pw,
}),
})
.then(res => res.json())
.then(res => {
// if (res.maessage === "INVALID_EMAIL") {
// alert("이메일 형식이 올바르지 않습니다.");
// }
// if (res.message === "REGISTERED_EAMIL") {
// alert("이미 가입된 이메일입니다.");
//}
// if (res.message === "INVALID_PASSWORD") {
// alert("비밀번호 형식이 올바르지 않습니다.");
// }
// if (res.message === "KEY_ERROR") {
// alert("이메일 또는 비밀번호가 입력되지 않았습니다.");
// }
// if (res.message === "INVALID_JSON") {
// alert("이메일과 비밀번호를 입력하여주세요.");
// }
if (res.message === "SUCCESS") {
this.props.history.push("/login");
alert("회원가입이 완료되었습니다.");
}
});
};
//handleEmail = e => {
// const { email } = this.state;
// const EMAIL = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;
// if (email === "") {
// this.setState({ emailCheck: false, multiCheckEmail: "" });
// return;
// }
// if (EMAIL.test(email)) {
// this.setState({ email: false });
// } else {
// this.setState({ email: true, multiCheckEmail: "" });
// return;
// }
// fetch("http://10.58.1.71:8000/account/email", {
// method: "POST",
// body: JSON.stringify({
// email: email,
// }),
// })
// .then(res => {
// return res.json();
// })
// .then(res => {
// if (res.message === "INVALID_EMAIL") {
// alert("이메일 형식을 지켜주세요.");
// }
// if (res.message === "REGISTERED_EAMIL") {
// alert("이미 존재하는 이메일입니다.");
// }
// });
// };
//handlePw = e => {
// const { pw } = this.state;
//fetch("http://10.58.1.71:8000/account/password", {
// method: "POST",
// body: JSON.stringify({
// password: pw,
// }),
// })
// .then(res => {
// return res.json();
// })
// .then(res => {
// if (res.message === "INVALID_PASSWORD") {
// alert("비밀번호 형식을 지켜주세요");
// }
//if (!/^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,25}$/.test(pw)) {
//alert("숫자+영문자+특수문자 조합으로 8자리 이상 사용해야 합니다.");
//}
// });
// };
sizeModal = e => {
this.setState({ sizeClick: e });
};
render() {
const btnChange = this.state.checkOn ? "checkOn" : "checkOff";
const btnChangeSecond = this.state.checkOnSecond
? "checkOnSecond"
: "checkOff";
//뭔가 하나로 줄일 수 있을 것 같긴한데..
//두번 지정해준 이유는 한 번만 지정하면 클릭할 때 두 개가 동시에 바뀌기 때문..
return (
<JoinArea>
<JoinTitle>회원가입</JoinTitle>
<ButtonInputBox>
<InputTitle>이메일 주소*</InputTitle>
<InputTxt
name="email"
type="text"
placeholder="예) [email protected]"
onChange={this.handleInputValue}
/>
{this.state.email && this.state.email.includes("@") ? null : (
<div style={{ color: "red", fontSize: "10px" }}>
이메일 형식을 지켜주세요.
</div>
)}
//"@"가 포함되면 경고문자가 사라지도록.
</ButtonInputBox>
<ButtonInputBox>
<InputTitle>비밀번호*</InputTitle>
<InputTxt
name="pw"
type="password"
placeholder="영문,숫자,특수문자 조합 8-16자"
onChange={this.handleInputValue}
/>
{this.state.pw && this.state.pw.length >= 8 ? null : (
<div style={{ color: "red", fontSize: "10px" }}>
비밀번호 형식을 지켜주세요.
</div>
)}
//8자 이상이면 경고문자가 사라지도록.
//다음엔 위의 조건 그대로 적용해보자.
</ButtonInputBox>
<ButtonInputBox>
<InputTitle>스니커즈 사이즈 (선택)</InputTitle>
<Modal
handleModal={this.handleModal}
modalOn={this.state.modalOn}
sizeClick={this.state.sizeClick}
/>
//Modal 컴퍼넌트에 sizeClick을 props로 넘겨주고 있다.
<InputTxt
type="text"
placeholder="선택하세요"
onClick={this.handleModal}
value={this.state.sizeClick}
></InputTxt>
//선택하세요 인풋창에 사이즈 클릭 값이 들어올 수 있도록
</ButtonInputBox>
<JoinWrap>
<LabelTxt>
<FiCheckSquare
className={btnChange}
size="20px"
onClick={this.boxClick}
/>
[필수] 만 14세 이상이며 모두 동의합니다.
</LabelTxt>
<LabelTxt2>
<FiCheckSquare
className={btnChangeSecond}
size="20px"
onClick={this.boxClickSecond}
/>
[선택] 광고성 정보 수신에 모두 동의합니다.
</LabelTxt2>
</JoinWrap>
<JoinBtnBox>
<JoinBtn
email={this.state.email}
pw={this.state.pw}
onClick={this.signUp}
>
회원가입
</JoinBtn>
</JoinBtnBox>
</JoinArea>
);
}
}
const JoinArea = styled.div`
width: 400px;
height: 678px;
padding: 60px 0 160px;
padding-top: 150px;
margin: 0 auto;
`;
const JoinTitle = styled.h2`
padding-bottom: 50px;
font-size: 30px;
font-weight: bold;
text-align: center;
`;
const ButtonInputBox = styled.div`
width: 400px;
height: 80px;
position: relative;
padding: 10px 0 14px;
`;
const InputTitle = styled.h3`
width: 400px;
font-size: 13px;
font-weight: bold;
letter-spacing: -0.07px;
line-height: 18px;
`;
const InputTxt = styled.input`
width: 400px;
height: 38px;
cursor: text;
margin-right: 300px;
border-bottom: 1px solid #ebebeb;
&::placeholder {
font-size: 14px;
color: lightgray;
}
&:hover {
cursor: pointer;
border-bottom: 2px solid black;
}
`;
const JoinWrap = styled.div`
padding: 24px 0 40px;
`;
const LabelTxt = styled.div`
margin-bottom: 17px;
font-size: 12px;
.checkOn {
background-color: black;
color: white;
}
`;
//checkOn 클라스에 효과를 넣었다.
//체크박스를 누를 때마다 바뀌도록.
const LabelTxt2 = styled.div`
margin-bottom: 17px;
font-size: 12px;
.checkOnSecond {
background-color: black;
color: white;
}
`;
const JoinBtnBox = styled.div`
width: 400px;
height: 140px;
`;
const JoinBtn = styled.button`
width: 400px;
height: 52px;
border-radius: 12px;
background-color: ${props =>
props.email.includes("@") && props.pw.length >= 8
? "black"
: "rgb(235, 235, 235)"};
color: white;
font-weight: bold;
`;
//별거 아니지만 하고나서 좀 뿌듯했던 것...
//스타일드 컴퍼넌트의 장점 중 하나.
//프롭스로 받아서 조건문을 작성할 수 있다.
class Modal extends React.Component {
render() {
return (
<>
{this.props.modalOn ? (
<WrapModal onClick={this.props.handleModal}>
<ModalContainer>
<LayerHeader>
<Title>사이즈 선택</Title>
</LayerHeader>
<LayerContent>
<SizeList>
<SizeItem>
{SIZE.map((size, index) => (
<ItemBtn
onClick={this.props.handleModal}
name={size.size}
//모달에서 바뀐 내용은 위 하나.
id={size.id}
key={size.id}
>
{size.size}
</ItemBtn>
))}
</SizeItem>
</SizeList>
<LayerBtn>
<Button onClick={this.props.handleModal}>확인</Button>
</LayerBtn>
</LayerContent>
</ModalContainer>
</WrapModal>
) : null}
</>
);
}
}
Author And Source
이 문제에 관하여(TIL_58_2차 프로젝트 회원가입), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@poohv7/TIL572차-프로젝트-회원가입-과-로그인저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)