From 06543dff454530f74e464d79916d900789bda378 Mon Sep 17 00:00:00 2001 From: hojin Date: Sat, 11 May 2024 22:17:43 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20sign1=EB=B8=8C=EB=9E=9C=EC=B9=98=20sign?= =?UTF-8?q?2=EB=B8=8C=EB=9E=9C=EC=B9=98=20=ED=86=B5=ED=95=A9=20=EB=B0=8F?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기능완성 --- public/sign/positionCircle.png | Bin 0 -> 504 bytes public/sign/positionClose.png | Bin 0 -> 264 bytes public/sign/positionColorCircle.png | Bin 0 -> 531 bytes src/api/auth/auth.post.api.ts | 6 +- src/components/shared/sign/ToBack.tsx | 2 +- src/components/signup/EmailVerification.tsx | 370 +++++++------- src/components/signup/JobPosition.tsx | 42 +- src/components/signup/JobPositionItem.tsx | 18 +- .../signup/PasswordVerification.tsx | 474 +++++++++--------- src/components/signup/PhoneCertification.tsx | 10 +- src/components/signup/Terms.tsx | 38 +- src/components/signup/terms/TermsItem.tsx | 2 +- src/components/signup/terms/TermsModal.tsx | 7 +- src/constant/temrs.ts | 2 +- src/models/applyValues.ts | 5 + src/models/jobPosition.ts | 18 + src/pages/signup/index.tsx | 57 ++- tsconfig.json | 3 +- 18 files changed, 581 insertions(+), 473 deletions(-) create mode 100644 public/sign/positionCircle.png create mode 100644 public/sign/positionClose.png create mode 100644 public/sign/positionColorCircle.png create mode 100644 src/models/applyValues.ts create mode 100644 src/models/jobPosition.ts diff --git a/public/sign/positionCircle.png b/public/sign/positionCircle.png new file mode 100644 index 0000000000000000000000000000000000000000..628452d31f85235a76789611203a6d1ace46be53 GIT binary patch literal 504 zcmV$EJq=UROK+a)SCmQ02cxGT> zf4;rDd(SFqkmq?1y%6K-Lg-v7Cd4=!$!?G+l7?>7C5uqw^ zT{klm5#GmS15SiK%X9DvaJ^o8=t$rgkVGyBa7$~w#S>1a)8!u^B3l4N*b89aa)r1x zgd)-ek-DtYCNc*grwxo^Uyk9b03RMBT&-502A0VU0?bCF?_fMCM#mZE^Z8IZ2%Ig7 zm`fgj{2|>HAuwCxW#K24jzWqhD4w`~mE1{WX}Plq%$TIoQN~57ro~_-TRI910>2pH z4$nxstIigU(+O#GCa2seZW$RcMyQQ_#>n&yy(ukq@G}_o1yP?epiJzT4Q-&mU=gD` z0x4MU6%B;$uQ_$xPW0~{V|IYO9qLuXtPVOZc>0VQrqBw)ejWwH0+GI0W zxz8M$mprX5pZ6S7Si&3U%mpTF;bqfvelUI$+Z0=*>YKnFb;kLIz>Nkb4y^`<$p1^$ z{L)yJx;W~_s(AmcmTwNY1>9=gXtC|xa{omA!&U)17=y(HI|3VdJ^&rc;OXk;vd$@? F2>?owSkeFh literal 0 HcmV?d00001 diff --git a/public/sign/positionColorCircle.png b/public/sign/positionColorCircle.png new file mode 100644 index 0000000000000000000000000000000000000000..39e8cfb5fcf5ac79a891e28f4a6cee5c48782c98 GIT binary patch literal 531 zcmV+u0_^>XP)>q~ zgc5h$1tdIfF+6_F?at1AyEi*C1Q!BZFY`aOMo17gnQ0ARySYFp5m1)QciG~8+HEiO z8+_{z0b)-|iOgdtRA$I{zp&_@_`SIVvAF$TOv5&TQfg1sRnYIv>xBqLC+6SCCH^MO zU-o$)L;5sK023W&3wsW=Zuj)j3HY25v6j4T_#s0mhn1aOZGgz~(<$gc-I4ri{=T zZ(7V;e+}63*^0>>q)O8w;*xq4+s#48YIe@Tu5Y1pfH8gwmhzJV-dsci2}}X?AYlP% zrBxnQF(CvlJE~C#r?g!qqA(^zT`CT=n}efjP??e#8yR=nZLFsss#X+JpD0FxlbPav zr0b@=1XOLS>WMPQ9wwvXP9(!l;lSy$yVDdVaip`KJJm#GoomGW3RzD(rQ?Ce`~|Xu Vm_DX`;J*L>002ovPDHLkV1i2v-l6~i literal 0 HcmV?d00001 diff --git a/src/api/auth/auth.post.api.ts b/src/api/auth/auth.post.api.ts index 88073cc..d760cd2 100644 --- a/src/api/auth/auth.post.api.ts +++ b/src/api/auth/auth.post.api.ts @@ -1,5 +1,5 @@ // import { ICommon } from '../types/common'; -import { basicResponse } from '@/models/response'; +import { basicResponse } from '../../models/response'; import { postRequest } from '../request'; import { ISignIn, @@ -71,7 +71,7 @@ export const emailauthverify = async ({ emailAddress, code }: IEmailAuth) => { /* 휴대전화 번호 인증 요청*/ export const phoneauthrequest = async ({ phoneNumber }: IPhoneNumber) => { - const response = await postRequest('/auth/phone', { + const response = await postRequest(`auth/phone`, { phoneNumber }); @@ -81,7 +81,7 @@ export const phoneauthrequest = async ({ phoneNumber }: IPhoneNumber) => { /* 휴대전화 번호 코드 검증*/ export const phoneauthverify = async ({ phoneNumber, code }: IPhoneAuth) => { - const response = await postRequest('/auth/phone/verify', { + const response = await postRequest(`auth/phone/verify`, { phoneNumber, code }); diff --git a/src/components/shared/sign/ToBack.tsx b/src/components/shared/sign/ToBack.tsx index d692e8b..6a8da40 100644 --- a/src/components/shared/sign/ToBack.tsx +++ b/src/components/shared/sign/ToBack.tsx @@ -4,7 +4,7 @@ import { IoIosArrowRoundBack } from 'react-icons/io'; const ToBack = () => { return ( -
+
diff --git a/src/components/signup/EmailVerification.tsx b/src/components/signup/EmailVerification.tsx index af9fd5b..fade2eb 100644 --- a/src/components/signup/EmailVerification.tsx +++ b/src/components/signup/EmailVerification.tsx @@ -3,11 +3,15 @@ import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; import ToBack from '../shared/sign/ToBack'; import { useMutation } from 'react-query'; import { motion } from 'framer-motion'; -import { emailauthrequest, emailauthverify } from 'src/api/auth/auth.post.api'; import Image from 'next/image'; -import PasswordVerification from './PasswordVerification'; +import { emailauthrequest, emailauthverify } from '../../api/auth/auth.post.api'; +import { ApplyValues } from '@/models/applyValues'; -const EmailVerification = () => { +interface EmailVerification { + onNext: (name: ApplyValues['memberName'], email: ApplyValues['memberEmail']) => void; +} + +const EmailVerification = ({ onNext }: EmailVerification) => { const [userName, setUserName] = useState(''); const [userEmail, setUserEmail] = useState(''); const [emailValid, setEmailValid] = useState(false); @@ -19,7 +23,6 @@ const EmailVerification = () => { const [isInvalidCode, setIsInvalidCode] = useState(false); const [isPartnerShip, setIsPartnerShip] = useState(false); const [timerExpired, setTimerExpired] = useState(false); - const [isEmailConfirmed, setIsEmailConfirmed] = useState(false); const { mutateAsync: emailRequest } = useMutation((email: string) => { return emailauthrequest({ emailAddress: email }); @@ -47,32 +50,32 @@ const EmailVerification = () => { const handleValidNumberChange = async (e: ChangeEvent) => { const regex = e.target.value.replace(/[^0-9]/g, ''); setValidNumber(regex); - + if (regex.length === 6) { try { const { status } = (await emailVerify({ emailAddress: userEmail, - code: Number(regex) + code: Number(regex) })) as unknown as { status: string }; - + if (status === 'SUCCESS') { console.log('인증 성공'); console.log(status); - setIsEmailConfirmed(true); + onNext(userName, userEmail); } } catch (error: any) { console.error(error); const errorResponse = error.response.data; const errorCode = errorResponse.errorCode; console.log('인증 실패 - 에러 코드:', errorCode); - + if (errorCode === '1-005') { setIsInvalidCode(true); } } } }; - + const handleRetryClick = async () => { try { await emailRequest(userEmail); @@ -117,194 +120,197 @@ const EmailVerification = () => { return (
- {!isEmailConfirmed && ( - <> - - -
- 제휴 기업이라면,
- 사내 이메일을 인증해주세요. + + +
+ 제휴 기업이라면, +
+ 사내 이메일을 인증해주세요. +
+
+ +
+
+ +
+
+
+
+ +
+
+
+ + +
+
+
+ +
- - -
+ {userEmail && !emailValid && ( +
+ *이메일 형식에 맞지 않습니다. +
+ )} + {isPartnerShip && !timerExpired && ( +
+ 계약되지 않은 회사입니다. +
+ )} +
+
+
+ +
+
+ +
+
+
+
+ ExclamationMark Logo +
+ 본인 인증, 예약 확인, 약관 변경 안내 등을 위해 사용됩니다. +
+ 사내 이메일로 정확하게 입력해주세요. +
+
+ + {showVerification && ( + +
+
-
-
- + {isInvalidCode && !timerExpired && ( +
+ 올바르지 않은 코드입니다.
-
-
- - -
-
-
- -
+ )} + {timerExpired && ( +
+ 인증 시간이 초과되었습니다.
- {userEmail && !emailValid && ( -
- *이메일 형식에 맞지 않습니다. -
- )} - {isPartnerShip && !timerExpired && ( -
- 계약되지 않은 회사입니다. -
- )} + )} +
+
+
+
-
-
- -
-
- -
+
+ {Math.floor(validTime / 60)}: + {validTime % 60 < 10 ? `0${validTime % 60}` : validTime % 60}
-
- ExclamationMark Logo -
본인 인증, 예약 확인, 약관 변경 안내 등을 위해 사용됩니다.
사내 이메일로 정확하게 입력해주세요.
+
+
+ ExclamationMark Logo +
+ 이메일로 발송된 코드를 입력해주세요.
- - {showVerification && ( - -
-
-
- -
-
- {isInvalidCode && !timerExpired && ( -
- 올바르지 않은 코드입니다. -
- )} - {timerExpired && ( -
- 인증 시간이 초과되었습니다. -
- )} -
-
-
- -
-
- {Math.floor(validTime / 60)}:{validTime % 60 < 10 ? `0${validTime % 60}` : validTime % 60} -
-
-
-
- ExclamationMark Logo -
이메일로 발송된 코드를 입력해주세요.
-
- - )} - - )} - {isEmailConfirmed && ( - +
+
)}
); }; export default EmailVerification; - diff --git a/src/components/signup/JobPosition.tsx b/src/components/signup/JobPosition.tsx index 29affa6..c918238 100644 --- a/src/components/signup/JobPosition.tsx +++ b/src/components/signup/JobPosition.tsx @@ -1,33 +1,51 @@ -import React, { useState } from 'react'; +import React, { Dispatch, useEffect, useState } from 'react'; import JobPositionItem from './JobPositionItem'; import { jobPosition as allPostion } from '@/constant/jobPosition'; import { motion } from 'framer-motion'; +import { createPortal } from 'react-dom'; -const JobPosition = () => { - //todo : 이미 선택된 직무를 다시 변경 할 수 있으니까 초기 직무선택값을 받아야함 +interface JobPositionProps { + setJobModal: Dispatch>; + setSelectedJob: Dispatch>; + selectedJob: string; +} + +const JobPosition = ({ setJobModal, setSelectedJob, selectedJob }: JobPositionProps) => { + useEffect(() => { + window.scrollTo(0, 0); + }, []); // eslint-disable-next-line @typescript-eslint/no-unused-vars const [selectPosition, setSelectPosition] = useState(null); + const [initialPosition, setInitialPosition] = useState(selectedJob); + + const $portalRoot = document.getElementById('root-portal'); + + if ($portalRoot == null) { + return null; + } const handleClick = (title: string) => { + setInitialPosition(''); setSelectPosition(title); }; const handleSubmit = () => { - //todo : 선택한 직무 넘기기 const res = allPostion?.find((item) => item.title === selectPosition); - console.log(res?.description); - alert('클릭'); + if (res) { + setSelectedJob(res?.title); + setJobModal(false); + } }; - return ( -
-
+ return createPortal( +
+
직무선택
{ - //todo : 모달 닫기 + setJobModal(false); }} className="w-[18px] h-[18px] absolute top-[25px] right-[16px] cursor-pointer"> @@ -51,6 +69,7 @@ const JobPosition = () => { title={position.title} handleClick={handleClick} selectPosition={selectPosition} + initialPosition={initialPosition} /> ))} @@ -72,7 +91,8 @@ const JobPosition = () => {
)} -
+
, + $portalRoot ); }; diff --git a/src/components/signup/JobPositionItem.tsx b/src/components/signup/JobPositionItem.tsx index 0345bca..4e1bdec 100644 --- a/src/components/signup/JobPositionItem.tsx +++ b/src/components/signup/JobPositionItem.tsx @@ -1,16 +1,28 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; interface JobPositionItemProps { title: string; handleClick: (title: string) => void; selectPosition: string | null; + initialPosition: string | undefined; } const JobPositionItem = ({ title, handleClick, - selectPosition + selectPosition, + initialPosition }: JobPositionItemProps) => { + const [isInitSelect, setIsInitSelect] = useState(false); + + useEffect(() => { + if (initialPosition === title) { + setIsInitSelect(true); + } else { + setIsInitSelect(false); + } + }, [initialPosition]); + return (
handleClick(title)}>
@@ -18,7 +30,7 @@ const JobPositionItem = ({ {title}
- {title == selectPosition ? ( + {title == selectPosition || isInitSelect ? ( { - const [password, setPassword] = useState(''); - const [passwordError, setPasswordError] = useState(''); - const [showJobPosition, setShowJobPosition] = useState(false); +const JobPosition = dynamic(() => import('./JobPosition'), { + ssr: false +}); - const handlePasswordChange = (e: React.ChangeEvent) => { - const newPassword = e.target.value; - setPassword(newPassword); - validatePassword(newPassword); - }; +interface PasswordVerificationProps { + onNext: ( + password: ApplyValues['memberPassword'], + job: ApplyValues['memberJob'], + smsAgree: ApplyValues['memberSmsAgree'] + ) => void; + applyValues: Partial; +} - const validatePassword = (value: string) => { - const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,16}$/; - if (!regex.test(value)) { - setPasswordError('패스워드를 다시 정해주세요.'); - } else { - setPasswordError(''); - } - }; +const PasswordVerification = ({ onNext, applyValues }: PasswordVerificationProps) => { + const [password, setPassword] = useState(''); //유저 비밀번호 + const [passwordError, setPasswordError] = useState(false); - const handleJobPositionClick = () => { - setShowJobPosition(true); - }; + const [selectedJob, setSelectedJob] = useState(''); //유저 직무 + const [jobModal, setJobModal] = useState(false); //직무 모달 오픈 상태 + const [completedJob, setCompletedJob] = useState(''); + const [isSmsAgree, setIsSmsAgree] = useState(false); //sms 동의 체크여부 + const [isAllAgreeChecked, setIsAllAgreeChecked] = useState(false); //모두동의했는가 + + const [isAllDataValid, setIsAllDataValid] = useState(false); // 모두동의 job선택됨 비밀번호 통과 + + useEffect(() => { + if (isAllAgreeChecked && selectedJob != '' && !passwordError && password != '') { + setIsAllDataValid(true); + } else { + setIsAllDataValid(false); + } + }, [isAllAgreeChecked, selectedJob, passwordError, password]); + + useEffect(() => { + const result = jobPosition.find((job) => job.title === selectedJob); + if (result) { + setCompletedJob(result.description as SetStateAction); + } + }, [selectedJob]); + + const handlePasswordChange = (e: React.ChangeEvent) => { + setPasswordError(false); + const newPassword = e.target.value; + setPassword(newPassword); + }; + + const checkValidPassword = () => { + const passwordRegex = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,16}$/; + if (!passwordRegex.test(password)) { + setPasswordError(true); + } else { + setPasswordError(false); + } + }; + + const handleCompleteClick = () => { + onNext(password, completedJob, isSmsAgree); + }; + + if (jobModal) { return ( + + ); + } -
- {!showJobPosition && ( - <> -
- 회원가입을 위한
정보를 입력해주세요. -
-
-
-
- -
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
- -
-
-
-
- ExclamationMark Logo -
본인 인증, 예약 확인, 약관 변경 안내 등을 위해 사용됩니다.
사내 이메일로 정확하게 입력해주세요.
-
-
-
- -
- {passwordError && ( -
- {passwordError} -
- )} -
-
-
- -
-
-
-
- ExclamationMark Logo -
*영문 (대문자 포함), 숫자, 특수문자 중 2가지 이상 조합 8~16자리
-
-
-
- -
-
-
-
- -
- DropDown Logo -
-
- - )} - {showJobPosition && ( - - - - )} - -
- - - - - + return ( +
+ + +
+ 회원가입을 위한 +
+ 정보를 입력해주세요. +
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+
+ ExclamationMark Logo +
+ 본인 인증, 예약 확인, 약관 변경 안내 등을 위해 사용됩니다. +
+ 사내 이메일로 정확하게 입력해주세요. +
+
+
+
+ +
+ {passwordError && ( +
+ 비밀번호 형식을 확인해주세요.
- + )}
- ); +
+
+ +
+
+
+
+ ExclamationMark Logo +
+ *영문 (대문자 포함), 숫자, 특수문자 중 2가지 이상 조합 8~16자리 +
+
+
+
+ +
+
+
+
+ setJobModal(true)} + value={selectedJob == '' ? '' : selectedJob} + readOnly={selectedJob == ''} + /> +
+ DropDown Logo +
+
+ +
+ +
+
+ ); }; -export default PasswordVerification; \ No newline at end of file +export default PasswordVerification; diff --git a/src/components/signup/PhoneCertification.tsx b/src/components/signup/PhoneCertification.tsx index 71dc344..63f2c1e 100644 --- a/src/components/signup/PhoneCertification.tsx +++ b/src/components/signup/PhoneCertification.tsx @@ -5,8 +5,13 @@ import { motion } from 'framer-motion'; import { invertSecond } from '@/utils/invertSecond'; import { useMutation } from 'react-query'; import { phoneauthrequest, phoneauthverify } from '@/api/auth/auth.post.api'; +import { ApplyValues } from '@/models/applyValues'; -const PhoneCertification = () => { +interface PhoneCertificationProps { + onNext: (phoneNumber: ApplyValues['memberPhone']) => void; +} + +const PhoneCertification = ({ onNext }: PhoneCertificationProps) => { const [phoneNumber, setPhoneNumber] = useState(''); const [btnStatus, setBtnStatus] = useState('FIRST'); const [isRequest, setIsRequest] = useState(false); @@ -104,8 +109,7 @@ const PhoneCertification = () => { })) as { status: string }; if (status == 'SUCCESS') { - //todo 여기서 SUCCESS (휴대폰 인증 완료 ) 되면 이메일 인증으로 넘어가면 됩니다. - alert('성공'); + onNext(phoneNumber); } } }; diff --git a/src/components/signup/Terms.tsx b/src/components/signup/Terms.tsx index 5948884..ff83498 100644 --- a/src/components/signup/Terms.tsx +++ b/src/components/signup/Terms.tsx @@ -1,4 +1,4 @@ -import React, { MouseEvent, useState } from 'react'; +import React, { Dispatch, MouseEvent, useEffect, useState } from 'react'; import TermsTitle from './terms/TermsTitle'; import { 약관목록 } from '@constant/temrs'; import { TermsType } from '@/models/terms'; @@ -9,7 +9,12 @@ const TermsModal = dynamic(() => import('./terms/TermsModal'), { ssr: false }); -const Terms = () => { +interface TermsProps { + setIsSmsAgree: Dispatch>; + setIsAllAgreeChecked: Dispatch>; +} + +const Terms = ({ setIsSmsAgree, setIsAllAgreeChecked }: TermsProps) => { const [termsAgreements, setTermsAgreements] = useState(() => setInitialValues(약관목록) ); @@ -29,14 +34,29 @@ const Terms = () => { }); }; - const isAllRequireChecked = termsAgreements - .filter((term) => term.required) - .every((term) => term.checked); + const isAllTermsChecked = termsAgreements.every((term) => term.checked); - console.log(isAllRequireChecked); - //todo : isAllRequireChecked을 넘겨서 true 여야지만 회원가입 이뤄지게 (버튼 눌러지게) + useEffect(() => { + const isAllRequireChecked = termsAgreements + .filter((term) => term.required) + .every((term) => term.checked); + if (isAllRequireChecked) { + setIsAllAgreeChecked(true); + } else { + setIsAllAgreeChecked(false); + } + }, [termsAgreements]); - const isAllTermsChecked = termsAgreements.every((term) => term.checked); + useEffect(() => { + const isSmsChecked = termsAgreements + .filter((term) => term.required == false) + .every((term) => term.checked); + if (isSmsChecked) { + setIsSmsAgree(true); + } else { + setIsSmsAgree(false); + } + }, [termsAgreements]); if (openModal) { return ( @@ -49,7 +69,7 @@ const Terms = () => { } return ( -
+
    {termsAgreements.map((term) => ( diff --git a/src/components/signup/terms/TermsItem.tsx b/src/components/signup/terms/TermsItem.tsx index 8f59054..8be3306 100644 --- a/src/components/signup/terms/TermsItem.tsx +++ b/src/components/signup/terms/TermsItem.tsx @@ -28,7 +28,7 @@ const TermsItem = ({ }; return ( -
  • +
  • { onChange(e, !checked); diff --git a/src/components/signup/terms/TermsModal.tsx b/src/components/signup/terms/TermsModal.tsx index ebe0503..cc6915a 100644 --- a/src/components/signup/terms/TermsModal.tsx +++ b/src/components/signup/terms/TermsModal.tsx @@ -16,7 +16,6 @@ const TermsModal = ({ setOpenModal, modalSubTitle }: TermsModalProps) => { - console.log(modalDescription); const $portalRoot = document.getElementById('root-portal'); if ($portalRoot == null) { @@ -27,8 +26,8 @@ const TermsModal = ({ } return createPortal( - -
    +
    +
    {modalSubTitle}
    @@ -47,7 +46,7 @@ const TermsModal = ({ {modalDescription}
    - , +
    , $portalRoot ); }; diff --git a/src/constant/temrs.ts b/src/constant/temrs.ts index c6db19e..b1d79f2 100644 --- a/src/constant/temrs.ts +++ b/src/constant/temrs.ts @@ -25,7 +25,7 @@ export const 약관목록 = [ 3) 제1항, 제2항에도 불구하고, "Offispace"와 제휴 계약을 체결한 그룹에 속한 "멤버"에 한하여, 별도의 가입절차 없이, 서비스이용권한을 부여할 수 있으며, "Offispace”가 권한을 부여한 때로부터 "Offispace"와 이러한 "멤버" 사이에 "웹사이트 등"의 이용계약이 체결된 것으로 봅니다. 4) "멤버"는 "Offispace"에서 제공하는 "웹사이트 등" 에 게시된 이 약관에 따라 가입한 하나의 계정으로 모든 "웹사이트 등"에 로그인하여 이용할 수 있습니다. -##### 상기 본인은 위와 같은 서비스 이용약관에 동의함.`, +#### 상기 본인은 위와 같이 서비스 이용약관에 동의함.`, required: true }, { diff --git a/src/models/applyValues.ts b/src/models/applyValues.ts new file mode 100644 index 0000000..b0201fe --- /dev/null +++ b/src/models/applyValues.ts @@ -0,0 +1,5 @@ +import { ISignUp } from '@/api/types/auth'; + +export interface ApplyValues extends ISignUp { + step: number; +} diff --git a/src/models/jobPosition.ts b/src/models/jobPosition.ts new file mode 100644 index 0000000..41981c9 --- /dev/null +++ b/src/models/jobPosition.ts @@ -0,0 +1,18 @@ +export type JobPositionType = + | '' + | 'OWNER' + | 'OFFICE' + | 'FINANCE' + | 'HRD' + | 'PROMOTION' + | 'ITDEV' + | 'ITPLAN' + | 'SALE' + | 'DESIGN' + | 'SERVICE' + | 'CONTENTS' + | 'RND' + | 'PROFESSIONAL' + | 'MD' + | 'INSURANCE' + | 'ETC'; diff --git a/src/pages/signup/index.tsx b/src/pages/signup/index.tsx index 1bfad50..1561384 100644 --- a/src/pages/signup/index.tsx +++ b/src/pages/signup/index.tsx @@ -1,15 +1,58 @@ import MainContainer from '@/components/shared/MainContainer'; -// import JobPosition from '@/components/signup/JobPosition'; -import Terms from '@/components/signup/Terms'; +import EmailVerification from '@/components/signup/EmailVerification'; +import PasswordVerification from '@/components/signup/PasswordVerification'; +import PhoneCertification from '@/components/signup/PhoneCertification'; +import { ApplyValues } from '@/models/applyValues'; +import { useState } from 'react'; const SignUpPage = () => { - // todo 단계별로 회원가입 이뤄지게 - // const [step, setStep] = useState(0); + const [applyValues, setApplyValues] = useState>({ + step: 0 + }); + + console.log(applyValues); + + const handlePhoneNumber = (phoneNumber: ApplyValues['memberPhone']) => { + setApplyValues((prev) => ({ + ...prev, + phoneNumber: phoneNumber, + step: (prev.step as number) + 1 + })); + }; + + const handleNameAndEmail = ( + name: ApplyValues['memberName'], + email: ApplyValues['memberEmail'] + ) => { + setApplyValues((prev) => ({ + ...prev, + memberName: name, + memberEmail: email, + step: (prev.step as number) + 1 + })); + }; + + const handleRemainData = ( + password: ApplyValues['memberPassword'], + job: ApplyValues['memberJob'], + smsAgree: ApplyValues['memberSmsAgree'] + ) => { + setApplyValues((prev) => ({ + ...prev, + memberPassword: password, + memberJob: job, + memberSmsAgree: smsAgree, + step: (prev.step as number) + 1 + })); + }; + return ( - {/* */} - {/* */} - + {applyValues.step === 0 ? : null} + {applyValues.step === 1 ? : null} + {applyValues.step === 2 ? ( + + ) : null} ); }; diff --git a/tsconfig.json b/tsconfig.json index 2072a32..90a994b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,8 @@ "@components/*": ["src/components/*"], "@types/*": ["src/types/*"], "@utils/*": ["src/utils/*"], - "@constant/*": ["src/constant/*"] + "@constant/*": ["src/constant/*"], + "@models/*": ["src/models/*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next.config.mjs"],