diff --git a/src/pages/SignUpPage.tsx b/src/pages/SignUpPage.tsx index a64a49b..5d5380e 100644 --- a/src/pages/SignUpPage.tsx +++ b/src/pages/SignUpPage.tsx @@ -12,6 +12,7 @@ import CloseIcon from '@/assets/icons/close.svg?react'; import Calendar from '@/components/Calendar'; import ImageSlider from '@/components/ImageSlider'; import PhoneCheck from '@/components/PhoneCheck'; +import { ValidatePassword, validatePassword } from '@/utils/validation'; import { BlurBackground } from '@/styles/modals/common.style'; import * as SignupPageStyles from '@/styles/signup/SignuppageStyle'; @@ -27,18 +28,15 @@ const SignUp = () => { const [phonenumber, setPhonenumber] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); - const [passwordCheck, setPasswordCheck] = useState(''); - const [isEmail, setIsEmail] = useState(false); - const [isPassword, setIsPassword] = useState(''); const [isCertify, setIsCertify] = useState(false); const [emailMessage, setEmailMessage] = useState(''); const [avaMessage, setAvaMessage] = useState(''); - const [passwordMessage, setPasswordMessage] = useState( - '*8자 이상으로 입력 *대문자 사용 *숫자 사용 *특수문자 사용', - ); - const [passwordcheckMessage, setPasswordCheckMessage] = useState(''); - const [mismatchError, setMismatchError] = useState(false); + const [validateNewPassword, setValidateNewPassword] = + useState(null); + const [confirmPassword, setConfirmPassword] = useState(''); + const [validateConfirmPassword, setValidateConfirmPassword] = useState(true); + // const [mismatchError, setMismatchError] = useState(false); const [isEmailSuccess, setIsEmailSuccess] = useState(false); const [isOpenOverlapModal, setIsOpenOverlapModal] = useState(false); @@ -82,35 +80,24 @@ const SignUp = () => { } }; - const onChangePassword = (e: React.ChangeEvent) => { - const passwordRegex = - /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/; - const passwordCurrent = e.target.value; - setPassword(passwordCurrent); - if (!passwordRegex.test(passwordCurrent)) { - setPasswordMessage( - '*8자 이상으로 입력 *대문자 사용 *숫자 사용 *특수문자 사용', - ); - setIsPassword(false); - } else { - setPasswordMessage(''); - setIsPassword(true); - } + const handleChangeNewPassword: React.ChangeEventHandler = ({ + target: { value }, + }) => { + setPassword(value); + setValidateNewPassword(validatePassword(value)); + setValidateConfirmPassword(value === password); }; - const onChangePasswordCheck = (e: React.ChangeEvent) => { - setPasswordCheck(e.target.value); - if (!password) { - setPasswordCheckMessage('비밀번호를 재입력해주세요'); - } else if (password && e.target.value !== password) { - setMismatchError(true); - setPasswordCheckMessage( - '비밀번호가 일치하지 않습니다. 다시 확인해주세요.', - ); - } else { - setMismatchError(false); - setPasswordCheckMessage('비밀번호가 일치합니다.'); - } + const handleChangeConfirmPassword: React.ChangeEventHandler< + HTMLInputElement + > = ({ target: { value } }) => { + setConfirmPassword(value); + setValidateConfirmPassword(value === password); + }; + + const getHelpStyle = (test: undefined | boolean) => { + if (test === undefined) return ''; + return test ? 'active' : 'error'; }; const onSubmit = (e: React.FormEvent) => { @@ -133,8 +120,8 @@ const SignUp = () => { selectedSex && email && password && - passwordCheck && - !mismatchError + confirmPassword && + validateConfirmPassword ) { // 서버에 데이터 전송 onRegisterUserInfo(); @@ -151,7 +138,7 @@ const SignUp = () => { name: name, email: email, password: password, - check_password: passwordCheck, + check_password: confirmPassword, birth_date: [year, month, date].join('-'), gender: selectedSex === '미표기' ? null : selectedSex, phone_number: phonenumber, @@ -173,6 +160,16 @@ const SignUp = () => { onApply(); }; + const getConfirmPasswordStyle = () => { + if (confirmPassword === '') { + return { color: '#BBBBBB' }; + } else if (validateConfirmPassword) { + return { color: '#3681FE' }; + } else { + return { color: '#FF4A4A' }; + } + }; + return ( @@ -297,13 +294,29 @@ const SignUp = () => { id="password" name="password" value={password} - onChange={onChangePassword} + onChange={handleChangeNewPassword} > - {!isPassword && ( - - {passwordMessage} - - )} +
+ + *8자 이상으로 입력 + + + + *대문자 사용 + + + + *숫자 사용 + + + + *특수문자 사용 + +
비밀번호 재입력 @@ -311,20 +324,23 @@ const SignUp = () => { type="password" id="passwordCheck" name="passwordCheck" - value={passwordCheck} - onChange={onChangePasswordCheck} + value={confirmPassword} + onChange={handleChangeConfirmPassword} onKeyDown={handleOnKeyDown} > - {(passwordCheck || passwordCheck === '') && - (mismatchError ? ( - - {passwordcheckMessage} - +
+ {validateConfirmPassword ? ( + + {confirmPassword === '' + ? '비밀번호 확인을 위해 다시 한 번 입력해주세요' + : '비밀번호가 일치해요!'} + ) : ( - - {passwordcheckMessage} - - ))} + + 비밀번호가 일치하지 않아요 다시 입력해주세요 + + )} +
@@ -336,9 +352,8 @@ const SignUp = () => { selectedSex && isEmail && avaMessage && - isPassword && - passwordCheck && - !mismatchError ? ( + confirmPassword && + validateConfirmPassword ? ( 가입하기 diff --git a/src/styles/signin/SigninpageStyle.ts b/src/styles/signin/SigninpageStyle.ts index 8c95cb5..b87f904 100644 --- a/src/styles/signin/SigninpageStyle.ts +++ b/src/styles/signin/SigninpageStyle.ts @@ -126,8 +126,6 @@ export const ModalDiv = styled.div` } `; - - export const SocialButton = styled.button` display: flex; align-items: center; @@ -144,7 +142,7 @@ export const SocialButton = styled.button` export const NaverSection = styled(SocialButton)` margin-top: 60px; - background: #F3F3F3; + background: #f3f3f3; color: #bbbbbb; `; diff --git a/src/styles/signup/SignuppageStyle.ts b/src/styles/signup/SignuppageStyle.ts index 7177635..b44f99e 100644 --- a/src/styles/signup/SignuppageStyle.ts +++ b/src/styles/signup/SignuppageStyle.ts @@ -9,6 +9,27 @@ export const Wrapper = styled.div` width: 100%; min-height: 100vh; gap: 124px; + + & .input-help { + display: flex; + gap: 4px; + padding-left: 16px; + padding-top: 8px; + + & > span { + color: ${(props) => props.theme.color.gray300}; + transition: 0.1s; + ${(props) => props.theme.typography.Body3}; + + &.active { + color: ${(props) => props.theme.color.gray500}; + } + + &.error { + color: ${(props) => props.theme.color.red}; + } + } + } `; export const LogoSection = styled.div`