sanguu
2 years ago
14 changed files with 1039 additions and 178 deletions
@ -1,108 +1,458 @@
|
||||
import * as yup from 'yup'; |
||||
import classnames from 'classnames'; |
||||
import { useState, useEffect } from 'react' |
||||
import { useParams, Link } from 'react-router-dom' |
||||
import { useSelector, useDispatch } from 'react-redux' |
||||
import { useForm } from 'react-hook-form'; |
||||
import { yupResolver } from '@hookform/resolvers/yup'; |
||||
|
||||
import { Form, InputGroup, InputGroupAddon, InputGroupText, Card, CardBody, Row, Col, Nav, NavItem, NavLink, TabContent, TabPane, Alert, FormGroup, Input, Label, Button, |
||||
Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap' |
||||
Modal, ModalHeader, ModalBody, ModalFooter, FormFeedback } from 'reactstrap' |
||||
import { User, Info, CreditCard, Lock, Check, X } from 'react-feather' |
||||
|
||||
import loginImg from '../../../assets/images/login01.png'; |
||||
import '../../../assets/css/custom.css'; |
||||
import { findAPI } from '../../../modules/account/find/apis/findApi' |
||||
import { accountApi } from '../../../modules/account/register/apis/accountApi' |
||||
import { updatePwAction } from '../../../modules/account/find/actions/findAction'; |
||||
|
||||
export const AccountFindPassword = props => { |
||||
const [activeTab, setActiveTab] = useState('1') |
||||
// const validationSchema = yup.object().shape({
|
||||
// newPw: yup
|
||||
// .string()
|
||||
// .required('비밀번호를 입력주세요.')
|
||||
// .matches(
|
||||
// /^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[@$!%*#?&])[A-Za-z0-9@$!%*#?&]{8,20}$/,
|
||||
// '8자 이상, 20자 미만 영문자/숫자/특수문자(@$!%*#?&) 조합하여 입력해주세요.'
|
||||
// ),
|
||||
// newPwCk: yup
|
||||
// .string()
|
||||
// .required('비밀번호 확인을 입력해 주세요.')
|
||||
// .oneOf([yup.ref('userPswd'), null], '비밀번호가 일치하지 않습니다.')
|
||||
// })
|
||||
|
||||
// const { register, getValues, setValue, errors, handleSubmit } = useForm({
|
||||
// defaultValues: {
|
||||
// newPw: '',
|
||||
// newPwCk: '',
|
||||
// },
|
||||
// resolver: yupResolver(validationSchema)
|
||||
// })
|
||||
|
||||
const dispatch = useDispatch(); |
||||
const [activeTab, setActiveTab] = useState('2') |
||||
|
||||
// ** Function to toggle tabs
|
||||
const toggle = tab => setActiveTab(tab) |
||||
const [modal, setModal] = useState(false) |
||||
//modal
|
||||
const [confirmModal, setConfirmModal] = useState(false) |
||||
const [modal, setModal] = useState({ |
||||
isOpen: false, |
||||
title: '', |
||||
desc: '', |
||||
color: '' |
||||
}) |
||||
|
||||
//state값
|
||||
const { idResult, userId, pwResult, udResult } = useSelector(state => state.findState); |
||||
|
||||
//param으로 넘기기 위한 값
|
||||
const [inputId, setInputId] = useState(''); |
||||
const [inputHpno, setInputHpno] = useState(''); |
||||
const [inputCrtfy, setInputCrtfy] = useState(''); |
||||
const [inputNewPw, setInputNewPw] = useState(''); |
||||
const [inputNewPwCk, setInputNewPwCk] = useState(''); |
||||
|
||||
//3분 시간 및 인증
|
||||
const [minutes_Counter, setMinutes_Counter] = useState('03'); |
||||
const [seconds_Counter, setSeconds_Counter] = useState('00'); |
||||
const [timer, setTimer] = useState(null); |
||||
const [isRunning, setIsRunning] = useState(false); |
||||
const [sendCount, setSendCount] = useState(0); |
||||
const [isCrtfy, setIsCrtfy] = useState(false); |
||||
|
||||
useEffect(() => { |
||||
if(isRunning) clearInterval(timer); |
||||
return () => { clearInterval(timer); } |
||||
}, []); |
||||
|
||||
const handlerSend = async() => { |
||||
if(!inputId || !inputHpno) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '빈칸을 채워주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
if(sendCount >= 3) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '인증번호가 발송은 3회 까지만 가능합니다.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
const res = await findAPI.sendForPw({userId: inputId, hpno: inputHpno}); |
||||
if(res?.data.code === -1) { |
||||
|
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '가입되지 않은 회원 정보입니다. 다시 확인해 주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
} else if(res?.data.code === 0) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '인증번호가 발송되었습니다.', |
||||
color: 'modal-primary' |
||||
}) |
||||
timeStart(); |
||||
} |
||||
} |
||||
|
||||
const timeStart = () => { |
||||
if(isRunning) { |
||||
clearInterval(timer); |
||||
} |
||||
|
||||
setIsRunning(true); |
||||
setIsCrtfy(false); |
||||
|
||||
setSendCount(sendCount + 1); |
||||
timerStart(180); |
||||
} |
||||
|
||||
const timerStart = count => { |
||||
let minutes, seconds; |
||||
|
||||
const timer = setInterval(() => { |
||||
setIsRunning(true); |
||||
minutes = parseInt(count / 60, 10); |
||||
seconds = parseInt(count % 60, 10); |
||||
minutes = minutes < 10 ? '0' + minutes : minutes; |
||||
seconds = seconds < 10 ? '0' + seconds : seconds; |
||||
setMinutes_Counter(minutes); |
||||
setSeconds_Counter(seconds); |
||||
|
||||
//타이머 끝
|
||||
if (--count < 0) { |
||||
clearInterval(timer); |
||||
setIsRunning(false); |
||||
// setValue('crtfyNo', '');
|
||||
// setCrtfyNo('');
|
||||
} |
||||
}, 1000); |
||||
|
||||
setTimer(timer); |
||||
|
||||
return () => { |
||||
clearInterval(timer); |
||||
} |
||||
} |
||||
|
||||
const handlerConfirm = async() => { |
||||
if(!inputId || !inputHpno) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '빈칸을 채워주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
if(!inputCrtfy) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '인증번호를 입력해 주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
const res = await accountApi.crtfyhpConfirm(inputHpno, inputCrtfy); |
||||
if(!res.data.result) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '인증번호가 잘못 되었습니다.', |
||||
color: 'modal-danger' |
||||
}); |
||||
return; |
||||
} else { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '인증되었습니다.', |
||||
color: 'modal-primary' |
||||
}); |
||||
setIsCrtfy(true); |
||||
setIsRunning(false); |
||||
} |
||||
} |
||||
|
||||
const handlerUpdatePw = async() => { |
||||
if(inputNewPw !== inputNewPwCk) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '비밀번호 변경', |
||||
desc: '비밀번호가 일치하지 않습니다.', |
||||
color: 'modal-danger' |
||||
}); |
||||
return; |
||||
} |
||||
|
||||
if(!inputNewPw || !inputNewPwCk) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '비밀번호 변경', |
||||
desc: '빈칸을 채워주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
if((inputNewPw === inputNewPwCk) && inputNewPw && inputNewPwCk) { |
||||
dispatch(updatePwAction.request({userId: inputId, hpno: inputHpno, newPw: inputNewPw})); |
||||
|
||||
setModal({ |
||||
isOpen: true, |
||||
title: '비밀번호 변경', |
||||
desc: '변경이 완료되었습니다. 다시 로그인 해주세요.', |
||||
color: 'modal-primary' |
||||
}) |
||||
return; |
||||
} |
||||
} |
||||
|
||||
const handlerChange = (e) => { |
||||
const {name, value} = e.target; |
||||
|
||||
if(name == 'userId') { |
||||
setInputId(value); |
||||
} else if(name == 'hpno') { |
||||
setInputHpno(value); |
||||
} else if(name == 'crtfyhpNo') { |
||||
setInputCrtfy(value); |
||||
} else if(name == 'newPw') { |
||||
setInputNewPw(value); |
||||
} else if(name == 'newPwCk') { |
||||
setInputNewPwCk(value); |
||||
} |
||||
} |
||||
|
||||
const handlerClose = () => { |
||||
setModal({ ...modal, isOpen: !modal.isOpen }); |
||||
setConfirmModal({ ...confirmModal, isOpen: !confirmModal.isOpen}); |
||||
props.handlerClose(); |
||||
} |
||||
|
||||
return( |
||||
<> |
||||
<TabPane tabId='2'> |
||||
<Form> |
||||
<FormGroup className='form-label-group position-relative has-icon-left'> |
||||
<InputGroup className=''> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<User size={14} /> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input placeholder='아이디' /> |
||||
</InputGroup> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn'> |
||||
<Col md='3' xs='12'> |
||||
<Input type='select' placeholder='+(국가번호)'> |
||||
<option>+82</option> |
||||
<option>21111</option> |
||||
</Input> |
||||
</Col> |
||||
<Col md='6' xs='12'> |
||||
<Input type='number' placeholder='휴대폰번호'/> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button color='primary' type='button'>인증번호 발송</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn time-span'> |
||||
<Col md='9' xs='12' className='timeInput'> |
||||
<Input type='number' placeholder='인증번호 입력'/> |
||||
<span className='time'>남은시간 : 3:00</span> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button color='primary' type='button'>인증번호 확인</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='full-btn-2n vertically-centered-modal'> |
||||
<FormGroup className='form-label-group position-relative has-icon-left'> |
||||
<InputGroup className=''> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<User size={14} /> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type='text' |
||||
id='userId' |
||||
name='userId' |
||||
placeholder='아이디'
|
||||
value={inputId} |
||||
onChange={handlerChange}
|
||||
/> |
||||
</InputGroup> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn'> |
||||
<Col md='3' xs='12'> |
||||
<Input type='select' placeholder='+(국가번호)'> |
||||
<option>+82</option> |
||||
</Input> |
||||
</Col> |
||||
<Col md='6' xs='12'> |
||||
<Input |
||||
type='number' |
||||
id='hpno' |
||||
name='hpno' |
||||
placeholder='01012345678' |
||||
value={inputHpno} |
||||
onChange={handlerChange} |
||||
/> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button |
||||
color='primary' |
||||
type='button' |
||||
onClick={handlerSend} |
||||
>인증번호 발송</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn time-span'> |
||||
<Col md='9' xs='12' className='timeInput'> |
||||
<Input |
||||
type='number' |
||||
id='crtfyhpNo' |
||||
name='crtfyhpNo' |
||||
placeholder='인증번호 입력' |
||||
onChange={handlerChange} |
||||
{...sendCount > 0 ?
|
||||
{} |
||||
: |
||||
{disabled: true} |
||||
} |
||||
/> |
||||
{/* <span className='time'>남은시간 : 3:00</span> */} |
||||
<span className={!isRunning || isCrtfy ? 'time d-none' : 'time'}> |
||||
남은시간 {minutes_Counter}:{seconds_Counter} |
||||
</span> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button |
||||
color='secondary' |
||||
color='primary' |
||||
type='button' |
||||
onClick={props.handlerClose} |
||||
> |
||||
취소 |
||||
</Button> |
||||
<Button color='primary' type='button' onClick={() => setModal(!modal)} >확인</Button> |
||||
<Modal isOpen={modal} toggle={() => setModal(!modal)} className='modal-dialog-centered user-search-modal'> |
||||
<ModalHeader toggle={() => setModal(!modal)}>비밀번호 확인</ModalHeader> |
||||
<ModalBody> |
||||
<span class="etc-txt">새로운 비밀번호로 변경해주세요.</span> |
||||
<FormGroup className='form-label-group position-relative has-icon-left'> |
||||
<InputGroup> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<Lock size={14} /> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input placeholder='새로운 비밀번호' type='password'/> |
||||
</InputGroup> |
||||
</FormGroup> |
||||
<FormGroup className='form-label-group position-relative has-icon-left mb-0'> |
||||
<InputGroup> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<Lock size={14} /> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input placeholder='새로운 비밀번호 확인' type='password'/> |
||||
</InputGroup> |
||||
onClick={handlerConfirm} |
||||
{...sendCount > 0 ?
|
||||
{} |
||||
: |
||||
{disabled: true} |
||||
} |
||||
>인증번호 확인</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='full-btn-2n vertically-centered-modal'> |
||||
<Button |
||||
color='secondary' |
||||
type='button' |
||||
onClick={props.handlerClose} |
||||
> |
||||
취소 |
||||
</Button> |
||||
<Button |
||||
color='primary' |
||||
type='button' |
||||
onClick={() => setConfirmModal(!confirmModal)} |
||||
{...isCrtfy ? |
||||
{} |
||||
: |
||||
{disabled: true} |
||||
} |
||||
>확인</Button> |
||||
|
||||
{/* <Form onSubmit={handleSubmit(onSubmit)}> */} |
||||
<Modal isOpen={confirmModal} toggle={() => setConfirmModal(!confirmModal)} className='modal-dialog-centered user-search-modal'> |
||||
<ModalHeader toggle={() => setConfirmModal(!confirmModal)}>비밀번호 확인</ModalHeader> |
||||
<ModalBody> |
||||
<span class="etc-txt">새로운 비밀번호로 변경해주세요.</span> |
||||
<FormGroup className='form-label-group position-relative has-icon-left'> |
||||
<InputGroup> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<Lock size={14} /> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type='password' |
||||
id='newPw' |
||||
name='newPw' |
||||
placeholder='새로운 비밀번호' |
||||
value={inputNewPw} |
||||
onChange={handlerChange} |
||||
// className={classnames({
|
||||
// 'is-invalid': errors.newPw
|
||||
// })}
|
||||
/> |
||||
{/* {errors && errors.newPw && ( |
||||
<FormFeedback>{errors.newPw.message}</FormFeedback> |
||||
)} */} |
||||
</InputGroup> |
||||
</FormGroup> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color='primary' onClick={() => setModal(!modal)}> |
||||
저장 |
||||
</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
</div> |
||||
</FormGroup> |
||||
</Form> |
||||
<FormGroup className='form-label-group position-relative has-icon-left mb-0'> |
||||
<InputGroup> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<Lock size={14} /> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input |
||||
type='password' |
||||
id='newPwCk' |
||||
name='newPwCk' |
||||
placeholder='새로운 비밀번호 확인' |
||||
value={inputNewPwCk} |
||||
onChange={handlerChange} |
||||
// className={classnames({
|
||||
// 'is-invalid': errors.newPwCk
|
||||
// })}
|
||||
/> |
||||
{/* {errors && errors.newPwCk && ( |
||||
<FormFeedback>{errors.newPwCk.message}</FormFeedback> |
||||
)} */} |
||||
</InputGroup> |
||||
</FormGroup> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button |
||||
color='primary' |
||||
type='button' |
||||
onClick={handlerUpdatePw} |
||||
>저장</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
{/* </Form> */} |
||||
</div> |
||||
</FormGroup> |
||||
|
||||
<div className='vertically-centered-modal'> |
||||
<Modal |
||||
isOpen={modal.isOpen} |
||||
toggle={() => setModal({ ...modal, isOpen: !modal.isOpen })} |
||||
modalClassName={modal.color} |
||||
className='modal-dialog-centered' |
||||
> |
||||
<ModalHeader |
||||
toggle={() => setModal({ ...modal, isOpen: !modal.isOpen })} |
||||
> |
||||
{modal.title} |
||||
</ModalHeader> |
||||
<ModalBody>{modal.desc}</ModalBody> |
||||
<ModalFooter> |
||||
{ |
||||
udResult?.data.code === 0 ? |
||||
<Button |
||||
color='danger' |
||||
onClick={handlerClose} |
||||
> |
||||
로그인 |
||||
</Button> |
||||
: |
||||
<Button |
||||
color='danger' |
||||
onClick={() => setModal({ ...modal, isOpen: !modal.isOpen })} |
||||
> |
||||
확인 |
||||
</Button> |
||||
} |
||||
</ModalFooter> |
||||
</Modal> |
||||
</div> |
||||
|
||||
</TabPane> |
||||
</> |
||||
) |
||||
|
@ -1,117 +1,362 @@
|
||||
import * as yup from 'yup'; |
||||
import classnames from 'classnames'; |
||||
import { yupResolver } from '@hookform/resolvers/yup'; |
||||
import { useState, useEffect } from 'react' |
||||
import { useParams, Link } from 'react-router-dom' |
||||
import { useSelector, useDispatch } from 'react-redux' |
||||
import { useForm } from 'react-hook-form'; |
||||
import { useDispatch, useSelector } from 'react-redux'; |
||||
|
||||
import { Form, InputGroup, InputGroupAddon, InputGroupText, Card, CardBody, Row, Col, Nav, NavItem, NavLink, TabContent, TabPane, Alert, FormGroup, Input, Label, Button, |
||||
Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap' |
||||
Modal, ModalHeader, ModalBody, ModalFooter, FormFeedback } from 'reactstrap' |
||||
import { User, Info, CreditCard, Lock, Check, X } from 'react-feather' |
||||
|
||||
import loginImg from '../../../assets/images/login01.png'; |
||||
import '../../../assets/css/custom.css'; |
||||
import { findUserIdAction, sendForIdAction } from '../../../modules/account/find/actions/findAction'; |
||||
import { accountApi } from '../../../modules/account/register/apis/accountApi'; |
||||
import { findAPI } from '../../../modules/account/find/apis/findApi'; |
||||
|
||||
export const AccountFindUserId = props => { |
||||
const [activeTab, setActiveTab] = useState('1') |
||||
// const validationSchema = yup.object().shape({
|
||||
// memberName: yup
|
||||
// .string()
|
||||
// .required('이름을 입력해 주세요.'),
|
||||
// hpno: yup.string().required('휴대폰번호를 입력해 주세요.')
|
||||
// })
|
||||
|
||||
// const { register, getValues, setValue, errors, handleSubmit } = useForm({
|
||||
// defaultValues: {
|
||||
// memberName: '',
|
||||
// hpno: '',
|
||||
// },
|
||||
// resolver: yupResolver(validationSchema)
|
||||
// })
|
||||
const dispatch = useDispatch(); |
||||
const [activeTab, setActiveTab] = useState('2') |
||||
|
||||
// ** Function to toggle tabs
|
||||
const toggle = tab => setActiveTab(tab) |
||||
|
||||
//modal
|
||||
const [confirmModal, setConfirmModal] = useState(false) |
||||
const [valiModal, setValiModal] = useState({ |
||||
const [modal, setModal] = useState({ |
||||
isOpen: false, |
||||
title: '', |
||||
desc: '' |
||||
}); |
||||
|
||||
const crtfyhpVali = yup.object().shape({ |
||||
memberName: yup.string().trim().required('이름을 입력해 주세요.'), |
||||
hpno: yup.string().required('휴대폰번호를 입력해 주세요.') |
||||
desc: '', |
||||
color: '' |
||||
}) |
||||
|
||||
const handlerCrtfySend = () => { |
||||
// const vData = getValues();
|
||||
setValiModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '인증번호 발송은 3회 까지만 가능합니다.' |
||||
}); |
||||
return false; |
||||
} |
||||
//state값
|
||||
const { idResult, userId, pwResult, udResult } = useSelector(state => state.findState); |
||||
|
||||
//param으로 넘기기 위한 값
|
||||
const [inputName, setInputName] = useState(''); |
||||
const [inputHpno, setInputHpno] = useState(''); |
||||
const [inputCrtfy, setInputCrtfy] = useState(''); |
||||
|
||||
//3분 시간 및 인증
|
||||
const [minutes_Counter, setMinutes_Counter] = useState('03'); |
||||
const [seconds_Counter, setSeconds_Counter] = useState('00'); |
||||
const [timer, setTimer] = useState(null); |
||||
const [isRunning, setIsRunning] = useState(false); |
||||
const [sendCount, setSendCount] = useState(0); |
||||
const [isCrtfy, setIsCrtfy] = useState(false); |
||||
|
||||
useEffect(() => { |
||||
if(isRunning) clearInterval(timer); |
||||
return () => { clearInterval(timer); } |
||||
}, []); |
||||
|
||||
const handlerSend = async() => { |
||||
if(!inputName || !inputHpno) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '빈칸을 채워주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
if(sendCount >= 3) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '인증번호가 발송은 3회 까지만 가능합니다.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
const res = await findAPI.sendForId({memberName: inputName, hpno: inputHpno}); |
||||
if(res?.data.code === -1) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '가입되지 않은 회원 정보입니다. 다시 확인해 주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
} else if(res?.data.code === 0) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 발송', |
||||
desc: '인증번호가 발송되었습니다.', |
||||
color: 'modal-primary' |
||||
}) |
||||
timeStart(); |
||||
} |
||||
} |
||||
|
||||
const timeStart = () => { |
||||
if(isRunning) { |
||||
clearInterval(timer); |
||||
} |
||||
|
||||
setIsRunning(true); |
||||
setIsCrtfy(false); |
||||
|
||||
setSendCount(sendCount + 1); |
||||
timerStart(180); |
||||
} |
||||
|
||||
const timerStart = count => { |
||||
let minutes, seconds; |
||||
|
||||
const timer = setInterval(() => { |
||||
setIsRunning(true); |
||||
minutes = parseInt(count / 60, 10); |
||||
seconds = parseInt(count % 60, 10); |
||||
minutes = minutes < 10 ? '0' + minutes : minutes; |
||||
seconds = seconds < 10 ? '0' + seconds : seconds; |
||||
setMinutes_Counter(minutes); |
||||
setSeconds_Counter(seconds); |
||||
|
||||
//타이머 끝
|
||||
if (--count < 0) { |
||||
clearInterval(timer); |
||||
setIsRunning(false); |
||||
// setValue('crtfyNo', '');
|
||||
// setCrtfyNo('');
|
||||
} |
||||
}, 1000); |
||||
|
||||
setTimer(timer); |
||||
|
||||
return () => { |
||||
clearInterval(timer); |
||||
} |
||||
} |
||||
|
||||
const handlerConfirm = async() => { |
||||
if(!inputName || !inputHpno) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '빈칸을 채워주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
if(!inputCrtfy) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '인증번호를 입력해 주세요.', |
||||
color: 'modal-danger' |
||||
}) |
||||
return; |
||||
} |
||||
|
||||
const res = await accountApi.crtfyhpConfirm(inputHpno, inputCrtfy); |
||||
if(!res.data.result) { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '인증번호가 잘못 되었습니다.', |
||||
color: 'modal-danger' |
||||
}); |
||||
return; |
||||
} else { |
||||
setModal({ |
||||
isOpen: true, |
||||
title: '인증번호 인증', |
||||
desc: '인증되었습니다.', |
||||
color: 'modal-primary' |
||||
}); |
||||
setIsCrtfy(true); |
||||
setIsRunning(false); |
||||
} |
||||
} |
||||
|
||||
const handlerChange = (e) => { |
||||
const {name, value} = e.target; |
||||
|
||||
if(name == 'memberName') { |
||||
setInputName(value); |
||||
} else if(name == 'hpno') { |
||||
setInputHpno(value); |
||||
} else if(name == 'crtfyhpNo') { |
||||
setInputCrtfy(value); |
||||
} |
||||
} |
||||
|
||||
//모든 인증 완료 후 확인버튼
|
||||
const handlerFindId = () => { |
||||
dispatch(findUserIdAction.request({memberName: inputName, hpno: inputHpno})); |
||||
setConfirmModal(!confirmModal); |
||||
} |
||||
|
||||
|
||||
|
||||
return( |
||||
<> |
||||
<TabPane tabId='1'> |
||||
<Form> |
||||
<FormGroup className='form-label-group position-relative has-icon-left'> |
||||
<FormGroup className='form-label-group position-relative has-icon-left'> |
||||
<InputGroup className=''> |
||||
<InputGroupAddon addonType='prepend'> |
||||
<InputGroupText> |
||||
<User size={14} /> |
||||
<User size={14}/> |
||||
</InputGroupText> |
||||
</InputGroupAddon> |
||||
<Input placeholder='이름' /> |
||||
<Input |
||||
type='text' |
||||
id='memberName' |
||||
name='memberName' |
||||
placeholder='이름' |
||||
value={inputName} |
||||
onChange={handlerChange} |
||||
// className={classnames({
|
||||
// 'is-invalid': errors.memberName
|
||||
// })}
|
||||
/> |
||||
{/* {errors && errors.memberName && ( |
||||
<FormFeedback>{errors.memberName.message}</FormFeedback> |
||||
)} */} |
||||
</InputGroup> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn'> |
||||
<Col md='3' xs='12'> |
||||
<Input type='select' placeholder='+(국가번호)'> |
||||
<option>+82</option> |
||||
{/* <option>21111</option> */} |
||||
</Input> |
||||
</Col> |
||||
<Col md='6' xs='12'> |
||||
<Input type='number' placeholder='휴대폰번호'/> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button |
||||
color='primary' |
||||
type='button' |
||||
onClick={handlerCrtfySend} |
||||
> |
||||
인증번호 발송 |
||||
</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn'> |
||||
<Col md='9' xs='12' className='timeInput'> |
||||
<Input type='number' placeholder='인증번호 입력'/> |
||||
<span className='time'>남은시간 : 3:00</span> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button color='primary' type='button'>인증번호 확인</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='full-btn-2n vertically-centered-confirmModal'> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='input-btn'> |
||||
<Col md='3' xs='12'> |
||||
<Input type='select' id='cntryCd' name='cntryCd' placeholder='+(국가번호)'> |
||||
<option>+82</option> |
||||
{/* <option>21111</option> */} |
||||
</Input> |
||||
</Col> |
||||
<Col md='6' xs='12'> |
||||
<Input |
||||
type='number' |
||||
id='hpno' |
||||
name='hpno' |
||||
placeholder='01012345678' |
||||
value={inputHpno} |
||||
onChange={handlerChange} |
||||
// className={classnames({
|
||||
// 'is-invalid': errors.hpno
|
||||
// })}
|
||||
/> |
||||
{/* {errors && errors.hpno && ( |
||||
<FormFeedback>{errors.hpno.message}</FormFeedback> |
||||
)} */} |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button |
||||
color='secondary' |
||||
color='primary' |
||||
type='button' |
||||
onClick={handlerSend} |
||||
>인증번호 발송</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
<div className='input-btn'> |
||||
<Col md='9' xs='12' className='timeInput'> |
||||
<Input |
||||
type='number' |
||||
id='crtfyhpNo' |
||||
name='crtfyhpNo' |
||||
placeholder='인증번호 입력' |
||||
onChange={handlerChange}
|
||||
{...sendCount > 0 ?
|
||||
{} |
||||
: |
||||
{disabled: true} |
||||
} |
||||
/> |
||||
<span className={!isRunning || isCrtfy ? 'time d-none' : 'time'}> |
||||
남은시간 {minutes_Counter}:{seconds_Counter} |
||||
</span> |
||||
</Col> |
||||
<Col md='3' xs='12'> |
||||
<Button
|
||||
color='primary' |
||||
type='button' |
||||
onClick={props.handlerClose} |
||||
onClick={handlerConfirm} |
||||
{ ...isRunning ?
|
||||
{} |
||||
: |
||||
{disabled: true} |
||||
} |
||||
>인증번호 확인</Button> |
||||
</Col> |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<div className='full-btn-2n vertically-centered-confirmModal'> |
||||
<Button |
||||
color='secondary' |
||||
type='button' |
||||
onClick={props.handlerClose} |
||||
> |
||||
취소 |
||||
</Button> |
||||
<Button |
||||
color='primary' |
||||
type='button' |
||||
onClick={handlerFindId} |
||||
{...isCrtfy ? |
||||
{} |
||||
: |
||||
{disabled: true} |
||||
} |
||||
>확인</Button> |
||||
<Modal isOpen={confirmModal} toggle={() => setConfirmModal(!confirmModal)} className='modal-dialog-centered user-search-modal'> |
||||
<ModalHeader toggle={() => setConfirmModal(!confirmModal)}>아이디 확인</ModalHeader> |
||||
<ModalBody> |
||||
회원님의 아이디는<br/><span className='user-search-id'>{userId?.data.userId}</span> 입니다. |
||||
{/* 회원님의 아이디는<br/><span className='user-search-id'>{result?.data.userId}</span> 입니다. */} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color='primary' onClick={props.handlerClose}> |
||||
로그인 |
||||
</Button>{' '} |
||||
</ModalFooter> |
||||
</Modal> |
||||
</div> |
||||
</FormGroup> |
||||
|
||||
<div className='vertically-centered-modal'> |
||||
<Modal |
||||
isOpen={modal.isOpen} |
||||
toggle={() => setModal({ ...modal, isOpen: !modal.isOpen })} |
||||
modalClassName={modal.color} |
||||
className='modal-dialog-centered' |
||||
> |
||||
<ModalHeader |
||||
toggle={() => setModal({ ...modal, isOpen: !modal.isOpen })} |
||||
> |
||||
{modal.title} |
||||
</ModalHeader> |
||||
<ModalBody>{modal.desc}</ModalBody> |
||||
<ModalFooter> |
||||
<Button |
||||
color='danger' |
||||
onClick={() => setModal({ ...modal, isOpen: !modal.isOpen })} |
||||
> |
||||
취소 |
||||
</Button> |
||||
<Button color='primary' type='button' onClick={() => setConfirmModal(!confirmModal)} >확인</Button> |
||||
<Modal isOpen={confirmModal} toggle={() => setConfirmModal(!confirmModal)} className='confirmModal-dialog-centered user-search-confirmModal'> |
||||
<ModalHeader toggle={() => setConfirmModal(!confirmModal)}>아이디 확인</ModalHeader> |
||||
<ModalBody> |
||||
회원님의 아이디는<br/><span className='user-search-id'>TEST123123</span> 입니다. |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
{/* <Button color='primary' onClick={() => setConfirmModal(!confirmModal)}> */} |
||||
<Button color='primary' onClick={props.handlerClose}> |
||||
로그인 |
||||
</Button>{' '} |
||||
</ModalFooter> |
||||
</Modal> |
||||
</div> |
||||
</FormGroup> |
||||
</Form> |
||||
확인 |
||||
</Button>{' '} |
||||
</ModalFooter> |
||||
</Modal> |
||||
</div> |
||||
|
||||
</TabPane> |
||||
</> |
||||
) |
||||
|
@ -0,0 +1,52 @@
|
||||
import { AxiosError } from 'axios'; |
||||
import { string } from 'prop-types'; |
||||
import { ActionType, createAsyncAction } from 'typesafe-actions'; |
||||
|
||||
const SEND_FORID_REQUEST = 'find/SEND_FORID_REQUEST'; |
||||
const SEND_FORID_SUCCESS = 'find/SEND_FORID_SUCCESS'; |
||||
const SEND_FORID_FAILURE = 'find/SEND_FORID_FAILURE'; |
||||
|
||||
const FIND_USERID_REQUEST = 'find/FIND_USERID_REQUEST'; |
||||
const FIND_USERID_SUCCESS = 'find/FIND_USERID_SUCCESS'; |
||||
const FIND_USERID_FAILURE = 'find/FIND_USERID_FAILURE'; |
||||
|
||||
const SEND_FORPW_REQUEST = 'find/SEND_FORPW_REQUEST'; |
||||
const SEND_FORPW_SUCCESS = 'find/SEND_FORPW_SUCCESS'; |
||||
const SEND_FORPW_FAILURE = 'find/SEND_FORPW_FAILURE'; |
||||
|
||||
const UPDATE_USERPW_REQUEST = 'find/UPDATE_USERPW_REQUEST' |
||||
const UPDATE_USERPW_SUCCESS = 'find/UPDATE_USERPW_SUCCESS' |
||||
const UPDATE_USERPW_FAILURE = 'find/UPDATE_USERPW_FAILURE' |
||||
|
||||
export const sendForIdAction = createAsyncAction( |
||||
SEND_FORID_REQUEST, |
||||
SEND_FORID_SUCCESS, |
||||
SEND_FORID_FAILURE |
||||
)<{memberName: string, hpno: string}, string, AxiosError>(); |
||||
|
||||
export const findUserIdAction = createAsyncAction( |
||||
FIND_USERID_REQUEST, |
||||
FIND_USERID_SUCCESS, |
||||
FIND_USERID_FAILURE |
||||
)<{memberName: string, hpno: string}, string, AxiosError>(); |
||||
|
||||
export const sendForPwAction = createAsyncAction( |
||||
SEND_FORPW_REQUEST, |
||||
SEND_FORPW_SUCCESS, |
||||
SEND_FORPW_FAILURE |
||||
)<{userId: string, hpno: string}, string, AxiosError>(); |
||||
|
||||
export const updatePwAction = createAsyncAction( |
||||
UPDATE_USERPW_REQUEST, |
||||
UPDATE_USERPW_SUCCESS, |
||||
UPDATE_USERPW_FAILURE |
||||
)<{userId: string, hpno: string, newPw: string}, string, AxiosError>(); |
||||
|
||||
const actions = { |
||||
sendForIdAction, |
||||
findUserIdAction, |
||||
sendForPwAction, |
||||
updatePwAction |
||||
}; |
||||
|
||||
export type FindAction = ActionType<typeof actions>; |
@ -0,0 +1,21 @@
|
||||
import axios from '../../../utils/customAxiosUtil'; |
||||
|
||||
import qs from 'qs'; |
||||
|
||||
export const findAPI = { |
||||
sendForId: async(param) => { |
||||
return await axios.get(`api/acnt/crtfyhp/find/sendForId?memberName=${param.memberName}&hpno=${param.hpno}`); |
||||
}, |
||||
|
||||
getUserId: async(param) => { |
||||
return await axios.get(`api/acnt/crtfyhp/find/findUserId?memberName=${param.memberName}&hpno=${param.hpno}`); |
||||
}, |
||||
|
||||
sendForPw: async(param) => { |
||||
return await axios.get(`api/acnt/crtfyhp/find/sendForPw?userId=${param.userId}&hpno=${param.hpno}`); |
||||
}, |
||||
|
||||
updatePw: async(param) => {
|
||||
return await axios.get(`api/acnt/crtfyhp/find/updatePw?userId=${param.userId}&hpno=${param.hpno}&newPw=${param.newPw}`); |
||||
} |
||||
} |
@ -0,0 +1,19 @@
|
||||
export interface AccountFindState { |
||||
accountFind: AccountFindData | undefined; |
||||
} |
||||
export interface AccountFindData { |
||||
cstmrSno: number; |
||||
userId: string; |
||||
memberName: string; |
||||
hpno: string; |
||||
cntfyhpNo: string; |
||||
crtfyhpYn: string; |
||||
} |
||||
|
||||
export interface IsCntfyhpSend { |
||||
|
||||
} |
||||
|
||||
export const initResponseFindData = { |
||||
accountFind: undefined |
||||
} |
@ -0,0 +1,55 @@
|
||||
// base
|
||||
import produce from 'immer'; |
||||
|
||||
import { createReducer } from 'typesafe-actions'; |
||||
|
||||
// action
|
||||
import { |
||||
FindAction, |
||||
findUserIdAction, |
||||
sendForIdAction, |
||||
sendForPwAction, |
||||
updatePwAction |
||||
} from '../actions/findAction'; |
||||
|
||||
//
|
||||
export interface findState { |
||||
idResult: string | undefined; |
||||
userId: string | undefined; |
||||
pwResult: string | undefined; |
||||
udResult: string | undefined; |
||||
} |
||||
const initFindState : findState = { |
||||
idResult: undefined, |
||||
userId: undefined, |
||||
pwResult: undefined, |
||||
udResult: undefined |
||||
} |
||||
|
||||
export const findAccountReducer = createReducer<findState, FindAction>( |
||||
initFindState |
||||
).handleAction(sendForIdAction.success, (state, action) =>
|
||||
produce(state, draft => { |
||||
const data = action.payload; |
||||
|
||||
draft.idResult = data; |
||||
}) |
||||
).handleAction(findUserIdAction.success, (state, action) =>
|
||||
produce(state, draft => { |
||||
const data = action.payload; |
||||
|
||||
draft.userId = data; |
||||
}) |
||||
).handleAction(sendForPwAction.success, (state, action) => |
||||
produce(state, draft => { |
||||
const data = action.payload; |
||||
|
||||
draft.pwResult = data; |
||||
}) |
||||
).handleAction(updatePwAction.success, (state, action) => |
||||
produce(state, draft => { |
||||
const data = action.payload; |
||||
|
||||
draft.udResult = data; |
||||
}) |
||||
) |
@ -0,0 +1,67 @@
|
||||
import { call, put, takeEvery } from 'redux-saga/effects'; |
||||
// packages
|
||||
import { ActionType } from 'typesafe-actions'; |
||||
// modules
|
||||
import * as Actions from '../actions/findAction'; |
||||
import { findAPI } from '../apis/findApi'; |
||||
|
||||
|
||||
function* sendForIdSaga( |
||||
action: ActionType<typeof Actions.sendForIdAction.request> |
||||
) { |
||||
try{ |
||||
const {memberName, hpno} = action.payload; |
||||
|
||||
const res = yield call(findAPI.sendForId, { memberName, hpno }); |
||||
yield put(Actions.sendForIdAction.success(res)); |
||||
} catch (error) { |
||||
yield put(Actions.sendForIdAction.failure(error)); |
||||
} |
||||
} |
||||
|
||||
function* findUserIdSaga( |
||||
action: ActionType<typeof Actions.findUserIdAction.request> |
||||
) { |
||||
try{ |
||||
const {memberName, hpno} = action.payload; |
||||
|
||||
const res = yield call(findAPI.getUserId, { memberName, hpno }); |
||||
yield put(Actions.findUserIdAction.success(res)); |
||||
} catch (error) { |
||||
yield put(Actions.findUserIdAction.failure(error)); |
||||
} |
||||
} |
||||
|
||||
function* sendForPwSaga( |
||||
action: ActionType<typeof Actions.sendForPwAction.request> |
||||
) { |
||||
try{ |
||||
const {userId, hpno} = action.payload; |
||||
|
||||
const res = yield call(findAPI.sendForPw, {userId, hpno}); |
||||
yield put(Actions.sendForPwAction.success(res)); |
||||
} catch (error) { |
||||
yield put(Actions.sendForPwAction.failure(error)); |
||||
} |
||||
} |
||||
|
||||
function* updatePwSaga( |
||||
action: ActionType<typeof Actions.updatePwAction.request> |
||||
) { |
||||
try{ |
||||
const {userId, hpno, newPw} = action.payload; |
||||
|
||||
const res = yield call(findAPI.updatePw, {userId, hpno, newPw}); |
||||
console.log(res, '>>>') |
||||
yield put(Actions.updatePwAction.success(res)); |
||||
} catch (error) { |
||||
yield put(Actions.updatePwAction.failure(error)); |
||||
} |
||||
} |
||||
|
||||
export function* findSaga() { |
||||
yield takeEvery(Actions.sendForIdAction.request, sendForIdSaga); |
||||
yield takeEvery(Actions.findUserIdAction.request, findUserIdSaga); |
||||
yield takeEvery(Actions.sendForPwAction.request, sendForPwSaga); |
||||
yield takeEvery(Actions.updatePwAction.request, updatePwSaga); |
||||
} |
Loading…
Reference in new issue