From 7aa87cb151a2a8282c83701e9cbf7a01f9606c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Sat, 20 Jan 2024 23:01:31 +0900 Subject: [PATCH 01/21] =?UTF-8?q?chore:=20react-hook-form=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 17 +++++++++++++++++ package.json | 1 + 2 files changed, 18 insertions(+) diff --git a/package-lock.json b/package-lock.json index d8fa7510..753608f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.12", + "react-hook-form": "^7.49.3", "react-router-dom": "^6.21.1", "recoil": "^0.7.7", "recoil-persist": "^5.1.0" @@ -6377,6 +6378,22 @@ "react": ">=16.13.1" } }, + "node_modules/react-hook-form": { + "version": "7.49.3", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.49.3.tgz", + "integrity": "sha512-foD6r3juidAT1cOZzpmD/gOKt7fRsDhXXZ0y28+Al1CHgX+AY1qIN9VSIIItXRq1dN68QrRwl1ORFlwjBaAqeQ==", + "engines": { + "node": ">=18", + "pnpm": "8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index de44ddf7..3977c4b9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.12", + "react-hook-form": "^7.49.3", "react-router-dom": "^6.21.1", "recoil": "^0.7.7", "recoil-persist": "^5.1.0" From a1af004d67166972a2f92174c89f153be3224556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 03:25:15 +0900 Subject: [PATCH 02/21] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20inp?= =?UTF-8?q?ut=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9C=A0=ED=9A=A8=EC=84=B1?= =?UTF-8?q?=20=EC=98=B5=EC=85=98=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/lib/login.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/utils/lib/login.ts diff --git a/src/utils/lib/login.ts b/src/utils/lib/login.ts new file mode 100644 index 00000000..b9b372eb --- /dev/null +++ b/src/utils/lib/login.ts @@ -0,0 +1,27 @@ +const emailRegex = + /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i; +const passwordRegex = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,20}$/g; + +export const fieldOptions = (fieldName: string) => { + switch (fieldName) { + case 'user_email': + return { + required: '이메일을 입력해주세요.', + pattern: { + value: emailRegex, + message: '이메일 형식에 맞게 입력해주세요.' + } + }; + case 'user_password': + return { + required: '비밀번호를 입력해주세요.', + minLength: 8, + maxLength: 20, + pattern: { + value: passwordRegex, + message: + '영문, 숫자, 특수문자를 포함한 8-20자의 비밀번호를 입력해주세요.' + } + }; + } +}; From aa8709b0f910daa9368dd4b8f77fab82cdac494f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= Date: Mon, 22 Jan 2024 03:45:01 +0900 Subject: [PATCH 03/21] =?UTF-8?q?feat:=20LoginForm=EC=97=90=20react-hook-f?= =?UTF-8?q?orm=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 김다빈 --- src/components/Login/LoginForm/index.tsx | 76 +++++++++++++----------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/src/components/Login/LoginForm/index.tsx b/src/components/Login/LoginForm/index.tsx index 02b6ceb2..49ee4401 100644 --- a/src/components/Login/LoginForm/index.tsx +++ b/src/components/Login/LoginForm/index.tsx @@ -1,5 +1,6 @@ import { useLocation, useNavigate } from 'react-router-dom'; import styled from '@emotion/styled'; +import { FormProvider, useForm } from 'react-hook-form'; import { InputValidation } from '@/types/login'; import { @@ -12,6 +13,7 @@ import { postLogin } from 'src/api'; import { setCookies } from '@utils/lib/cookies'; const LoginForm = () => { + const methods = useForm(); const navigate = useNavigate(); const { state } = useLocation(); @@ -47,42 +49,44 @@ const LoginForm = () => { }; return ( -
- - - - - {isInvalid && ( - - 아이디를 입력해 주세요 - - )} - - - - -
+ +
+ + + + + {isInvalid && ( + + 아이디를 입력해 주세요 + + )} + + + + +
+
); }; From cc4116fbd14129ac4a975e0bd4ab28beea84571e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 03:49:23 +0900 Subject: [PATCH 04/21] =?UTF-8?q?feat:=20AuthInputNormal=EC=97=90=20react-?= =?UTF-8?q?hook-form=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Auth/AuthInputNormal/index.tsx | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/common/Auth/AuthInputNormal/index.tsx index c0ee44c7..013e6689 100644 --- a/src/components/common/Auth/AuthInputNormal/index.tsx +++ b/src/components/common/Auth/AuthInputNormal/index.tsx @@ -1,10 +1,11 @@ -import { ChangeEvent, useState } from 'react'; import styled from '@emotion/styled'; +import { useFormContext } from 'react-hook-form'; import { AuthInputNormal } from '@/types/auth'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; +import { fieldOptions } from '@utils/lib/login'; const AuthInputNormal = ({ type, @@ -13,18 +14,9 @@ const AuthInputNormal = ({ usedFor, isInvalid }: AuthInputNormal) => { - const [text, setText] = useState(''); - - const handleChange = (event: ChangeEvent) => { - setText(event.target.value); - }; - - const handleReset = (event: React.MouseEvent) => { - event.preventDefault(); - setText(''); - }; - - // TODO : react-hook-form 적용 후 유효성 검사 로직 예정 + const { register, watch, resetField } = useFormContext(); + const inputValue = watch(id); + const handleReset = () => resetField(id); return ( @@ -32,12 +24,14 @@ const AuthInputNormal = ({ type={type} id={id} placeholder={placeholder} - value={text} - onChange={handleChange} + {...register(id, fieldOptions(id))} /> - {usedFor === 'login' && text.length > 0 && ( - )} - {usedFor === 'signup' && - (isInvalid ? : )} + {usedFor === 'signup' && ( + + )} ); From 8156ab5888581474d57646c7294846bc31f00685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 04:00:07 +0900 Subject: [PATCH 06/21] =?UTF-8?q?feat:=20AuthInputPassword=EC=97=90=20reac?= =?UTF-8?q?t-hook-form=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/Auth/AuthInputPassword/index.tsx | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/components/common/Auth/AuthInputPassword/index.tsx b/src/components/common/Auth/AuthInputPassword/index.tsx index 1749c801..0abe8d9e 100644 --- a/src/components/common/Auth/AuthInputPassword/index.tsx +++ b/src/components/common/Auth/AuthInputPassword/index.tsx @@ -1,5 +1,6 @@ -import { ChangeEvent, useState } from 'react'; +import { useState } from 'react'; import styled from '@emotion/styled'; +import { useFormContext } from 'react-hook-form'; import { AuthInput } from '@/types/auth'; import eyeOn from '@assets/icons/ic-login-eye-on.svg'; @@ -7,6 +8,7 @@ import eyeOff from '@assets/icons/ic-login-eye-off.svg'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; +import { fieldOptions } from '@utils/lib/login'; const AuthInputPassword = ({ id, @@ -14,17 +16,11 @@ const AuthInputPassword = ({ usedFor, isInvalid }: AuthInput) => { - const [text, setText] = useState(''); - const [showPW, setShowPW] = useState(false); - - const handleChange = (event: ChangeEvent) => { - setText(event.target.value); - }; + const { register, watch, resetField } = useFormContext(); + const inputValue = watch(id); + const handleReset = () => resetField(id); - const handleReset = (event: React.MouseEvent) => { - event.preventDefault(); - setText(''); - }; + const [showPW, setShowPW] = useState(false); const handleShowPW = (event: React.MouseEvent) => { event.preventDefault(); @@ -37,11 +33,10 @@ const AuthInputPassword = ({ type={showPW ? 'text' : 'password'} id={id} placeholder={placeholder} - value={text} - onChange={handleChange} + {...register(id, fieldOptions(id))} /> - {text.length > 0 && ( + {!!inputValue && ( )} - {usedFor === 'login' && text.length > 0 && ( + {usedFor === 'login' && !!inputValue && ( )} - {usedFor === 'signup' && - (isInvalid ? : )} + {usedFor === 'signup' && ( + + )} ); From b8c2e49dd6bfcc3088831bab1a1aa32b145e5f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 04:05:45 +0900 Subject: [PATCH 08/21] =?UTF-8?q?feat:=20SignUpForm=EC=97=90=20react-hook-?= =?UTF-8?q?form=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SignUp/SignUpForm/index.tsx | 147 +++++++++++---------- 1 file changed, 76 insertions(+), 71 deletions(-) diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx index 35ec971b..feca63c0 100644 --- a/src/components/SignUp/SignUpForm/index.tsx +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -1,4 +1,5 @@ import styled from '@emotion/styled'; +import { FormProvider, useForm } from 'react-hook-form'; import { SignUpInputValidation } from '@/types/signUp'; import { @@ -8,84 +9,88 @@ import { } from '@components/common/Auth'; const SignUpForm = () => { + const methods = useForm(); + const isInvalid = true; const isEmailValidationVisible = false; return ( -
- - - - {isInvalid && ( - - 이름을 입력해 주세요. - - )} - - - - - + + + + - { - // TODO : 회원가입 API 요청 로직 - }} + {isInvalid && ( + + 이름을 입력해 주세요. + + )} + + + + + + { + // TODO : 회원가입 API 요청 로직 + }} + /> + + {isEmailValidationVisible && ( + + 사용 가능한 아이디입니다. + + )} + + + + - - {isEmailValidationVisible && ( - - 사용 가능한 아이디입니다. - - )} - - - - - {isInvalid && ( - - 비밀번호 형식이 아닙니다. - - )} - - - - + 비밀번호 형식이 아닙니다. + + )} + + + + + {isInvalid && ( + + 비밀번호가 일치하지 않습니다. + + )} + + {}} /> - {isInvalid && ( - - 비밀번호가 일치하지 않습니다. - - )} - - {}} - /> - + + ); }; From 958960266a970ceb50628fc6ea8c39d492be6bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 04:28:22 +0900 Subject: [PATCH 09/21] =?UTF-8?q?feat:=20SignUpForm=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=EB=A9=94=EC=9D=BCinput=EC=9D=84=20AuthInputNormal=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SignUp/SignUpForm/index.tsx | 43 +++---------------- .../common/Auth/AuthInputNormal/index.tsx | 21 ++++++--- src/types/auth.ts | 5 +++ 3 files changed, 26 insertions(+), 43 deletions(-) diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx index feca63c0..430703c9 100644 --- a/src/components/SignUp/SignUpForm/index.tsx +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -35,17 +35,19 @@ const SignUpForm = () => { - { - // TODO : 회원가입 API 요청 로직 + // TODO : 이메일 중복확인 API 요청 로직 }} /> @@ -87,7 +89,9 @@ const SignUpForm = () => { size="large" variant="navy" text="회원가입" - buttonFunc={() => {}} + buttonFunc={() => { + // TODO : 회원가입 API 요청 로직 + }} /> @@ -118,44 +122,11 @@ const Label = styled.label` line-height: 32px; `; -const Input = styled.input` - width: 524px; - height: 79px; - - border-radius: 16px; - border: 2px solid #757676; - padding: 23px 20px; - - display: flex; - align-items: center; - - color: #1a2849; - font-size: 18px; - font-weight: 500; - line-height: 32px; - - &::placeholder { - color: #979c9e; - font-size: 18px; - font-weight: 500; - line-height: 32px; - } - - &:focus { - outline: 2px solid #1a2849; - border-color: #1a2849; - } -`; - const EmailInputWrapper = styled.div` display: flex; justify-content: space-between; `; -const EmailInput = styled(Input)` - width: 358px; -`; - const ValidationText = styled.p` margin-top: 2px; margin-left: 12px; diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/common/Auth/AuthInputNormal/index.tsx index 98952b55..130afd84 100644 --- a/src/components/common/Auth/AuthInputNormal/index.tsx +++ b/src/components/common/Auth/AuthInputNormal/index.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; import { useFormContext } from 'react-hook-form'; -import { AuthInputNormal } from '@/types/auth'; +import { AuthInputNormal, AuthInputStyleProps } from '@/types/auth'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; @@ -19,11 +19,16 @@ const AuthInputNormal = ({ const handleReset = () => resetField(id); return ( - + @@ -38,7 +43,7 @@ const AuthInputNormal = ({ /> )} - {usedFor === 'signup' && ( + {usedFor === 'signup' && type !== 'email' && ( )} @@ -48,18 +53,20 @@ const AuthInputNormal = ({ export default AuthInputNormal; -const Container = styled.div` +const Container = styled.div` position: relative; - width: 524px; + width: ${props => + props.$usedFor === 'signup' && props.$type === 'email' ? '358px' : '524px'}; height: 79px; display: flex; align-items: center; `; -const Input = styled.input` - width: 524px; +const Input = styled.input` + width: ${props => + props.$usedFor === 'signup' && props.$type === 'email' ? '358px' : '524px'}; height: 79px; border-radius: 16px; diff --git a/src/types/auth.ts b/src/types/auth.ts index 49861aba..7eed7c2a 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -1,3 +1,8 @@ +export type AuthInputStyleProps = { + $usedFor: string; + $type: string; +}; + export type AuthInput = { id: string; placeholder: string; From ba5dd595860e8765e4dddc7f6cdcbf1f86d4368f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 17:24:36 +0900 Subject: [PATCH 10/21] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20input=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EC=98=B5=EC=85=98=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/lib/login.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/utils/lib/login.ts b/src/utils/lib/login.ts index b9b372eb..8ff82f55 100644 --- a/src/utils/lib/login.ts +++ b/src/utils/lib/login.ts @@ -1,9 +1,20 @@ +const nameRegex = /^[가-힣]{2,20}$/i; const emailRegex = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i; const passwordRegex = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,20}$/g; -export const fieldOptions = (fieldName: string) => { +export const fieldOptions = (fieldName: string, password?: string) => { switch (fieldName) { + case 'user_name': + return { + required: '이름을 입력해주세요.', + minLength: { value: 2, message: '이름은 최소 2자 이상 입력해주세요.' }, + maxLength: { value: 20, message: '이름은 최대 20자까지 입력해주세요.' }, + pattern: { + value: nameRegex, + message: '2-20자의 한글로 입력해주세요.' + } + }; case 'user_email': return { required: '이메일을 입력해주세요.', @@ -19,8 +30,16 @@ export const fieldOptions = (fieldName: string) => { maxLength: 20, pattern: { value: passwordRegex, - message: - '영문, 숫자, 특수문자를 포함한 8-20자의 비밀번호를 입력해주세요.' + message: '8~20자의 영문, 숫자, 특수문자를 모두 포함하여 입력해주세요.' + } + }; + case 'user_password_confirm': + return { + required: '비밀번호를 입력해주세요.', + validate: { + matchPassword: (value: string) => { + return password !== value ? '비밀번호가 일치하지 않습니다.' : true; + } } }; } From 7b44cc9d85daa95c976a6df59929dee2f94417c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 17:26:11 +0900 Subject: [PATCH 11/21] =?UTF-8?q?rename:=20utils=20>=20login.ts=20->=20aut?= =?UTF-8?q?h.ts=EB=A1=9C=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Auth/AuthInputNormal/index.tsx | 2 +- src/components/common/Auth/AuthInputPassword/index.tsx | 2 +- src/utils/lib/{login.ts => auth.ts} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/utils/lib/{login.ts => auth.ts} (100%) diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/common/Auth/AuthInputNormal/index.tsx index 130afd84..25a63eec 100644 --- a/src/components/common/Auth/AuthInputNormal/index.tsx +++ b/src/components/common/Auth/AuthInputNormal/index.tsx @@ -5,7 +5,7 @@ import { AuthInputNormal, AuthInputStyleProps } from '@/types/auth'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; -import { fieldOptions } from '@utils/lib/login'; +import { fieldOptions } from '@utils/lib/auth'; const AuthInputNormal = ({ type, diff --git a/src/components/common/Auth/AuthInputPassword/index.tsx b/src/components/common/Auth/AuthInputPassword/index.tsx index 4a952d83..dd4a8b4b 100644 --- a/src/components/common/Auth/AuthInputPassword/index.tsx +++ b/src/components/common/Auth/AuthInputPassword/index.tsx @@ -8,7 +8,7 @@ import eyeOff from '@assets/icons/ic-login-eye-off.svg'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; -import { fieldOptions } from '@utils/lib/login'; +import { fieldOptions } from '@utils/lib/auth'; const AuthInputPassword = ({ id, diff --git a/src/utils/lib/login.ts b/src/utils/lib/auth.ts similarity index 100% rename from src/utils/lib/login.ts rename to src/utils/lib/auth.ts From 11e81efe16893b8791d4b4a273d216eecbb7778d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 17:30:47 +0900 Subject: [PATCH 12/21] =?UTF-8?q?modify:=20filedOptions=20->=20getInputOpt?= =?UTF-8?q?ions=EB=A1=9C=20=ED=95=A8=EC=88=98=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Auth/AuthInputNormal/index.tsx | 4 ++-- src/components/common/Auth/AuthInputPassword/index.tsx | 4 ++-- src/utils/lib/auth.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/common/Auth/AuthInputNormal/index.tsx index 25a63eec..74160b43 100644 --- a/src/components/common/Auth/AuthInputNormal/index.tsx +++ b/src/components/common/Auth/AuthInputNormal/index.tsx @@ -5,7 +5,7 @@ import { AuthInputNormal, AuthInputStyleProps } from '@/types/auth'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; -import { fieldOptions } from '@utils/lib/auth'; +import { getInputOptions } from '@utils/lib/auth'; const AuthInputNormal = ({ type, @@ -29,7 +29,7 @@ const AuthInputNormal = ({ placeholder={placeholder} $usedFor={usedFor} $type={type} - {...register(id, fieldOptions(id))} + {...register(id, getInputOptions(id))} /> {usedFor === 'login' && !!inputValue && ( diff --git a/src/components/common/Auth/AuthInputPassword/index.tsx b/src/components/common/Auth/AuthInputPassword/index.tsx index dd4a8b4b..60e92169 100644 --- a/src/components/common/Auth/AuthInputPassword/index.tsx +++ b/src/components/common/Auth/AuthInputPassword/index.tsx @@ -8,7 +8,7 @@ import eyeOff from '@assets/icons/ic-login-eye-off.svg'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; -import { fieldOptions } from '@utils/lib/auth'; +import { getInputOptions } from '@utils/lib/auth'; const AuthInputPassword = ({ id, @@ -33,7 +33,7 @@ const AuthInputPassword = ({ type={showPW ? 'text' : 'password'} id={id} placeholder={placeholder} - {...register(id, fieldOptions(id))} + {...register(id, getInputOptions(id))} /> {!!inputValue && ( diff --git a/src/utils/lib/auth.ts b/src/utils/lib/auth.ts index 8ff82f55..9643cb75 100644 --- a/src/utils/lib/auth.ts +++ b/src/utils/lib/auth.ts @@ -3,8 +3,8 @@ const emailRegex = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i; const passwordRegex = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,20}$/g; -export const fieldOptions = (fieldName: string, password?: string) => { - switch (fieldName) { +export const getInputOptions = (inputName: string, password?: string) => { + switch (inputName) { case 'user_name': return { required: '이름을 입력해주세요.', From b327ab89b86e6dc34753cb4854ca9ce38c0302da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 17:32:17 +0900 Subject: [PATCH 13/21] =?UTF-8?q?modify:=20getInputOptions=EB=A1=9C=20impo?= =?UTF-8?q?rt=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Auth/AuthInputNormal/index.tsx | 2 +- src/components/common/Auth/AuthInputPassword/index.tsx | 2 +- src/utils/index.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/common/Auth/AuthInputNormal/index.tsx index 74160b43..a49d5a6e 100644 --- a/src/components/common/Auth/AuthInputNormal/index.tsx +++ b/src/components/common/Auth/AuthInputNormal/index.tsx @@ -5,7 +5,7 @@ import { AuthInputNormal, AuthInputStyleProps } from '@/types/auth'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; -import { getInputOptions } from '@utils/lib/auth'; +import { getInputOptions } from '@utils/index'; const AuthInputNormal = ({ type, diff --git a/src/components/common/Auth/AuthInputPassword/index.tsx b/src/components/common/Auth/AuthInputPassword/index.tsx index 60e92169..89aee228 100644 --- a/src/components/common/Auth/AuthInputPassword/index.tsx +++ b/src/components/common/Auth/AuthInputPassword/index.tsx @@ -8,7 +8,7 @@ import eyeOff from '@assets/icons/ic-login-eye-off.svg'; import closeIcon from '@assets/icons/ic-login-close.svg'; import checkInvalid from '@assets/icons/ic-signup-check-invalid.svg'; import checkValid from '@assets/icons/ic-signup-check-valid.svg'; -import { getInputOptions } from '@utils/lib/auth'; +import { getInputOptions } from '@utils/index'; const AuthInputPassword = ({ id, diff --git a/src/utils/index.ts b/src/utils/index.ts index b567f823..71c34959 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -7,3 +7,4 @@ export { } from './lib/report'; export { getUpdatedDate } from './lib/calculation'; export { getStatusToLocaleString } from './lib/dashboard'; +export { getInputOptions } from './lib/auth'; From 1040e01a9f940e5db446b2b8cc2e31e9f9a1526f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 22:38:35 +0900 Subject: [PATCH 14/21] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8&=EB=B9=84?= =?UTF-8?q?=EB=B0=80=EB=B2=88=ED=98=B8=20=ED=99=95=EC=9D=B8=20input=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SignUp/SignUpForm/index.tsx | 46 +++++++++++-------- .../common/Auth/AuthInputPassword/index.tsx | 14 ++++-- src/types/auth.ts | 2 +- src/types/signUp.ts | 4 +- src/utils/lib/auth.ts | 24 ++++++++-- 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx index 430703c9..7f33b60e 100644 --- a/src/components/SignUp/SignUpForm/index.tsx +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -9,7 +9,12 @@ import { } from '@components/common/Auth'; const SignUpForm = () => { - const methods = useForm(); + const methods = useForm({ + mode: 'all' + }); + const { + formState: { errors } + } = methods; const isInvalid = true; const isEmailValidationVisible = false; @@ -24,11 +29,11 @@ const SignUpForm = () => { id="user_name" placeholder="이름 입력" usedFor="signup" - isInvalid={isInvalid} + isError={!!errors?.user_name} /> - {isInvalid && ( - - 이름을 입력해 주세요. + {errors.user_name && ( + + {errors?.user_name?.message?.toString()} )} @@ -40,7 +45,7 @@ const SignUpForm = () => { id="user_email" placeholder="이메일 입력" usedFor="signup" - isInvalid={isInvalid} + isError={!!errors?.user_email} /> { }} /> - {isEmailValidationVisible && ( - - 사용 가능한 아이디입니다. + {errors.user_email && ( + + {errors?.user_email?.message?.toString()} + + )} + {!errors.user_email && isEmailValidationVisible && ( + + 백엔드 응답에 따라 나타날 유효성 메세지 )} @@ -63,11 +73,11 @@ const SignUpForm = () => { id="user_password" placeholder="8-20자, 영문/숫자/특수문자 조합" usedFor="signup" - isInvalid={isInvalid} + isError={!!errors?.user_password} /> - {isInvalid && ( - - 비밀번호 형식이 아닙니다. + {errors.user_password && ( + + {errors?.user_password?.message?.toString()} )} @@ -77,11 +87,11 @@ const SignUpForm = () => { id="user_password_confirm" placeholder="다시 한번 입력해주세요." usedFor="signup" - isInvalid={isInvalid} + isError={!!errors?.user_password_confirm} /> - {isInvalid && ( - - 비밀번호가 일치하지 않습니다. + {errors.user_password_confirm && ( + + {errors?.user_password_confirm?.message?.toString()} )} @@ -131,7 +141,7 @@ const ValidationText = styled.p` margin-top: 2px; margin-left: 12px; - color: ${props => (props.$isInvalid ? '#DA1E28' : '#1a2849')}; + color: ${props => (props.$isValid ? '#1a2849' : '#DA1E28')}; font-size: 15px; font-weight: 700; line-height: 32px; diff --git a/src/components/common/Auth/AuthInputPassword/index.tsx b/src/components/common/Auth/AuthInputPassword/index.tsx index 89aee228..b0343353 100644 --- a/src/components/common/Auth/AuthInputPassword/index.tsx +++ b/src/components/common/Auth/AuthInputPassword/index.tsx @@ -14,12 +14,18 @@ const AuthInputPassword = ({ id, placeholder, usedFor, - isInvalid + isError }: AuthInput) => { - const { register, watch, resetField } = useFormContext(); + const { register, watch, resetField, getFieldState, formState } = + useFormContext(); + const inputValue = watch(id); const handleReset = () => resetField(id); + const passwordValue = watch('user_password'); + const isInputTouched = getFieldState(id, formState).isTouched; + const isValid = isInputTouched ? !isError : false; + const [showPW, setShowPW] = useState(false); const handleShowPW = (event: React.MouseEvent) => { @@ -33,7 +39,7 @@ const AuthInputPassword = ({ type={showPW ? 'text' : 'password'} id={id} placeholder={placeholder} - {...register(id, getInputOptions(id))} + {...register(id, getInputOptions(id, passwordValue))} /> {!!inputValue && ( @@ -53,7 +59,7 @@ const AuthInputPassword = ({ )} {usedFor === 'signup' && ( - + )} diff --git a/src/types/auth.ts b/src/types/auth.ts index 7eed7c2a..75e106a4 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -7,7 +7,7 @@ export type AuthInput = { id: string; placeholder: string; usedFor: string; - isInvalid: boolean; + isError?: boolean; }; export type AuthInputNormal = AuthInput & { diff --git a/src/types/signUp.ts b/src/types/signUp.ts index c07f069b..a0fd1e23 100644 --- a/src/types/signUp.ts +++ b/src/types/signUp.ts @@ -1,5 +1,5 @@ export type SignUpFormStyleProps = { - $isInvalid: boolean; + $isValid?: boolean; }; -export type SignUpInputValidation = Pick; +export type SignUpInputValidation = Pick; diff --git a/src/utils/lib/auth.ts b/src/utils/lib/auth.ts index 9643cb75..1abddb0c 100644 --- a/src/utils/lib/auth.ts +++ b/src/utils/lib/auth.ts @@ -26,8 +26,14 @@ export const getInputOptions = (inputName: string, password?: string) => { case 'user_password': return { required: '비밀번호를 입력해주세요.', - minLength: 8, - maxLength: 20, + minLength: { + value: 8, + message: '비밀번호는 최소 8자 이상 입력해주세요.' + }, + maxLength: { + value: 20, + message: '비밀번호는 최대 20자까지 입력해주세요.' + }, pattern: { value: passwordRegex, message: '8~20자의 영문, 숫자, 특수문자를 모두 포함하여 입력해주세요.' @@ -36,9 +42,21 @@ export const getInputOptions = (inputName: string, password?: string) => { case 'user_password_confirm': return { required: '비밀번호를 입력해주세요.', + minLength: { + value: 8, + message: '비밀번호는 최소 8자 이상 입력해주세요.' + }, + maxLength: { + value: 20, + message: '비밀번호는 최대 20자까지 입력해주세요.' + }, + pattern: { + value: passwordRegex, + message: '8~20자의 영문, 숫자, 특수문자를 모두 포함하여 입력해주세요.' + }, validate: { matchPassword: (value: string) => { - return password !== value ? '비밀번호가 일치하지 않습니다.' : true; + return password === value || '비밀번호가 일치하지 않습니다'; } } }; From 6238f6223955ee9d0d193a30eeca74cfe7072e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 22:44:34 +0900 Subject: [PATCH 15/21] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=9D=B4=EB=A6=84=20input=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/Auth/AuthInputNormal/index.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/common/Auth/AuthInputNormal/index.tsx index a49d5a6e..f8490e93 100644 --- a/src/components/common/Auth/AuthInputNormal/index.tsx +++ b/src/components/common/Auth/AuthInputNormal/index.tsx @@ -12,12 +12,16 @@ const AuthInputNormal = ({ id, placeholder, usedFor, - isInvalid + isError }: AuthInputNormal) => { - const { register, watch, resetField } = useFormContext(); + const { register, watch, resetField, getFieldState, formState } = + useFormContext(); const inputValue = watch(id); const handleReset = () => resetField(id); + const isInputTouched = getFieldState(id, formState).isTouched; + const isValid = isInputTouched ? !isError : false; + return ( )} {usedFor === 'signup' && type !== 'email' && ( - + )} From 6d4a4f0a1a4405df2b7e3af8b843eb70adcbe462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 22:56:28 +0900 Subject: [PATCH 16/21] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20input=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SignUp/SignUpForm/index.tsx | 17 ++++++++++------- src/components/common/Auth/AuthButton/index.tsx | 9 ++++++++- src/types/auth.ts | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx index 7f33b60e..48f8f4b8 100644 --- a/src/components/SignUp/SignUpForm/index.tsx +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -12,12 +12,13 @@ const SignUpForm = () => { const methods = useForm({ mode: 'all' }); - const { - formState: { errors } - } = methods; + const { getFieldState, formState } = methods; + const { errors } = formState; const isInvalid = true; - const isEmailValidationVisible = false; + + const isEmailTouched = getFieldState('user_email', formState).isTouched; + const isEmailValid = isEmailTouched ? !errors?.user_email : false; return ( @@ -49,8 +50,9 @@ const SignUpForm = () => { /> { // TODO : 이메일 중복확인 API 요청 로직 }} @@ -61,8 +63,8 @@ const SignUpForm = () => { {errors?.user_email?.message?.toString()} )} - {!errors.user_email && isEmailValidationVisible && ( - + {!errors.user_email && isEmailValid && ( + 백엔드 응답에 따라 나타날 유효성 메세지 )} @@ -99,6 +101,7 @@ const SignUpForm = () => { size="large" variant="navy" text="회원가입" + disabled={false} buttonFunc={() => { // TODO : 회원가입 API 요청 로직 }} diff --git a/src/components/common/Auth/AuthButton/index.tsx b/src/components/common/Auth/AuthButton/index.tsx index 3fbe96e8..59f0e3d3 100644 --- a/src/components/common/Auth/AuthButton/index.tsx +++ b/src/components/common/Auth/AuthButton/index.tsx @@ -2,12 +2,19 @@ import styled from '@emotion/styled'; import { AuthButton, AuthButtonStyleProps } from '@/types/auth'; -const AuthButton = ({ size, variant, text, buttonFunc }: AuthButton) => { +const AuthButton = ({ + size, + variant, + text, + disabled, + buttonFunc +}: AuthButton) => { return ( {text} diff --git a/src/types/auth.ts b/src/types/auth.ts index 75e106a4..98a64c4f 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -26,6 +26,7 @@ export type AuthButton = { size: string; variant: string; text: string; + disabled: boolean; buttonFunc: | LoginAPIButton | SignUpAPIButton From f0db448ca91c765ed092c3bcce5a328b012711a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Mon, 22 Jan 2024 23:00:57 +0900 Subject: [PATCH 17/21] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=ED=8F=BC=20=EC=9E=85=EB=A0=A5=EC=83=81=ED=83=9C?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85(submit)=EB=B2=84=ED=8A=BC=20disabled=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/SignUp/SignUpForm/index.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx index 48f8f4b8..fe752dd2 100644 --- a/src/components/SignUp/SignUpForm/index.tsx +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -13,9 +13,7 @@ const SignUpForm = () => { mode: 'all' }); const { getFieldState, formState } = methods; - const { errors } = formState; - - const isInvalid = true; + const { errors, isValid } = formState; const isEmailTouched = getFieldState('user_email', formState).isTouched; const isEmailValid = isEmailTouched ? !errors?.user_email : false; @@ -99,9 +97,9 @@ const SignUpForm = () => { { // TODO : 회원가입 API 요청 로직 }} From 88656564997f5a90ee478e5ef072d27981c76002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Tue, 23 Jan 2024 03:31:04 +0900 Subject: [PATCH 18/21] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=8F=BC=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Login/LoginForm/index.tsx | 46 +++++++++++++----------- src/types/auth.ts | 2 +- src/types/login.ts | 4 +-- src/utils/lib/auth.ts | 8 +++++ 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/components/Login/LoginForm/index.tsx b/src/components/Login/LoginForm/index.tsx index 49ee4401..bfb5a7d2 100644 --- a/src/components/Login/LoginForm/index.tsx +++ b/src/components/Login/LoginForm/index.tsx @@ -13,19 +13,23 @@ import { postLogin } from 'src/api'; import { setCookies } from '@utils/lib/cookies'; const LoginForm = () => { - const methods = useForm(); const navigate = useNavigate(); const { state } = useLocation(); - // HACK : 추후 useState로 입력 데이터 관리할 예쩡 + const methods = useForm({ + mode: 'onBlur' + }); + const { + formState: { errors, isValid } + } = methods; + const isError = !!errors?.user_id || !!errors?.user_password ? true : false; + + // HACK : 추후 react-hook-form으로 입력 데이터 관리 예정 const formData: LoginData = { email: 'juhwanTest@gmail.com', password: 'juhwanTest' }; - // HACK: 유효성 검사 기능 구현 후 유효성 메세지 노출 여부 결정 - const isInvalid = true; - const movetoSignUp = (event: React.MouseEvent) => { event.preventDefault(); navigate('/signup'); @@ -51,31 +55,37 @@ const LoginForm = () => { return (
- + - {isInvalid && ( + {errors.user_id && ( + + {errors?.user_id?.message?.toString()} + + )} + {!errors.user_id && errors.user_password && ( - 아이디를 입력해 주세요 + {errors?.user_password?.message?.toString()} )} - + { export default LoginForm; const Inputs = styled.div` - margin-bottom: ${props => (props.$isInvalid ? '10px' : '65px')}; + margin-bottom: ${props => (props.$isValid ? '65px' : '10px')}; display: flex; flex-direction: column; @@ -105,12 +115,8 @@ const ValidationText = styled.p` color: #da1e28; font-size: 15px; - font-weight: 500; - line-height: 32px; -`; - -const ValidationBoldText = styled.span` font-weight: 700; + line-height: 32px; `; const Buttons = styled.div` @@ -118,5 +124,5 @@ const Buttons = styled.div` flex-direction: column; gap: 13px; - ${props => props.$isInvalid && 'margin-top: 23px'}; + margin-top: ${props => (props.$isValid ? 0 : '23px')}; `; diff --git a/src/types/auth.ts b/src/types/auth.ts index 98a64c4f..80b9c785 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -26,7 +26,7 @@ export type AuthButton = { size: string; variant: string; text: string; - disabled: boolean; + disabled?: boolean; buttonFunc: | LoginAPIButton | SignUpAPIButton diff --git a/src/types/login.ts b/src/types/login.ts index f529da27..78ad6373 100644 --- a/src/types/login.ts +++ b/src/types/login.ts @@ -1,5 +1,5 @@ export type LoginFormStyleProps = { - $isInvalid: boolean; + $isValid: boolean; }; -export type InputValidation = Pick; +export type InputValidation = Pick; diff --git a/src/utils/lib/auth.ts b/src/utils/lib/auth.ts index 1abddb0c..15a0697a 100644 --- a/src/utils/lib/auth.ts +++ b/src/utils/lib/auth.ts @@ -60,5 +60,13 @@ export const getInputOptions = (inputName: string, password?: string) => { } } }; + case 'user_id': + return { + required: '아이디를 입력해주세요.', + pattern: { + value: emailRegex, + message: '이메일 형식에 맞게 입력해주세요.' + } + }; } }; From f9b75dd6d1883f71e7a7595553e1a44b6a7a7edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Tue, 23 Jan 2024 15:38:07 +0900 Subject: [PATCH 19/21] =?UTF-8?q?move:=20components=20>=20common>=20Auth?= =?UTF-8?q?=20=ED=8F=B4=EB=8D=94=20=EC=9C=84=EC=B9=98=20components=20>=20A?= =?UTF-8?q?uth=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/{common => }/Auth/AuthButton/index.tsx | 0 src/components/{common => }/Auth/AuthInputNormal/index.tsx | 0 src/components/{common => }/Auth/AuthInputPassword/index.tsx | 0 src/components/{common => }/Auth/index.tsx | 0 src/components/Login/LoginForm/index.tsx | 2 +- src/components/SignUp/SignUpForm/index.tsx | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) rename src/components/{common => }/Auth/AuthButton/index.tsx (100%) rename src/components/{common => }/Auth/AuthInputNormal/index.tsx (100%) rename src/components/{common => }/Auth/AuthInputPassword/index.tsx (100%) rename src/components/{common => }/Auth/index.tsx (100%) diff --git a/src/components/common/Auth/AuthButton/index.tsx b/src/components/Auth/AuthButton/index.tsx similarity index 100% rename from src/components/common/Auth/AuthButton/index.tsx rename to src/components/Auth/AuthButton/index.tsx diff --git a/src/components/common/Auth/AuthInputNormal/index.tsx b/src/components/Auth/AuthInputNormal/index.tsx similarity index 100% rename from src/components/common/Auth/AuthInputNormal/index.tsx rename to src/components/Auth/AuthInputNormal/index.tsx diff --git a/src/components/common/Auth/AuthInputPassword/index.tsx b/src/components/Auth/AuthInputPassword/index.tsx similarity index 100% rename from src/components/common/Auth/AuthInputPassword/index.tsx rename to src/components/Auth/AuthInputPassword/index.tsx diff --git a/src/components/common/Auth/index.tsx b/src/components/Auth/index.tsx similarity index 100% rename from src/components/common/Auth/index.tsx rename to src/components/Auth/index.tsx diff --git a/src/components/Login/LoginForm/index.tsx b/src/components/Login/LoginForm/index.tsx index bfb5a7d2..827b419e 100644 --- a/src/components/Login/LoginForm/index.tsx +++ b/src/components/Login/LoginForm/index.tsx @@ -7,7 +7,7 @@ import { AuthButton, AuthInputNormal, AuthInputPassword -} from '@components/common/Auth'; +} from '@components/Auth'; import { LoginData } from '@/types/auth'; import { postLogin } from 'src/api'; import { setCookies } from '@utils/lib/cookies'; diff --git a/src/components/SignUp/SignUpForm/index.tsx b/src/components/SignUp/SignUpForm/index.tsx index fe752dd2..b1f0aa2a 100644 --- a/src/components/SignUp/SignUpForm/index.tsx +++ b/src/components/SignUp/SignUpForm/index.tsx @@ -6,7 +6,7 @@ import { AuthButton, AuthInputNormal, AuthInputPassword -} from '@components/common/Auth'; +} from '@components/Auth'; const SignUpForm = () => { const methods = useForm({ From c3026c5c2b2af1d1e25b57367b102329f0407da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=8B=A4=EB=B9=88?= <991012dabin@gmail.com> Date: Tue, 23 Jan 2024 16:37:47 +0900 Subject: [PATCH 20/21] =?UTF-8?q?feat:=20react-hook-form=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=A0=9C=EC=B6=9C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Login/LoginForm/index.tsx | 30 +++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/components/Login/LoginForm/index.tsx b/src/components/Login/LoginForm/index.tsx index 827b419e..b3ea2341 100644 --- a/src/components/Login/LoginForm/index.tsx +++ b/src/components/Login/LoginForm/index.tsx @@ -1,6 +1,11 @@ import { useLocation, useNavigate } from 'react-router-dom'; import styled from '@emotion/styled'; -import { FormProvider, useForm } from 'react-hook-form'; +import { + FormProvider, + useForm, + SubmitHandler, + FieldValues +} from 'react-hook-form'; import { InputValidation } from '@/types/login'; import { @@ -20,25 +25,22 @@ const LoginForm = () => { mode: 'onBlur' }); const { - formState: { errors, isValid } + formState: { errors, isValid }, + handleSubmit } = methods; const isError = !!errors?.user_id || !!errors?.user_password ? true : false; - // HACK : 추후 react-hook-form으로 입력 데이터 관리 예정 - const formData: LoginData = { - email: 'juhwanTest@gmail.com', - password: 'juhwanTest' - }; - const movetoSignUp = (event: React.MouseEvent) => { event.preventDefault(); navigate('/signup'); }; - const handleLoginSubmit = async ( - event: React.FormEvent - ) => { - event.preventDefault(); + const onSubmit: SubmitHandler = async data => { + const formData: LoginData = { + email: data.user_id, + password: data.user_password + }; + const response = await postLogin(formData); setCookies('userName', response.name, response.expires_in); setCookies('userEmail', response.email, response.expires_in); @@ -54,7 +56,7 @@ const LoginForm = () => { return ( - + { variant="navy" text="로그인" disabled={!isValid} - buttonFunc={handleLoginSubmit} + buttonFunc={handleSubmit(onSubmit)} /> Date: Tue, 23 Jan 2024 16:57:37 +0900 Subject: [PATCH 21/21] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20API?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Login/LoginForm/index.tsx | 29 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/components/Login/LoginForm/index.tsx b/src/components/Login/LoginForm/index.tsx index b3ea2341..eec62c84 100644 --- a/src/components/Login/LoginForm/index.tsx +++ b/src/components/Login/LoginForm/index.tsx @@ -1,4 +1,5 @@ import { useLocation, useNavigate } from 'react-router-dom'; +import { AxiosError } from 'axios'; import styled from '@emotion/styled'; import { FormProvider, @@ -40,17 +41,25 @@ const LoginForm = () => { email: data.user_id, password: data.user_password }; + try { + const response = await postLogin(formData); + setCookies('userName', response.name, response.expires_in); + setCookies('userEmail', response.email, response.expires_in); + setCookies('accessToken', response.access_token, response.expires_in); + setCookies('refreshToken', response.refresh_token, response.expires_in); - const response = await postLogin(formData); - setCookies('userName', response.name, response.expires_in); - setCookies('userEmail', response.email, response.expires_in); - setCookies('accessToken', response.access_token, response.expires_in); - setCookies('refreshToken', response.refresh_token, response.expires_in); - - if (state) { - navigate(state); - } else { - navigate('/'); + if (state) { + navigate(state); + } else { + navigate('/'); + } + } catch (error) { + if (error instanceof AxiosError) { + console.log(error); + // TODO : 에러코드에 따라 모달 표시 예정 + // error.response?.data.code; + // error.response?.data.message; + } } };