Browse Source

인증번호 공통단 비밀번호 찾기에 적용

master
junh_eee(이준희) 7 months ago
parent
commit
8f7fa6089e
  1. 396
      src/components/account/find/AccountFindPassword.js
  2. 5
      src/components/account/find/AccountFindTab.js
  3. 249
      src/containers/account/find/AccountFindPasswordContainer.js
  4. 6
      src/containers/account/find/AccountFindUserIdContainer.js

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

@ -1,5 +1,3 @@
import { useDispatch } from '@src/redux/store';
import { useState, useEffect } from 'react';
import {
InputGroup,
InputGroupAddon,
@ -8,261 +6,27 @@ import {
TabPane,
FormGroup,
Input,
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter
Button
} from '@component/ui';
import { User, Lock } from 'react-feather';
import '../../../assets/css/custom.css';
import { confirmCrtfyhp } from '@src/redux/features/account/register/registerThunk';
import {
sendCrtfyhpForPw,
updateUserPw
} from '@src/redux/features/account/find/findThunk';
import { openModal } from '@src/redux/features/comn/message/messageSlice';
import { MODAL_CRTFYHP, MODAL_BODY, MODAL_HEADER } from '@src/configs/msgConst';
export const AccountFindPassword = props => {
const dispatch = useDispatch();
// 탭 상태
const [activeTab, setActiveTab] = useState('2');
// ** Function to toggle tabs
const toggle = tab => setActiveTab(tab);
//modal
const [confirmModal, setConfirmModal] = useState(false);
// 비밀번호 변경 모달
const [saveModal, setSaveModal] = useState(false);
//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(() => {
setIsRunning(true);
if (isRunning) clearInterval(timer);
return () => {
clearInterval(timer);
setIsRunning(false);
};
}, []);
// 단순 메시지 표출 모달
const handlerOpenModal = (header, body) => {
dispatch(
openModal({
header: header,
body: body
})
);
};
const handlerValidCheck = () => {
if (!inputId) {
handlerOpenModal(MODAL_HEADER.crtfyhp, '아이디를' + MODAL_BODY.valid);
return;
}
};
const handlerSend = async () => {
handlerValidCheck();
if (!inputHpno) {
handlerOpenModal(
MODAL_HEADER.crtfyhp,
'휴대폰 번호를' + MODAL_BODY.valid
);
return;
}
if (inputHpno.length < 11) {
handlerOpenModal(
MODAL_HEADER.crtfyhp,
'올바른 번호를' + MODAL_BODY.valid
);
return;
}
if (sendCount >= 3) {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.count);
return;
}
const { payload: data } = await dispatch(
sendCrtfyhpForPw({ userId: inputId, hpno: inputHpno })
);
if (data.code === -1) {
handlerOpenModal(
MODAL_HEADER.crtfyhp,
'가입되지 않은 회원정보입니다. 다시 확인해주세요.'
);
} else if (data.code === 0) {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.send);
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('');
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.expire);
}
}, 1000);
setTimer(timer);
return () => {
clearInterval(timer);
};
};
const handlerConfirm = async () => {
if (!inputId) {
handlerOpenModal(MODAL_HEADER.crtfyhp, '아이디를' + MODAL_BODY.valid);
return;
}
if (!inputHpno) {
handlerOpenModal(
MODAL_HEADER.crtfyhp,
'휴대폰 번호를' + MODAL_BODY.valid
);
return;
}
if (!inputCrtfy) {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.valid);
return;
}
// const res = await accountAPI.confirmCrtfyhp(inputHpno, inputCrtfy);
const { payload: data } = await dispatch(
confirmCrtfyhp({ hpno: inputHpno, crtfyNo: inputCrtfy })
);
if (!data.result) {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.failed);
return;
} else {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.confirm);
setIsCrtfy(true);
setIsRunning(false);
}
};
const handlerUpdatePw = async () => {
const modalHeader = '비밀번호 변경';
if (!inputNewPw || !inputNewPwCk) {
handlerOpenModal(modalHeader, '비밀번호를' + MODAL_BODY.valid);
return;
}
const reg =
/^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[@$!%*#?&])[A-Za-z0-9@$!%*#?&]{8,20}$/;
if (!reg.test(inputNewPw) || !reg.test(inputNewPwCk)) {
handlerOpenModal(
modalHeader,
'8자 이상, 20자 미만 영문자/숫자/특수문자(@$!%*#?&) 조합하여 입력해주세요.'
);
return;
}
if (inputNewPw !== inputNewPwCk) {
handlerOpenModal(modalHeader, '비밀번호가 일치하지 않습니다.');
return;
}
if (inputNewPw === inputNewPwCk && inputNewPw && inputNewPwCk) {
const param = {
userId: inputId,
hpno: inputHpno,
newPw: inputNewPw
};
dispatch(updateUserPw(param));
setSaveModal(!saveModal);
}
};
let id = '';
let hpno = '';
let crtfyhp = '';
let newpw = '';
let newpwck = '';
const handlerChange = e => {
const { name, value } = e.target;
if (name == 'userId') {
id = value;
setInputId(id);
} else if (name == 'hpno') {
const regex = /^[0-9]{0,11}$/;
if (regex.test(value)) {
hpno = value;
setInputHpno(hpno);
}
} else if (name == 'crtfyhpNo') {
const regex = /^[0-9]{0,6}$/;
if (regex.test(value)) {
crtfyhp = value;
setInputCrtfy(crtfyhp);
}
} else if (name == 'newPw') {
const regex = /^[A-Za-z0-9@$!%*#?&]{0,20}$/;
if (regex.test(value)) {
newpw = value;
setInputNewPw(newpw);
}
} else if (name == 'newPwCk') {
const regex = /^[A-Za-z0-9@$!%*#?&]{0,20}$/;
if (regex.test(value)) {
newpwck = value;
setInputNewPwCk(newpwck);
}
}
};
import { User } from 'react-feather';
import { useSelector } from '@src/redux/store';
import { CrtfyhpUtil } from '@src/utility/crtfyhpUtil';
import { useRef } from 'react';
import { sendCrtfyhpForPw } from '@src/redux/features/account/find/findThunk';
export const AccountFindPassword = ({
rq,
inputCrtfy,
handlerModal,
handlerClose,
handlerChange,
handlerConfirm,
handlerValidCheck
}) => {
const hookRef = useRef();
const { isRunning, isCrtfyhp, counter, sendCount } = useSelector(
state => state.crtfyhpState
);
return (
<>
<TabPane tabId='2'>
@ -278,15 +42,20 @@ export const AccountFindPassword = props => {
id='userId'
name='userId'
placeholder='아이디'
value={inputId}
value={rq.userId}
onChange={handlerChange}
disabled={isRunning || isCrtfyhp}
/>
</InputGroup>
</FormGroup>
<FormGroup>
<div className='input-btn'>
<Col md='3' xs='12'>
<Input type='select' placeholder='+(국가번호)'>
<Input
type='select'
placeholder='+(국가번호)'
disabled={isRunning || isCrtfyhp}
>
{/* <option>+82</option> */}
<option value={'+82'}>대한민국(+82)</option>
<option value={'+81'}>일본(+81)</option>
@ -299,12 +68,20 @@ export const AccountFindPassword = props => {
id='hpno'
name='hpno'
placeholder='01012345678'
value={inputHpno}
value={rq.hpno}
onChange={handlerChange}
disabled={isRunning || isCrtfyhp}
/>
</Col>
<Col md='3' xs='12'>
<Button color='primary' type='button' onClick={handlerSend}>
<Button
color='primary'
type='button'
disabled={isRunning || isCrtfyhp}
onClick={() => {
hookRef?.current?.handlerSendCrtfyhp(rq);
}}
>
인증번호 발송
</Button>
</Col>
@ -320,11 +97,10 @@ export const AccountFindPassword = props => {
placeholder='인증번호 입력'
value={inputCrtfy}
onChange={handlerChange}
{...(sendCount > 0 ? {} : { disabled: true })}
{...(isRunning ? {} : { disabled: true })}
/>
{/* <span className='time'>남은시간 : 3:00</span> */}
<span className={!isRunning || isCrtfy ? 'time d-none' : 'time'}>
남은시간 {minutes_Counter}:{seconds_Counter}
<span className={!isRunning ? 'time d-none' : 'time'}>
남은시간 {counter.min}:{counter.sec}
</span>
</Col>
<Col md='3' xs='12'>
@ -341,100 +117,26 @@ export const AccountFindPassword = props => {
</FormGroup>
<FormGroup>
<div className='full-btn-2n vertically-centered-modal'>
{/* <div className='full-btn-2n vertically-centered-confirmModal'> */}
<Button
color='secondary'
type='button'
onClick={props.handlerClose}
>
<Button color='secondary' type='button' onClick={handlerClose}>
취소
</Button>
<Button
color='primary'
type='button'
onClick={() => setConfirmModal(!confirmModal)}
{...(isCrtfy ? {} : { disabled: true })}
onClick={handlerModal}
{...(isCrtfyhp ? {} : { disabled: true })}
>
확인
</Button>
<Modal
isOpen={confirmModal}
toggle={() => setConfirmModal(!confirmModal)}
className='modal-dialog-centered user-search-modal'
>
<ModalHeader toggle={() => setConfirmModal(!confirmModal)}>
비밀번호 확인
</ModalHeader>
<ModalBody>
<span className='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}
/>
</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
type='password'
id='newPwCk'
name='newPwCk'
placeholder='새로운 비밀번호 확인'
value={inputNewPwCk}
onChange={handlerChange}
/>
</InputGroup>
</FormGroup>
</ModalBody>
<ModalFooter>
<Button color='primary' type='button' onClick={handlerUpdatePw}>
저장
</Button>
<div className='vertically-centered-modal'>
<Modal
isOpen={saveModal}
toggle={() => setSaveModal(!saveModal)}
modalClassName='modal-primary'
className='modal-dialog-centered'
>
<ModalHeader toggle={() => setSaveModal(!saveModal)}>
비밀번호 변경
</ModalHeader>
<ModalBody>
변경이 완료되었습니다. 다시 로그인해 주세요.
</ModalBody>
<ModalFooter>
<Button color='primary' onClick={props.handlerClose}>
로그인
</Button>{' '}
</ModalFooter>
</Modal>
</div>
</ModalFooter>
</Modal>
</div>
</FormGroup>
</TabPane>
<CrtfyhpUtil
ref={hookRef}
sendCrtfyhp={sendCrtfyhpForPw}
handlerValidCheck={handlerValidCheck}
modalMessage='가입되지 않은 회원정보입니다.'
/>
</>
);
};

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

@ -89,7 +89,10 @@ export const AccountFindTab = props => {
handlerClose={handlerClose}
handlerOpenModal={handlerOpenModal}
/>
<AccountFindPasswordContainer handlerClose={handlerClose} />
<AccountFindPasswordContainer
handlerClose={handlerClose}
handlerOpenModal={handlerOpenModal}
/>
</TabContent>
</CardBody>
</Card>

249
src/containers/account/find/AccountFindPasswordContainer.js

@ -1,13 +1,250 @@
import { AccountFindPassword } from "../../../components/account/find/AccountFindPassword"
import { useDispatch } from '@src/redux/store';
import { AccountFindPassword } from '../../../components/account/find/AccountFindPassword';
import { useState } from 'react';
import { MODAL_BODY, MODAL_CRTFYHP, MODAL_HEADER } from '@src/configs/msgConst';
import {
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Button,
FormGroup,
InputGroup,
InputGroupAddon,
InputGroupText,
Input
} from '@component/ui';
import { Lock } from 'react-feather';
import { confirmCrtfyhp } from '@src/redux/features/account/register/registerThunk';
import {
isConfirmCrtfyhp,
isSendCrtfyhp
} from '@src/redux/features/comn/crtfyhp/crtfyhpSlice';
export const AccountFindPasswordContainer = props => {
export const AccountFindPasswordContainer = ({
handlerClose,
handlerOpenModal
}) => {
const dispatch = useDispatch();
return(
//modal
const [confirmModal, setConfirmModal] = useState(false);
// 비밀번호 변경 모달
const [saveModal, setSaveModal] = useState(false);
//param으로 넘기기 위한 값
const [inputCrtfy, setInputCrtfy] = useState('');
const [inputNewPw, setInputNewPw] = useState('');
const [inputNewPwCk, setInputNewPwCk] = useState('');
const [rq, setRq] = useState({
userId: '',
hpno: ''
});
const handlerValidCheck = () => {
if (!rq.userId) {
handlerOpenModal(MODAL_HEADER.crtfyhp, '아이디를' + MODAL_BODY.valid);
return;
}
};
const handlerConfirm = async () => {
if (!rq.userId) {
handlerOpenModal(MODAL_HEADER.crtfyhp, '아이디를' + MODAL_BODY.valid);
return;
}
if (!rq.hpno) {
handlerOpenModal(
MODAL_HEADER.crtfyhp,
'휴대폰 번호를' + MODAL_BODY.valid
);
return;
}
if (!inputCrtfy) {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.valid);
return;
}
const { payload: data } = await dispatch(
confirmCrtfyhp({ hpno: rq.hpno, crtfyNo: inputCrtfy })
);
if (!data.result) {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.failed);
return;
} else {
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.confirm);
dispatch(isSendCrtfyhp(false));
dispatch(isConfirmCrtfyhp(true));
}
};
const handlerUpdatePw = async () => {
const modalHeader = '비밀번호 변경';
if (!inputNewPw || !inputNewPwCk) {
handlerOpenModal(modalHeader, '비밀번호를' + MODAL_BODY.valid);
return;
}
const reg =
/^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[@$!%*#?&])[A-Za-z0-9@$!%*#?&]{8,20}$/;
if (!reg.test(inputNewPw) || !reg.test(inputNewPwCk)) {
handlerOpenModal(
modalHeader,
'8자 이상, 20자 미만 영문자/숫자/특수문자(@$!%*#?&) 조합하여 입력해주세요.'
);
return;
}
if (inputNewPw !== inputNewPwCk) {
handlerOpenModal(modalHeader, '비밀번호가 일치하지 않습니다.');
return;
}
if (inputNewPw === inputNewPwCk && inputNewPw && inputNewPwCk) {
const param = {
userId: rq.userId,
hpno: rq.hpno,
newPw: inputNewPw
};
dispatch(updateUserPw(param));
setSaveModal(!saveModal);
}
};
let id = '';
let hpno = '';
let crtfyhp = '';
let newpw = '';
let newpwck = '';
const handlerChange = e => {
const { name, value } = e.target;
if (name == 'userId') {
id = value;
setRq(prev => ({
...prev,
userId: id
}));
} else if (name == 'hpno') {
const regex = /^[0-9]{0,11}$/;
if (regex.test(value)) {
hpno = value;
setRq(prev => ({
...prev,
hpno: hpno
}));
}
} else if (name == 'crtfyhpNo') {
const regex = /^[0-9]{0,6}$/;
if (regex.test(value)) {
crtfyhp = value;
setInputCrtfy(crtfyhp);
}
} else if (name == 'newPw') {
const regex = /^[A-Za-z0-9@$!%*#?&]{0,20}$/;
if (regex.test(value)) {
newpw = value;
setInputNewPw(newpw);
}
} else if (name == 'newPwCk') {
const regex = /^[A-Za-z0-9@$!%*#?&]{0,20}$/;
if (regex.test(value)) {
newpwck = value;
setInputNewPwCk(newpwck);
}
}
};
const handlerModal = () => {
setConfirmModal(!confirmModal);
};
return (
<>
<AccountFindPassword
handlerClose={props.handlerClose}
rq={rq}
inputCrtfy={inputCrtfy}
handlerModal={handlerModal}
handlerClose={handlerClose}
handlerChange={handlerChange}
handlerConfirm={handlerConfirm}
handlerValidCheck={handlerValidCheck}
/>
<Modal
isOpen={confirmModal}
toggle={() => setConfirmModal(!confirmModal)}
className='modal-dialog-centered user-search-modal'
>
<ModalHeader toggle={() => setConfirmModal(!confirmModal)}>
비밀번호 확인
</ModalHeader>
<ModalBody>
<span className='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}
/>
</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
type='password'
id='newPwCk'
name='newPwCk'
placeholder='새로운 비밀번호 확인'
value={inputNewPwCk}
onChange={handlerChange}
/>
</InputGroup>
</FormGroup>
</ModalBody>
<ModalFooter>
<Button color='primary' type='button' onClick={handlerUpdatePw}>
저장
</Button>
<div className='vertically-centered-modal'>
<Modal
isOpen={saveModal}
toggle={() => setSaveModal(!saveModal)}
modalClassName='modal-primary'
className='modal-dialog-centered'
>
<ModalHeader toggle={() => setSaveModal(!saveModal)}>
비밀번호 변경
</ModalHeader>
<ModalBody>
변경이 완료되었습니다. 다시 로그인해 주세요.
</ModalBody>
<ModalFooter>
<Button color='primary' onClick={handlerClose}>
로그인
</Button>{' '}
</ModalFooter>
</Modal>
</div>
</ModalFooter>
</Modal>
</>
)
}
);
};

6
src/containers/account/find/AccountFindUserIdContainer.js

@ -23,8 +23,6 @@ export const AccountFindUserIdContainer = ({
}) => {
const dispatch = useDispatch();
const [activeTab, setActiveTab] = useState('2');
const [confirmModal, setConfirmModal] = useState(false);
const { userId } = useSelector(state => state.findState);
@ -117,10 +115,6 @@ export const AccountFindUserIdContainer = ({
setConfirmModal(!confirmModal);
};
const toggle = tab => {
setActiveTab(tab);
};
return (
<>
<AccountFindUserId

Loading…
Cancel
Save