diff --git a/src/components/PhoneCheck.tsx b/src/components/PhoneCheck.tsx new file mode 100644 index 0000000..2433afb --- /dev/null +++ b/src/components/PhoneCheck.tsx @@ -0,0 +1,130 @@ +import React, { useState, useEffect } from "react"; +import { sendSMSAPI, checkSMSAPI } from '@/apis/sms'; +import Container from '@/styles/PhoneCheck'; + + +interface PhoneCheckProps { + setCheck : (value: boolean) => void; + tel : string; + setTel : (value : string) => void; +} + +const PhoneCheck : React.FC = ({setCheck, tel, setTel}) => { + const [certifyNum, setCertifyNum] = useState(''); + const [token, setToken] = useState(''); + + const [time, setTime] = useState(5 * 60); // 초 단위 + + const [isCheck, SetIsCheck] = useState(false); + const [isSend, setIsSend] = useState(false); + const [isCertify, setIsCertify] = useState(false); + const [isTel, setIsTel] = useState(false); + const [isTimer, setIsTimer] = useState(false); + const [isSuccess, setIsSuccess] = useState(false); + + useEffect(() => { + if (isTimer) { + const intervalId = setInterval(() => { + setTime(prevTime => { + if (prevTime <= 1) { + clearInterval(intervalId); + setIsTimer(false); + return 0; + } else { + return prevTime - 1; + } + }); + }, 1000); + + return () => clearInterval(intervalId); + } + }, [isTimer]); + + const onChangeCertifyInput = (e : React.ChangeEvent) => { + const certifyRegex = /^\d{7}$/; + setCertifyNum(e.target.value); + if(certifyRegex.test(e.target.value)){ + setIsCertify(true); + } else { + setIsCertify(false); + } + } + const onChangeTel = (e: React.ChangeEvent) => { + const telRegex = /^01(?:0|1|[6-9])(?:\d{3}|\d{4})\d{4}$/; + const telCurrent = e.target.value; + setTel(telCurrent); + + if (!telRegex.test(telCurrent)) { + setIsTel(false); + } else { + setIsTel(true); + } + } + + const handleCheckCertify = async () => { + setIsTimer(false); + SetIsCheck(true); + const response = (await checkSMSAPI({ + verification_code : Number(certifyNum), + }, token)) + if(response.data.success){ + setIsSuccess(true); + setCheck(true); + } else { + setIsSuccess(false); + } + } + + const handleCertifyNum = async () => { + setIsSend(true) + setIsTimer(true); + if(isSend){ + SetIsCheck(false); + setTime(10); + } + const response = (await sendSMSAPI({ + phone_number : tel + })) + + if(response.data.success){ + setToken(response.data.result.token); + } + } + + const minutes = Math.floor(time / 60); // 분 + const seconds = time % 60; + + return( + +
전화번호
+
+ + +
+ {isSend ?
+ onChangeCertifyInput(e)} + style={{width : '326px'}} + readOnly={isSuccess}/> + +
: ''} + {isSend && (isCheck === false) && 인증번호가 발송되었어요 (유효시간 {minutes}:{seconds})} + {isCheck === true && {isSuccess ? '인증되었습니다' : '인증번호를 다시 확인해주세요'}} +
+ ); +} + +export default PhoneCheck; diff --git a/src/styles/PhoneCheck.ts b/src/styles/PhoneCheck.ts new file mode 100644 index 0000000..f9bf679 --- /dev/null +++ b/src/styles/PhoneCheck.ts @@ -0,0 +1,58 @@ +import styled from "styled-components"; +import theme from "./theme"; + +const Cotainer = styled.div` + width : 494px; + display : flex; + flex-direction : column; + gap : 5px; + & div.label { + color : ${theme.color.gray400}; + ${theme.typography.Body1}; + } + & input { + width : 326px; + height : 56px; + padding: 0px 0px 0px 20px; + border : 1.5px solid ${theme.color.gray200}; + border-radius : 12px; + outline : none; + color : ${theme.color.gray500}; + ${theme.typography.Body1}; + &:focus { + border: 1.5px solid ${theme.color.gray500}; + }; + &:hover { + border: 1.5px solid ${theme.color.gray500}; + } + &::placeholder { + color : ${theme.color.gray300}; + } + } + & button { + width : 160px; + height : 56px; + background-color : ${theme.color.green400}; + color : ${theme.color.gray500}; + border : none; + border-radius : 12px; + ${theme.typography.Body1}; + &:disabled { + background-color : ${theme.color.gray100}; + color : ${theme.color.gray300}; + } + } + & div.inputwrap { + display : flex; + gap : 10px; + } + & span.msg { + margin-left : 10px; + ${theme.typography.Body3}; + color : ${theme.color.red}; + } +`; + + + +export default Cotainer; \ No newline at end of file