Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 차집합
- slice()
- toUpperCase()
- substring()
- 교집합
- reat if문
- Math.floor()
- includes()
- useRef()
- 3진수
- Eventlitener
- useEffect()
- Number()
- useState()
- map()
- parseInt()
- React
- 소수점 올림내림
- getday()
- sort()
- filter()
- 항해99솔직후기 #항해99장점 #항해99단점 #부트캠프추천
- new Date()
- indexOf()
- Math.sqrt()
- isNaN()
- jsx반복문
- charAt()
- repeat()
- setDate
Archives
- Today
- Total
개발자로 전향중
react hook form 사용 예시 and 자동 전화번호 하이픈 본문
import React, { useState, useEffect, useRef } from "react";
import styled from "styled-components";
import { useForm, SubmitHandler } from "react-hook-form";
import PreReservationBtn from "../../public/images/web/Main/Button_booking.svg";
import PreReservationBtnhover from "../../public/images/web/Main/Button_booking_mouseover.svg";
import MLogo from "../../public/images/web/Main/Logo_Fatalbomb.svg";
import ButtonClose from "../../public/images/web/Main/Button_Close_Mobile.svg";
import Image from "next/image";
import ModalBackImg from "../../public/images/web/Main/Pc_BookingPopup_Background.png";
import MobileModalBackImg from "../../public/images/web/Main/Mobile_Booking_Background.png"
//Mobile layout
import { SCREEN_SIZE } from "../../constants/screenSize";
import { getValue } from "@mui/system";
interface modalprops {
premodalhover: boolean;
prereserve: boolean;
Setpremodalhover: React.Dispatch<React.SetStateAction<boolean>>;
Setprereserve: React.Dispatch<React.SetStateAction<boolean>>;
mobileResize: number;
}
export interface IFormInput {
nickname: string;
phonenumber: string;
}
const PreModal = ({
premodalhover,
prereserve,
Setpremodalhover,
Setprereserve,
mobileResize
}: modalprops) => {
const {
register,
handleSubmit,
formState: { errors },
setValue,
watch
} = useForm<IFormInput>();
const ismodalhover = () => {
Setpremodalhover(!premodalhover);
};
const isprebooking = () => {
Setprereserve(!prereserve);
};
const onSubmitHandler: SubmitHandler<IFormInput> = (data) => {
console.log(data)
}
const [hyphen, setHyphen] = useState<string>("")
const watchAllFields = watch("phonenumber");
useEffect(() => {
if (watchAllFields && watchAllFields.length === 11) {
setHyphen(watch("phonenumber").replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3'))
setTimeout(() => { setValue("phonenumber", hyphen); }, 0.00001);
}
}, [hyphen, watchAllFields]);
return (
<PreModalWrapper>
<PreModalUi>
<PreModalUiInner>
<ModalClose onClick={() => { isprebooking() }}>
{mobileResize <= 480 ?
<Image src={ButtonClose}
alt="모달닫기"
width={15}
height={15} /> :
<Image src={ButtonClose}
alt="모달닫기"
width={25}
height={25} />}
</ModalClose>
<ModalLogo>
{mobileResize <= 480 ?
<Image src={MLogo}
alt="모달로고"
width={120}
height={50} /> :
<Image src={MLogo}
alt="모달로고"
width={150}
height={60} />}
</ModalLogo>
<UserInfo>
<form onSubmit={handleSubmit(onSubmitHandler)}>
<div className='userinfo--text'>
휴대폰번호
<span className='userinfo--important'>
(필수)
</span>
</div>
<UserInfoPhone
type="text"
placeholder="-을 제외하고 입력해주세요"
{...register("phonenumber",
{
required: "핸드폰 번호를 입력해주세요.",
maxLength: {
value: 13,
message: "핸드폰의 정보가 정확하지 않습니다."
},
minLength: {
value: 13,
message: "핸드폰의 정보가 정확하지 않습니다."
}
})}
/>
<Alert>{ watchAllFields && watchAllFields.length === 13 ? "" : errors.phonenumber?.message}</Alert>
<div className='userinfo--text'>
닉네임
<span className='userinfo--important'>
(필수)
</span>
</div>
<UserInfoNick
type="text"
placeholder="2-10글자 이내로 입력해주세요"
{...register("nickname",
{
required: "닉네임을 입력해주세요",
pattern: {
value : /^[\w\Wㄱ-ㅎㅏ-ㅣ가-힣]{2,10}$/,
message : "닉네임의 이름이 정확하지 않습니다."
},
maxLength: {
value: 10,
message: "닉네임의 이름이 정확하지 않습니다."
}
})}
/>
<Alert>{errors.nickname?.message}</Alert>
<DuplicatedBtnWrapper>
<DuplicatedBtn type="submit">
중복확인
</DuplicatedBtn>
</DuplicatedBtnWrapper>
</form>
<Agreepersnal>
<input type="checkbox" className='modalcheckbox' />
<div className='persoanlcheck'>
개인정보 수집 및 이용 동의
<span className='personalimportant'>
(필수)
</span>
</div>
</Agreepersnal>
<div className='personal'>
Ⅰ. 개인정보의 수집 및 이용 동의서
- 이용자가 제공한 모든 정보는 다음의 목적을 위해 활용하며, 하기 목적 이외의 용도로는 사용되지 않습니다.
① 개인정보 수집 항목 및 수집·이용 목적
가) 수집 항목 (필수항목)
- 성명(국문), 주민등록번호, 주소, 전화번호(자택, 휴대전화), 사진, 이메일, 나이, 재학정보, 병역사항,
외국어 점수, 가족관계, 재산정도, 수상내역, 사회활동, 타 장학금 수혜현황, 요식업 종사 현황 등 지원
신청서에 기재된 정보 또는 신청자가 제공한 정보
나) 수집 및 이용 목적
- 하이트진로 장학생 선발 전형 진행
- 하이트진로 장학생과의 연락 및 자격확인
- 하이트진로 장학생 자원관리
② 개인정보 보유 및 이용기간
- 수집·이용 동의일로부터 개인정보의 수집·이용목적을 달성할 때까지
③ 동의거부관리
- 귀하께서는 본 안내에 따른 개인정보 수집, 이용에 대하여 동의를 거부하실 권리가 있습니다. 다만,
귀하가 개인정보의 수집/이용에 동의를 거부하시는 경우에 장학생 선발 과정에 있어 불이익이 발생할 수
있음을 알려드립니다.
</div>
</UserInfo>
{mobileResize <= 480 ?
<div className="prebutton" onMouseEnter={ismodalhover} onMouseLeave={ismodalhover}>
{premodalhover ?
<Image src={PreReservationBtnhover}
alt="모달사전예약호바"
width={177}
height={51} /> :
<Image src={PreReservationBtn}
alt="모달사전예약"
width={177}
height={51} />}
</div> :
<div className="prebutton" onMouseEnter={ismodalhover} onMouseLeave={ismodalhover}>
{premodalhover ?
<Image src={PreReservationBtnhover}
alt="모달사전예약호바"
width={220}
height={63} /> :
<Image src={PreReservationBtn}
alt="모달사전예약"
width={220}
height={63} />}
</div>}
</PreModalUiInner>
{mobileResize <= 480 ?
<Image src={MobileModalBackImg}
layout="fill"
width={375}
height={812}
/> :
<Image src={ModalBackImg}
layout="fill"
width={1358}
height={888}
/>}
</PreModalUi>
</PreModalWrapper>
);
};
const PreModalWrapper = styled.div`
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
width: 100%;
height: 100%;
z-index: 20;
`
const PreModalUi = styled.div`
position: relative;
width: 70%;
margin-top: 50px;
margin-right: auto;
margin-left: auto;
height: 90vh;
z-index: 100;
opacity: 1;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
width: 100%;
height: 100%;
margin-top: 0px;
}
.personal {
width: 100%;
height: 228px;
margin-top: 12px;
background: #FFFFFF33 0% 0% no-repeat padding-box;
border: 2px solid #FFFFFFB3;
border-radius: 2px;
opacity: 1;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
overflow:auto;
color:white;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
height: 30vh;
}
}
.prebutton {
width: 220px;
cursor:pointer;
margin-top: 30px;
margin-left: auto;
margin-right: auto;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
width: 177px;
height: 51px;
margin-top: 10px;
}
}
`
const PreModalUiInner = styled.div`
z-index: 1;
position: absolute;
width: 100%;
height:100%;
`;
const ModalClose = styled.div`
width: 100%;
display: flex;
justify-content: flex-end;
margin-top: 18px;
padding-right: 18px;
cursor: pointer;
`
const ModalLogo = styled.div`
width: 150px;
height: 50px;
margin: 30px auto 0px auto;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
width: 120px;
margin: 10px auto 20px auto;
}
`
const UserInfo = styled.div`
width: 70%;
margin-left: auto;
margin-right: auto;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
width: 85%;
}
.userinfo--text {
margin-top: 36px;
font: normal normal normal 18px NanumSquare_ac;
margin-left: 4px;
letter-spacing: 0px;
color: #FFFFFF;
opacity: 0.9;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
font: normal normal normal 15px NanumSquare_ac;
}
}
.userinfo--important {
font: normal normal normal 16px NanumSquare_ac;
letter-spacing: 0px;
color: #FFFFFF;
opacity: 0.7;
margin-left: 5px;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
font: normal normal normal 13px NanumSquare_ac;
}
}
`
const DuplicatedBtnWrapper = styled.div`
width: 100%;
display: flex;
justify-content: flex-end;
margin-top: 10px;
padding-right: 10px;
`
const DuplicatedBtn = styled.button`
background: #FFFFFF33 0% 0% no-repeat padding-box;
border: 1px solid #FFFFFFB3;
border-radius: 2px;
opacity: 0.9;
color: #FFFFFF;
display: inline-block;
cursor: pointer;
padding: 6px 12px 6px 12px;
:hover {
background: #FFFFFF66 0% 0% no-repeat padding-box;
border: 1px solid #FFFFFF;
border-radius: 2px;
opacity: 1;
}
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
padding: 3px 6px 3px 6px;
font-size: 12px;
}
`
const Alert = styled.div`
font: normal normal normal 12px NanumSquare_ac;
margin-top: 2px;
margin-left: 4px;
letter-spacing: 0px;
color: #FF4040;
opacity: 0.8;
`;
const UserInfoPhone = styled.input`
width: 100%;
height: 42px;
margin-top: 10px;
background: #FFFFFF33 0% 0% no-repeat padding-box;
border: 1.5px solid #FFFFFFB3;
border-radius: 2px;
opacity: 1;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
color: white;
padding-left: 10px;
font-size: 15px;
:focus {
outline: none;
}
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
height: 32px;
}
`
const UserInfoNick = styled.input`
width: 100%;
height: 42px;
margin-top: 10px;
background: #FFFFFF33 0% 0% no-repeat padding-box;
border: 1.5px solid #FFFFFFB3;
border-radius: 2px;
opacity: 1;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
color: white;
padding-left: 10px;
font-size: 15px;
:focus {
outline: none;
}
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
height: 32px;
}
`
const Agreepersnal = styled.div`
margin-top: 34px;
display: flex;
align-items: center;
height: 32px;
width: 100%;
.modalcheckbox {
width: 20px;
height: 20px;
background: #FFFFFF4D 0% 0% no-repeat padding-box;
border: 2px solid #FFFFFFB3;
border-radius: 2px;
opacity: 1;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
width: 16px;
height: 16px;
}
}
.persoanlcheck {
text-align: left;
margin-left: 5px;
margin-bottom: 2px;
font: normal normal normal 18px NanumSquare_ac;
letter-spacing: 0px;
color: white;
opacity: 1;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
font: normal normal normal 15px NanumSquare_ac;
margin-bottom: 1px;
}
}
.personalimportant {
margin-left: 5px;
text-align: left;
font: normal normal normal 16px NanumSquare_ac;
letter-spacing: 0px;
color: #FFFFFF;
opacity: 0.7;
@media screen and (max-width: ${SCREEN_SIZE.WIDTH.MOBILE}) {
font: normal normal normal 13px NanumSquare_ac;
}
}
`
export default PreModal;
'React' 카테고리의 다른 글
React 체크박스 여러개 체크할 때 체크 value (0) | 2022.11.02 |
---|---|
react 표 만들고 싶을 때 참고 (0) | 2022.10.26 |
UseCountup 자동으로 숫자올라가기 (0) | 2022.10.06 |
Swiper react/typescript 화살표 커스텀 및 slider 인덱스 (0) | 2022.09.14 |
ReactElement vs ReactNode vs JSX.Element (0) | 2022.09.05 |