Browse Source

아이디찾기, 비밀번호 찾기 작업

pull/2/head
junh_eee 2 years ago
parent
commit
febd1c49da
  1. 517
      src/components/account/find/AccountFindPassword.js
  2. 4
      src/components/account/find/AccountFindTab.js
  3. 409
      src/components/account/find/AccountFindUserId.js
  4. 52
      src/modules/account/find/actions/findAction.ts
  5. 21
      src/modules/account/find/apis/findApi.ts
  6. 19
      src/modules/account/find/models/findModel.ts
  7. 55
      src/modules/account/find/reducers/findReducer.ts
  8. 67
      src/modules/account/find/sagas/findSaga.ts
  9. 6
      src/redux/reducers/rootReducer.ts

517
src/components/account/find/AccountFindPassword.js

@ -1,108 +1,463 @@
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 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('1')
// ** 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)}
// onClick={handlerChangePw}
// {...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='submit'
type='button'
// onClick={() => setModal(!modal)}
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={() => setModal({ ...modal, isOpen: !modal.isOpen })}
// onClick={props.handlerClose}
onClick={handlerClose}
>
로그인
</Button>
:
<Button
color='danger'
onClick={() => setModal({ ...modal, isOpen: !modal.isOpen })}
>
확인
</Button>
}
</ModalFooter>
</Modal>
</div>
</TabPane>
</>
)

4
src/components/account/find/AccountFindTab.js

@ -27,15 +27,13 @@ export const AccountFindTab = props => {
const history = useHistory();
const toggle = tab => setActiveTab(tab)
const [centeredModal, setCenteredModal] = useState(false)
const [centeredModal02, setCenteredModal02] = useState(false)
// const toggle = tab => {
// if (activeTab !== tab) setActiveTab(tab);
// };
const handlerClose = () => {
history.push(`/account/login/AccountLogin`)
history.push(`/account/login`)
}
return(

409
src/components/account/find/AccountFindUserId.js

@ -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('1')
// ** 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}
{...sendCount > 0 ?
{}
:
{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>
</>
)

52
src/modules/account/find/actions/findAction.ts

@ -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>;

21
src/modules/account/find/apis/findApi.ts

@ -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}`);
}
}

19
src/modules/account/find/models/findModel.ts

@ -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
}

55
src/modules/account/find/reducers/findReducer.ts

@ -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;
})
)

67
src/modules/account/find/sagas/findSaga.ts

@ -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);
}

6
src/redux/reducers/rootReducer.ts

@ -15,6 +15,8 @@ import { groupReducer } from '../../modules/basis/group/reducers/basisGroupReduc
import { basGroupSaga } from '../../modules/basis/group/sagas/basisGroupSaga';
import { messageReducer } from '../../modules/comn/message/reducers/comnMessageReducer';
import { mypageReducer, userPwReducer } from '../../modules/account/login/reducers/authReducer';
import { findSaga } from '../../modules/account/find/sagas/findSaga';
import { findAccountReducer } from '../../modules/account/find/reducers/findReducer';
import {
controlGpDtlReducer,
@ -52,6 +54,7 @@ export function* saga() {
yield all([fork(dronSaga)]);
yield all([fork(analysisSimulatorSaga)]);
yield all([fork(flightSaga)]);
yield all([fork(findSaga)]);
}
const rootReducer = combineReducers({
@ -76,7 +79,8 @@ const rootReducer = combineReducers({
menuState: menuReducer,
analysisHistoryState: analysisHistoryReducer,
analysisSimulatorState: analysisSimulatorReducer,
flightState: flightReducer
flightState: flightReducer,
findState: findAccountReducer,
});
export default rootReducer;

Loading…
Cancel
Save