junh_eee(이준희)
7 months ago
6 changed files with 248 additions and 22 deletions
@ -0,0 +1,149 @@
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; |
||||
import { MODAL_CRTFYHP, MODAL_HEADER, MODAL_BODY } from '@src/configs/msgConst'; |
||||
import { useDispatch, useSelector } from '@src/redux/store'; |
||||
import { openModal } from '@src/redux/features/comn/message/messageSlice'; |
||||
import { |
||||
isSendCrtfyhp, |
||||
isStartTimer, |
||||
resetTimer, |
||||
setCounter, |
||||
setSendCount |
||||
} from '@src/redux/features/comn/crtfyhp/crtfyhpSlice'; |
||||
|
||||
export const CrtfyhpHook = forwardRef( |
||||
({ handlerValidCheck, sendCrtfyhp, rq, modalMesssage, type }, ref) => { |
||||
const dispatch = useDispatch(); |
||||
const { isRunning, sendCount } = useSelector(state => state.crtfyhpState); |
||||
|
||||
// 타이머
|
||||
const [timer, setTimer] = useState(null); |
||||
|
||||
// 언마운트시 타이머 종료
|
||||
useEffect(() => { |
||||
if (isRunning) { |
||||
handlerResetTimer(); |
||||
} |
||||
|
||||
return () => { |
||||
handlerResetTimer(); |
||||
}; |
||||
}, []); |
||||
|
||||
// 타이머 및 인증번호 관련 값 초기화
|
||||
const handlerResetTimer = () => { |
||||
clearInterval(timer); |
||||
dispatch(resetTimer()); |
||||
}; |
||||
|
||||
// 단순 메시지 표출 모달
|
||||
const handlerOpenModal = (header, body) => { |
||||
dispatch( |
||||
openModal({ |
||||
header: header, |
||||
body: body |
||||
}) |
||||
); |
||||
}; |
||||
|
||||
// 타이머 셋팅
|
||||
const handlerTimer = count => { |
||||
let minutes, seconds; |
||||
|
||||
// 타이머 동작
|
||||
const timer = setInterval(() => { |
||||
dispatch(isStartTimer(true)); |
||||
minutes = parseInt(count / 60, 10); |
||||
seconds = parseInt(count % 60, 10); |
||||
minutes = minutes < 10 ? '0' + minutes : minutes; |
||||
seconds = seconds < 10 ? '0' + seconds : seconds; |
||||
dispatch( |
||||
setCounter({ |
||||
min: minutes, |
||||
sec: seconds |
||||
}) |
||||
); |
||||
|
||||
// 타이머 종료
|
||||
if (--count < 0) { |
||||
clearInterval(timer); |
||||
dispatch(isStartTimer(false)); |
||||
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.expire); |
||||
} |
||||
}, 1000); |
||||
|
||||
setTimer(timer); |
||||
|
||||
return () => { |
||||
handlerResetTimer(); |
||||
}; |
||||
}; |
||||
|
||||
// 타이머 시작
|
||||
const handlerStart = () => { |
||||
if (isRunning) { |
||||
clearInterval(timer); |
||||
} |
||||
|
||||
dispatch(isStartTimer(true)); |
||||
dispatch(isSendCrtfyhp(false)); |
||||
dispatch(setSendCount()); |
||||
handlerTimer(180); |
||||
}; |
||||
|
||||
// 인증번호 전송
|
||||
const handlerSendCrtfyhp = async rq => { |
||||
if (handlerValidCheck) handlerValidCheck(); |
||||
|
||||
// 휴대폰 번호 유효성검사
|
||||
if (!rq.hpno || rq.hpno === '') { |
||||
handlerOpenModal( |
||||
MODAL_HEADER.crtfyhp, |
||||
'휴대폰 번호를' + MODAL_BODY.valid |
||||
); |
||||
return; |
||||
} |
||||
|
||||
// 휴대폰 번호 길이 유효성검사
|
||||
if (rq.hpno.length < 11) { |
||||
handlerOpenModal( |
||||
MODAL_HEADER.crtfyhp, |
||||
'올바른 번호를' + MODAL_BODY.valid |
||||
); |
||||
return; |
||||
} |
||||
|
||||
// 인증번호 전송 횟수 제한
|
||||
if (sendCount >= 3) { |
||||
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.count); |
||||
return; |
||||
} |
||||
|
||||
let request; |
||||
if (type) { |
||||
request = rq.hpno; |
||||
} else { |
||||
request = rq; |
||||
} |
||||
|
||||
// 인증번호 전송
|
||||
const { payload: data } = await dispatch(sendCrtfyhp(request)); |
||||
if (!data.result) { |
||||
if (data.code === -1) { |
||||
handlerOpenModal(MODAL_HEADER.crtfyhp, modalMesssage); |
||||
} else { |
||||
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.failed); |
||||
} |
||||
return; |
||||
} else { |
||||
handlerOpenModal(MODAL_HEADER.crtfyhp, MODAL_CRTFYHP.send); |
||||
handlerStart(); |
||||
} |
||||
}; |
||||
|
||||
useImperativeHandle(ref, () => ({ |
||||
handlerSendCrtfyhp |
||||
})); |
||||
|
||||
return null; |
||||
} |
||||
); |
@ -0,0 +1,65 @@
|
||||
import { CrtfyhpHook } from '@src/components/account/CrtfyhpHook'; |
||||
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'; |
||||
|
||||
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 ( |
||||
<> |
||||
<Row className='input-inline-btn'> |
||||
<Col md='8'> |
||||
<Label className='form-label' for='hpno'> |
||||
휴대폰 번호 |
||||
</Label> |
||||
<Input |
||||
type='number' |
||||
name='hpno' |
||||
id='hpno' |
||||
bsSize='sm' |
||||
value={hpno} |
||||
onChange={handlerChange} |
||||
placeholder='01012345678' |
||||
/> |
||||
</Col> |
||||
<Col md='4' xs='12'> |
||||
<span className={!isRunning || isCrtfyhp ? 'time d-none' : 'time'}> |
||||
남은시간 {counter.min}:{counter.sec} |
||||
</span> |
||||
<Button |
||||
type='button' |
||||
color='secondary' |
||||
onClick={() => hookRef?.current?.handlerSendCrtfyhp({ hpno })} |
||||
> |
||||
<span className='d-sm-inline-block'>인증번호 발송</span> |
||||
</Button> |
||||
</Col> |
||||
</Row> |
||||
<CrtfyhpHook |
||||
ref={hookRef} |
||||
sendCrtfyhp={sendCrtfyhp} |
||||
rq={{ hpno }} |
||||
modalMesssage='이미 가입된 어쩌구 입니다.' |
||||
type='1' |
||||
/> |
||||
</> |
||||
); |
||||
}; |
Loading…
Reference in new issue