From e1d633c51af5c2161b8f16cb97f77cc5a7751024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?junh=5Feee=28=EC=9D=B4=EC=A4=80=ED=9D=AC=29?= Date: Tue, 27 Feb 2024 18:58:26 +0900 Subject: [PATCH] =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?=ED=8F=BC=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/register/AccountRegister.js | 4 +- .../account/register/AccountRegisterForm.js | 245 +++--------------- .../account/mypage/ParentsContainer.js | 64 ----- .../register/AccountRegisterFormContainer.js | 219 ++++++++++++++++ .../account/register/registerThunk.ts | 6 +- 5 files changed, 251 insertions(+), 287 deletions(-) delete mode 100644 src/containers/account/mypage/ParentsContainer.js create mode 100644 src/containers/account/register/AccountRegisterFormContainer.js diff --git a/src/components/account/register/AccountRegister.js b/src/components/account/register/AccountRegister.js index 8f7aca73..8acedb1b 100644 --- a/src/components/account/register/AccountRegister.js +++ b/src/components/account/register/AccountRegister.js @@ -4,6 +4,7 @@ import { useRef, useState } from 'react'; import Wizard from '@core@components/wizard'; import '@styles/base/pages/page-auth.scss'; import { AccountRegisterComplete } from './AccountRegisterComplete'; +import { AccountRegisterFormContainer } from '@src/containers/account/register/AccountRegisterFormContainer'; export const AccountRegister = ({ props }) => { // step @@ -37,11 +38,10 @@ export const AccountRegister = ({ props }) => { title: '가입정보 입력', subtitle: 'STEP02', content: ( - ) diff --git a/src/components/account/register/AccountRegisterForm.js b/src/components/account/register/AccountRegisterForm.js index 278be8cf..8fb1caab 100644 --- a/src/components/account/register/AccountRegisterForm.js +++ b/src/components/account/register/AccountRegisterForm.js @@ -1,10 +1,6 @@ -import { useDispatch, useSelector } from '@src/redux/store'; -import * as yup from 'yup'; +import { useSelector } from '@src/redux/store'; import { Fragment, useEffect, useRef, useState } from 'react'; import classnames from 'classnames'; -import { isObjEmpty } from '@utils'; -import { useForm } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; import { Form, Label, @@ -20,207 +16,24 @@ import { confirmCrtfyhp, sendCrtfyhp } from '@src/redux/features/account/register/registerThunk'; -import { openModal } from '@src/redux/features/comn/message/messageSlice'; -import { MODAL_CRTFYHP, MODAL_BODY, MODAL_HEADER } from '@src/configs/msgConst'; -import { createRegister } from '@src/redux/features/account/register/registerThunk'; -import { - isSendCrtfyhp, - isConfirmCrtfyhp -} from '@src/redux/features/comn/crtfyhp/crtfyhpSlice'; + import { CrtfyhpUtil } from '@src/utility/crtfyhpUtil'; export const AccountRegisterForm = ({ - stepper, - type, - movePage, - testName, - setMemberName + errors, + register, + getValues, + onSubmit, + handleSubmit, + handlerCancel, + handlerChange, + handlerSmsConfirm }) => { - const dispatch = useDispatch(); - - // 약관동의 내용 - const { agreeTerms } = useSelector(state => state.registerState); - const hookRef = useRef(); const { isRunning, isCrtfyhp, counter } = useSelector( state => state.crtfyhpState ); - // 단순 메시지 표출 모달 - const handlerOpenModal = (header, body) => { - dispatch( - openModal({ - header: header, - body: body - }) - ); - }; - - // 회원가입 폼 유효성 검사 - const SignupSchema = yup.object().shape({ - userId: yup.string().trim().required('ID를 입력해 주세요.'), - // .matches( - // /^[a-z]+[a-z0-9]{5,19}$/g, - // '4자 이상, 20자 미만 영문자 또는 숫자로 입력해 주세요.' - // ), - userPswd: yup.string().required('비밀번호를 입력해 주세요.'), - // genderCd: yup.string().required('성별을 선택해 주세요.'), - brthdyDate: yup - .string() - .required('생년월일을 입력해 주세요.') - .matches( - /^(19[0-9][0-9]|20\d{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$/, - '올바른 생년월일을 입력해 주세요.' - ), - memberName: yup - .string() - .required('이름을 입력해 주세요.') - .min(3, '최소 2 자 이상 입력 부탁드립니다.') - .max(20, '최대 10 자 이하 입력 부탁드립니다.'), - email: yup.string().required('이메일을 입력해 주세요.'), - hpno: yup - .string() - .required('휴대폰번호를 입력해 주세요.') - .matches( - /^(01[0-1])([1-9][0-9]{3})([0-9]{4})$/, - '올바른 휴대폰번호를 입력해 주세요.' - ), - // cntryCd: yup.string().required('국가를 선택해 주세요.'), - clncd: yup.string().required('국가번호를 선택해 주세요.'), - userPswd: yup - .string() - .required('비밀번호를 입력해 주세요.') - .matches( - /^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[@$!%*#?&])[A-Za-z0-9@$!%*#?&]{8,20}$/, - '8 자 이상, 20 자 미만 영문자/숫자/특수문자(@$!%*#?&) 조합하여 입력해 주세요.' - ), - confirmUserPaswd: yup - .string() - .required('비밀번호 확인을 입력해 주세요.') - .oneOf([yup.ref('userPswd'), null], '비밀번호가 일치하지 않습니다.') - }); - - const { register, getValues, setValue, errors, handleSubmit } = useForm({ - defaultValues: { - userId: '', - userPswd: '', - confirmUserPaswd: '', - cntryCd: 'KOR', - genderCd: '', - memberName: '', - brthdyDate: '', - email: '', - hpno: '', - clncd: '+82', - crtfyNo: '', - company: '팔네트웍스', - trmnlId: 'SANDBOX-001' - }, - resolver: yupResolver(SignupSchema) - }); - - // 취소 헨들러 - const handlerCancel = async () => { - movePage('/account/login'); - }; - - // 회원가입 버튼 헨들러 - const onSubmit = async rq => { - if (isObjEmpty(errors)) { - if (!isCrtfy) { - handlerOpenModal('회원가입 실패', '휴대폰 인증을 진행해주세요.'); - return false; - } - - const data = await dispatch(createRegister({ ...rq, terms: agreeTerms })); - - if (data?.payload.errCode === -1) { - handlerOpenModal( - '회원가입 실패', - '동일한 아이디가 존재합니다. 다른 아이디로 가입 신청해주세요.' - ); - return; - } - - if (data?.payload.errCode === 1) { - stepper.next(); - } else { - handlerOpenModal('회원가입 실패', '회원 가입에 실패하였습니다.'); - return; - } - } - }; - - // 인증번호 인증 헨들러 - const handlerSmsConfirm = async () => { - const vData = getValues(); - - if (!vData.clncd || !vData.hpno) { - handlerOpenModal( - MODAL_HEADER.crtfyhp, - '휴대폰 번호를' + MODAL_BODY.valid - ); - - return false; - } - if (!vData.crtfyNo) { - handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.valid); - return false; - } - - const { payload: data } = await dispatch( - confirmCrtfyhp({ hpno: vData.hpno, crtfyNo: vData.crtfyNo }) - ); - if (!data.result) { - handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.failed); - dispatch(isConfirmCrtfyhp(false)); - return; - } else { - handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.confirm); - dispatch(isSendCrtfyhp(false)); - dispatch(isConfirmCrtfyhp(true)); - return; - } - }; - - let hpno = ''; - let brthdyDate = ''; - let trmnlId = ''; - - // 회원가입 폼 변경 헨들러 - const onChangeHandler = e => { - const { name, value } = e.target; - - if (name === 'company') { - trmnlId = value; - setValue('trmnlId', trmnlId); - } - - if (name === 'memberName') { - setMemberName(value); - } - - if (name === 'brthdyDate') { - const regex = /^[0-9\b]{0,8}$/; - - if (regex.test(value)) { - brthdyDate = value; - // setValue(name, value); - } else { - setValue(name, brthdyDate); - } - } else if (name === 'hpno') { - const regex = /^[0-9\b]{0,11}$/; - - if (regex.test(value)) { - hpno = value; - // setValue(name, value); - } else { - setValue(name, hpno); - } - } - }; - return (
@@ -239,7 +52,7 @@ export const AccountRegisterForm = ({ name='memberName' id='memberName' // value={registerInfo.memberName} - onChange={onChangeHandler} + onChange={handlerChange} placeholder='홍길동' ref={register} // ref={register({ required: true })} @@ -261,7 +74,7 @@ export const AccountRegisterForm = ({ name='brthdyDate' id='brthdyDate' // value={registerInfo.brthdyDate} - onChange={onChangeHandler} + onChange={handlerChange} placeholder='19950915' ref={register} // ref={register({ required: true })} @@ -284,7 +97,7 @@ export const AccountRegisterForm = ({ name='genderCd' id='genderCd' // value={registerInfo.genderCd} - onChange={onChangeHandler} + onChange={handlerChange} ref={register} // ref={register({ required: true })} className={classnames({ @@ -310,7 +123,7 @@ export const AccountRegisterForm = ({ name='cntryCd' id='cntryCd' // value={registerInfo.cntryCd} - onChange={onChangeHandler} + onChange={handlerChange} ref={register} // ref={register({ required: true })} className={classnames({ @@ -337,7 +150,7 @@ export const AccountRegisterForm = ({ id='clncd' readOnly={isCrtfyhp} // value={registerInfo.clncd} - onChange={onChangeHandler} + onChange={handlerChange} ref={register} // ref={register({ required: true })} className={classnames({ @@ -358,7 +171,7 @@ export const AccountRegisterForm = ({ id='hpno' readOnly={isCrtfyhp} // value={registerInfo.hpno} - onChange={onChangeHandler} + onChange={handlerChange} placeholder='01000000000' ref={register} // ref={register({ required: true })} @@ -391,12 +204,6 @@ export const AccountRegisterForm = ({ ) : null} -
); }; diff --git a/src/containers/account/mypage/ParentsContainer.js b/src/containers/account/mypage/ParentsContainer.js deleted file mode 100644 index 03ae7c18..00000000 --- a/src/containers/account/mypage/ParentsContainer.js +++ /dev/null @@ -1,64 +0,0 @@ -import { sendCrtfyhp } from '@src/redux/features/account/register/registerThunk'; -import { useSelector } from '@src/redux/store'; -import { Button, Label, Row, Col, Input } from '@src/components/ui'; -import { useRef, useState } from 'react'; -import { CrtfyhpUtil } from '@src/utility/crtfyhpUtil'; - -export const ParentsContainer = () => { - const hookRef = useRef(); - const { isRunning, isCrtfyhp, counter } = useSelector( - state => state.crtfyhpState - ); - - const [hpno, setHpno] = useState(''); - - const handlerChange = e => { - const { name, value } = e.target; - - if (name == 'hpno') { - const regex = /^[0-9]{0,11}$/; - if (regex.test(value)) { - setHpno(value); - } - } - }; - - return ( - <> - - - - - - - - 남은시간 {counter.min}:{counter.sec} - - - - - - - ); -}; diff --git a/src/containers/account/register/AccountRegisterFormContainer.js b/src/containers/account/register/AccountRegisterFormContainer.js new file mode 100644 index 00000000..5e7a1e45 --- /dev/null +++ b/src/containers/account/register/AccountRegisterFormContainer.js @@ -0,0 +1,219 @@ +import * as yup from 'yup'; +import { isObjEmpty } from '@utils'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { + confirmCrtfyhp, + sendCrtfyhp +} from '@src/redux/features/account/register/registerThunk'; +import { openModal } from '@src/redux/features/comn/message/messageSlice'; +import { MODAL_CRTFYHP, MODAL_BODY, MODAL_HEADER } from '@src/configs/msgConst'; +import { createRegister } from '@src/redux/features/account/register/registerThunk'; +import { + isSendCrtfyhp, + isConfirmCrtfyhp +} from '@src/redux/features/comn/crtfyhp/crtfyhpSlice'; +import { useRef } from 'react'; +import { useDispatch, useSelector } from '@src/redux/store'; +import { AccountRegisterForm } from '@src/components/account/register/AccountRegisterForm'; + +export const AccountRegisterFormContainer = ({ + stepper, + type, + movePage, + setMemberName +}) => { + const dispatch = useDispatch(); + + const { isCrtfyhp } = useSelector(state => state.crtfyhpState); + + // 약관동의 내용 + const { agreeTerms } = useSelector(state => state.registerState); + + // 단순 메시지 표출 모달 + const handlerOpenModal = (header, body) => { + dispatch( + openModal({ + header: header, + body: body + }) + ); + }; + + // 회원가입 폼 유효성 검사 + const SignupSchema = yup.object().shape({ + userId: yup.string().trim().required('ID를 입력해 주세요.'), + // .matches( + // /^[a-z]+[a-z0-9]{5,19}$/g, + // '4자 이상, 20자 미만 영문자 또는 숫자로 입력해 주세요.' + // ), + userPswd: yup.string().required('비밀번호를 입력해 주세요.'), + brthdyDate: yup + .string() + .required('생년월일을 입력해 주세요.') + .matches( + /^(19[0-9][0-9]|20\d{2})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$/, + '올바른 생년월일을 입력해 주세요.' + ), + memberName: yup + .string() + .required('이름을 입력해 주세요.') + .min(3, '최소 2 자 이상 입력 부탁드립니다.') + .max(20, '최대 10 자 이하 입력 부탁드립니다.'), + email: yup.string().required('이메일을 입력해 주세요.'), + hpno: yup + .string() + .required('휴대폰번호를 입력해 주세요.') + .matches( + /^(01[0-1])([1-9][0-9]{3})([0-9]{4})$/, + '올바른 휴대폰번호를 입력해 주세요.' + ), + // cntryCd: yup.string().required('국가를 선택해 주세요.'), + clncd: yup.string().required('국가번호를 선택해 주세요.'), + userPswd: yup + .string() + .required('비밀번호를 입력해 주세요.') + .matches( + /^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[@$!%*#?&])[A-Za-z0-9@$!%*#?&]{8,20}$/, + '8 자 이상, 20 자 미만 영문자/숫자/특수문자(@$!%*#?&) 조합하여 입력해 주세요.' + ), + confirmUserPaswd: yup + .string() + .required('비밀번호 확인을 입력해 주세요.') + .oneOf([yup.ref('userPswd'), null], '비밀번호가 일치하지 않습니다.') + }); + + const { register, getValues, setValue, errors, handleSubmit } = useForm({ + defaultValues: { + userId: '', + userPswd: '', + confirmUserPaswd: '', + cntryCd: 'KOR', + genderCd: '', + memberName: '', + brthdyDate: '', + email: '', + hpno: '', + clncd: '+82', + crtfyNo: '', + company: '팔네트웍스', + trmnlId: 'SANDBOX-001' + }, + resolver: yupResolver(SignupSchema) + }); + + // 취소 헨들러 + const handlerCancel = async () => { + movePage('/account/login'); + }; + + // 회원가입 버튼 헨들러 + const onSubmit = async rq => { + if (isObjEmpty(errors)) { + if (!isCrtfyhp) { + handlerOpenModal('회원가입 실패', '휴대폰 인증을 진행해주세요.'); + return false; + } + + const { payload: data } = await dispatch( + createRegister({ ...rq, terms: agreeTerms }) + ); + + if (data?.errCode === -1) { + handlerOpenModal( + '회원가입 실패', + '동일한 아이디가 존재합니다. 다른 아이디로 가입 신청해주세요.' + ); + return; + } else if (data?.errCode === 1) { + stepper.next(); + } else { + handlerOpenModal('회원가입 실패', '회원 가입에 실패하였습니다.'); + return; + } + } + }; + + // 인증번호 인증 헨들러 + const handlerSmsConfirm = async () => { + const vData = getValues(); + + if (!vData.clncd || !vData.hpno) { + handlerOpenModal( + MODAL_HEADER.crtfyhp, + '휴대폰 번호를' + MODAL_BODY.valid + ); + + return false; + } + if (!vData.crtfyNo) { + handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.valid); + return false; + } + + const { payload: data } = await dispatch( + confirmCrtfyhp({ hpno: vData.hpno, crtfyNo: vData.crtfyNo }) + ); + if (!data.result) { + handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.failed); + dispatch(isConfirmCrtfyhp(false)); + return; + } else { + handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.confirm); + dispatch(isSendCrtfyhp(false)); + dispatch(isConfirmCrtfyhp(true)); + return; + } + }; + + let hpno = ''; + let brthdyDate = ''; + let trmnlId = ''; + + // 회원가입 폼 변경 헨들러 + const handlerChange = e => { + const { name, value } = e.target; + + if (name === 'company') { + trmnlId = value; + setValue('trmnlId', trmnlId); + } + + if (name === 'memberName') { + setMemberName(value); + } + + if (name === 'brthdyDate') { + const regex = /^[0-9\b]{0,8}$/; + + if (regex.test(value)) { + brthdyDate = value; + // setValue(name, value); + } else { + setValue(name, brthdyDate); + } + } else if (name === 'hpno') { + const regex = /^[0-9\b]{0,11}$/; + + if (regex.test(value)) { + hpno = value; + // setValue(name, value); + } else { + setValue(name, hpno); + } + } + }; + + return ( + + ); +}; diff --git a/src/redux/features/account/register/registerThunk.ts b/src/redux/features/account/register/registerThunk.ts index cf8248b5..cd8acccb 100644 --- a/src/redux/features/account/register/registerThunk.ts +++ b/src/redux/features/account/register/registerThunk.ts @@ -27,11 +27,7 @@ export const createRegister = createAsyncThunk( }; } = await axios.post('api/acnt/cstmr/register', param); - if (data.errCode > 0) { - return data; - } else { - throw new Error(); - } + return data; } catch (error) { thunkAPI.dispatch( openModal({