diff --git a/src/MenteeSignup.css b/src/MenteeSignup.css index f5e8ec1..eeee8af 100644 --- a/src/MenteeSignup.css +++ b/src/MenteeSignup.css @@ -140,11 +140,10 @@ color: rgba(0, 0, 0, 0.40); background-color: #fff; } -.join_btn{ +.join_btn { height: 6vh; width: 20vw; - background-color: #F0EFEF; - color: rgba(0, 0, 0, 0.40); + font-family: "Noto Sans"; font-weight: 600; border-radius: 5px; @@ -154,5 +153,16 @@ align-items: center; } +.join_btn:disabled { + background-color: #F0EFEF; + color: rgba(0, 0, 0, 0.40); +} + +.join_btn:enabled { + color: white; + background-color: #1CA764; +} + + diff --git a/src/MenteeSignup.jsx b/src/MenteeSignup.jsx index e3acbd3..76a9d29 100644 --- a/src/MenteeSignup.jsx +++ b/src/MenteeSignup.jsx @@ -14,6 +14,7 @@ import { useNavigate } from "react-router"; import '../Styles/MenteeSignup.css'; import downArrow from '../assets/downArrow.png'; import Home from './Home' +import Signin from "./Signin"; export default function MenteeSignup() { const navigate = useNavigate(); @@ -41,8 +42,9 @@ export default function MenteeSignup() { const ageOptions = ["10대", "20대", "30대", "40대 이상"].filter(age => age !== inputAge); const handleGenderChange = (value) => { - setInputGender(value === "여성" ? false : true); + setInputGender(value); setShowGenderDropdown(false); + }; const handleAgeChange = (value) => { @@ -103,6 +105,7 @@ export default function MenteeSignup() { // 모든 필드가 유효한지 확인 const isValid = Object.values(errors).every(error => error === ''); setIsFormValid(isValid); + }; useEffect(() => { @@ -124,7 +127,7 @@ export default function MenteeSignup() { "password": inputPassword, "nickname" : inputNickname, //닉네임 "isMentor" : false, - "gender" : inputGender, // 남자 -> true , 여자 -> false + "gender" : inputGender === '남자', // 남자 -> true , 여자 -> false "age" : inputAge, }), //실제 데이터 파싱하여 body에 저장 }) @@ -134,6 +137,7 @@ export default function MenteeSignup() { if (response.status === 200) { alert('회원가입에 성공하였습니다.'); + navigate('/Signin'); } else if(response.status === 400){ alert('입력값이 올바르지 않습니다.') } @@ -146,8 +150,14 @@ export default function MenteeSignup() { } catch (error) { alert('에러 발생'); } - - navigate('/'); + setInputName=''; + setInputGender = ''; + setInputAge = ''; + setInputId = ''; + setInputPassword = ''; + setInputPasswordConfirmed=''; + setInputNickName =''; + }; return ( @@ -219,7 +229,7 @@ export default function MenteeSignup() { value={inputId} onChange={(e) => setInputId(e.target.value)} /> - +
{inputErrors.idError}
@@ -265,3 +275,4 @@ export default function MenteeSignup() { ); } + diff --git a/src/MentorSignup.jsx b/src/MentorSignup.jsx index cdb907d..a13b807 100644 --- a/src/MentorSignup.jsx +++ b/src/MentorSignup.jsx @@ -130,7 +130,7 @@ export default function MentorSignup() { "nickname" : inputNickname, //닉네임 "employmentPath": inputCertificate, "isMentor" : false, - "gender" : inputGender, // 남자 -> true , 여자 -> false + "gender" : inputGender ==='남자', // 남자 -> true , 여자 -> false "age" : inputAge, }), }) @@ -154,6 +154,14 @@ export default function MentorSignup() { } navigate('/Signin'); + setInputName=''; + setInputGender = ''; + setInputAge = ''; + setInputId = ''; + setInputPassword = ''; + setInputPasswordConfirmed=''; + setInputNickName =''; + setInputCertificate = ''; }; return ( @@ -285,3 +293,4 @@ export default function MentorSignup() { ); } + diff --git a/src/Signin.jsx b/src/Signin.jsx new file mode 100644 index 0000000..9fc0178 --- /dev/null +++ b/src/Signin.jsx @@ -0,0 +1,295 @@ +import React, { useState, useEffect } from "react"; +import { useRecoilState } from "recoil"; +import { + inputGenderState, + inputAgeState, + inputNameState, + inputPasswordState, + inputPasswordConfirmedState, + inputNickNameState, + inputIdState, + inputCertificateState +} from "../recoil"; +import Header from "./Header"; +import { useNavigate } from "react-router"; +import '../Styles/MenteeSignup.css'; +import downArrow from '../assets/downArrow.png'; +import Signin from "./Signin"; + +export default function MentorSignup() { + const navigate = useNavigate(); + const [inputGender, setInputGender] = useRecoilState(inputGenderState); + const [inputAge, setInputAge] = useRecoilState(inputAgeState); + const [inputName, setInputName] = useRecoilState(inputNameState); + const [inputPassword, setInputPassword] = useRecoilState(inputPasswordState); + const [inputId, setInputId] = useRecoilState(inputIdState); + const [inputPasswordConfirmed, setInputPasswordConfirmed] = useRecoilState(inputPasswordConfirmedState); + const [inputNickname, setInputNickName] = useRecoilState(inputNickNameState); + const [inputCertificate, setInputCertificate] = useRecoilState(inputCertificateState) + const [showGenderDropdown, setShowGenderDropdown] = useState(false); + const [showAgeDropdown, setShowAgeDropdown] = useState(false); + + const [isFormValid, setIsFormValid] = useState(false); + const [inputErrors, setInputErrors] = useState({ + nameError: '', + idError: '', + passwordError: '', + passwordConfirmedError: '', + nicknameError: '' + }); + + const genderOptions = ["남성", "여성"].filter(gender => gender !== inputGender); + const ageOptions = ["10대", "20대", "30대", "40대 이상"].filter(age => age !== inputAge); + + const handleGenderChange = (value) => { + setInputGender(value); + setShowGenderDropdown(false); + }; + + const handleAgeChange = (value) => { + setInputGender(value === "여성" ? false : true); + setShowAgeDropdown(false); + }; + + const validatePassword = (password) => { + const passwordRegExp = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,25}$/; + return passwordRegExp.test(password); + }; + + const validateId = (id) => { + const idRegExp = /^[a-zA-Z0-9]{6,12}$/; + return idRegExp.test(id); + }; + + const validateNickname = (nickname) => { + const nicknameRegExp = /^[a-zA-Z0-9]{6,12}$/; + return nicknameRegExp.test(nickname); + }; + + const checkFormValidity = () => { + const errors = { + nameError: '', + idError: '', + passwordError: '', + passwordConfirmedError: '', + nicknameError: '', + certificateError: '' + }; + + if (!inputName) { + errors.nameError = '이름을 입력하세요.'; + } + if (!inputId) { + errors.idError = '아이디를 입력하세요.'; + } else if (!validateId(inputId)) { + errors.idError = '아이디는 6~12자 이내의 영문 또는 숫자만 사용 가능합니다.'; + } + if (!inputPassword) { + errors.passwordError = '비밀번호를 입력하세요.'; + } else if (!validatePassword(inputPassword)) { + errors.passwordError = '비밀번호는 8자 이상의 문자, 숫자, 특수기호 조합이어야 합니다.'; + } + if (!inputPasswordConfirmed) { + errors.passwordConfirmedError = '비밀번호를 확인하세요.'; + } else if (inputPasswordConfirmed !== inputPassword) { + errors.passwordConfirmedError = '비밀번호가 일치하지 않습니다.'; + } + if (!inputNickname) { + errors.nicknameError = '닉네임을 입력하세요.'; + } else if (!validateNickname(inputNickname)) { + errors.nicknameError = '닉네임은 6~12자 이내의 영문 또는 숫자만 사용 가능합니다.'; + } + if(!inputCertificate){ + errors.certificateError = "재직자 인증 확인 후 가입이 완료됩니다."; + } + + setInputErrors(errors); + + // 모든 필드가 유효한지 확인 + const isValid = Object.values(errors).every(error => error === ''); + setIsFormValid(isValid); + }; + + useEffect(() => { + checkFormValidity(); + }, [inputName, inputGender, inputAge, inputId, inputPassword, inputPasswordConfirmed, inputNickname, inputCertificate]); + + + const handleSignUp = async () => { + try { + const response = await fetch("http://52.78.165.203:8080/api/user/register/mentor", { + method : "POST", + headers : { + "Content-Type":"application/json; charset=utf-8" + }, + + body: JSON.stringify({ + "name": inputName, //이름 + "userName": inputId, //로그인할 때 쓰는 아이디 + "password": inputPassword, + "nickname" : inputNickname, //닉네임 + "employmentPath": inputCertificate, + "isMentor" : false, + "gender" : inputGender ==='남자', // 남자 -> true , 여자 -> false + "age" : inputAge, + }), + }) + + const data = await response.json(); + console.log(data); + + if (response.status === 200) { + alert('회원가입에 성공하였습니다.'); + } else if(response.status === 400){ + alert('입력값이 올바르지 않습니다.') + } + else if(response.status === 409){ + alert('이미 존재하는 회원입니다.') + } + else { + alert('회원가입 실패'); + } + } catch (error) { + alert('에러 발생'); + } + + navigate('/Signin'); + setInputName=''; + setInputGender = ''; + setInputAge = ''; + setInputId = ''; + setInputPassword = ''; + setInputPasswordConfirmed=''; + setInputNickName =''; + setInputCertificate = ''; + }; + + return ( + <> +
+
+
+
+ 이름 + setInputName(e.target.value)} + /> +
{inputErrors.nameError}
+
+
+
+
+
setShowGenderDropdown(!showGenderDropdown)} + > + {inputGender || "성별"} + {!inputGender && down arrow} +
+ {showGenderDropdown && ( +
+ {genderOptions.map(gender => ( +
handleGenderChange(gender)}> + {gender} +
+ ))} +
+ )} +
+
+
+
+
setShowAgeDropdown(!showAgeDropdown)} + > + {inputAge || "연령대"} + {!inputAge && down arrow} +
+ {showAgeDropdown && ( +
+ {ageOptions.map(age => ( +
handleAgeChange(age)}> + {age} +
+ ))} +
+ )} +
+
+
*(필수)
+
+
+ 아이디 +
+ setInputId(e.target.value)} + /> + +
+
{inputErrors.idError}
+ +
+
+ 비밀번호 + setInputPassword(e.target.value)} + /> +
{inputErrors.passwordError}
+
+
+ setInputPasswordConfirmed(e.target.value)} + /> +
{inputErrors.passwordConfirmedError}
+
+
+ 닉네임 +
+ setInputNickName(e.target.value)} + /> + +
+
+
{inputErrors.nicknameError}
+
+
+ 증명서 +
+ setInputCertificate(e.target.value)} + /> + +
+
{inputErrors.certificateError}
+
+ +
+ + ); +}