From 893a5278b5ae6db5e0d84cc5d8b8bd7f4e5927de Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Wed, 5 Jun 2024 15:55:11 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B0=BE=EA=B8=B0=20=EC=B4=88=EA=B8=B0=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FindPassword/Verify/index.module.scss | 36 ++++++ src/page/Auth/FindPassword/Verify/index.tsx | 115 ++++++++++++++++++ src/page/Auth/FindPassword/index.tsx | 24 ++++ 3 files changed, 175 insertions(+) create mode 100644 src/page/Auth/FindPassword/Verify/index.module.scss create mode 100644 src/page/Auth/FindPassword/Verify/index.tsx create mode 100644 src/page/Auth/FindPassword/index.tsx diff --git a/src/page/Auth/FindPassword/Verify/index.module.scss b/src/page/Auth/FindPassword/Verify/index.module.scss new file mode 100644 index 00000000..c9650ca2 --- /dev/null +++ b/src/page/Auth/FindPassword/Verify/index.module.scss @@ -0,0 +1,36 @@ +.container { + height: calc(100vh - 30vh); +} + +.section { + display: flex; + flex-direction: column; + justify-content: center; + gap: 10px; + margin-top: 25px; +} + +.title { + font-weight: bold; +} + +.input { + background-color: #f5f5f5; + border-radius: 4px; + border: none; + height: 50px; + padding: 2px 10px; + box-sizing: border-box; +} + +.button { + background-color: #eeeeee; + border: 4px; + height: 50px; + width: 40%; +} + +.error { + color: #f7941e; + font-size: 10px; +} \ No newline at end of file diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx new file mode 100644 index 00000000..78b56a33 --- /dev/null +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -0,0 +1,115 @@ +import { isKoinError } from '@bcsdlab/koin'; +import { useMutation } from '@tanstack/react-query'; +import { sendVerifyCode, verifyCode } from 'api/auth'; +import { useState } from 'react'; +import { + useFormContext, UseFormGetValues, UseFormSetError, +} from 'react-hook-form'; +import styles from './index.module.scss'; + +// 코드 발송 및 에러 처리 +const code = ( + getValues: UseFormGetValues, + setError: UseFormSetError, + setIsSent: React.Dispatch>, +) => { + sendVerifyCode(getValues('phone_number')) + .then(() => setIsSent(true)) + .catch((e) => { + if (isKoinError(e)) { + setError('phone_number', { type: 'custom', message: e.message }); + } + }); +}; + +const useCheckCode = () => { + const mutate = useMutation({ + mutationFn: ({ + phone_number, + certification_code, + }: { phone_number: string, certification_code: string }) => verifyCode({ + phone_number, + certification_code, + }), + onError: () => { + // + }, + }); + + return mutate; +}; + +interface Verify { + phone_number: string; + certification_code: string; +} + +export default function Verify() { + const method = useFormContext(); + const { + register, getValues, setError, formState: { errors }, + } = method; + const [isSent, setIsSent] = useState(false); + const [id, setId] = useState(null); + const mutate = useCheckCode(); + console.log(mutate); + + // 디바운싱 + const debounce = () => { + if (id) clearTimeout(id); + const timeId = setTimeout(() => code(getValues, setError, setIsSent), 200); + setId(timeId); + }; + + const sendCode = () => { + if (getValues('phone_number').length === 0) { + setError('phone_number', { type: 'custom', message: '필수 입력 항목입니다.' }); + return; + } + debounce(); + }; + + return ( +
+
+
휴대폰 번호
+ +
+ {errors.phone_number && errors.phone_number.message} +
+
+
+
인증번호
+
+ + +
+
+ {errors.certification_code && errors.certification_code.message} +
+
+
+ ); +} diff --git a/src/page/Auth/FindPassword/index.tsx b/src/page/Auth/FindPassword/index.tsx new file mode 100644 index 00000000..e844813f --- /dev/null +++ b/src/page/Auth/FindPassword/index.tsx @@ -0,0 +1,24 @@ +import { useOutletContext } from 'react-router-dom'; +// eslint-disable-next-line +import Verify from './Verify'; + +export interface OutletProps { + nextStep: () => void; + previousStep: () => void; + currentStep: string; + index: number; + totalStep: number; + isComplete: boolean; + setIsComplete: React.Dispatch>; +} + +export default function FindPassword() { + const steps: OutletProps = useOutletContext(); + const { index } = steps; + return ( + <> + {index === 0 && } + {index === 1 &&
비밀번호 변경
} + + ); +} From bd1fab4381caf9e8b2909fe0bfe8dcae71c6657d Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Wed, 5 Jun 2024 15:55:36 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B0=BE=EA=B8=B0=20=EB=AC=B8=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20api=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 3 ++- src/api/auth/index.ts | 8 ++++++++ src/page/Auth/components/Common/index.tsx | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d2ce3303..9bb58b0b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,7 @@ import OwnerLayout from 'layout/OwnerLayout'; import CoopLayout from 'layout/CoopLayout'; import Login from 'page/Auth/Login'; import Signup from 'page/Auth/Signup'; -import FindPassword from 'page/Auth/FindPassword/SendAuthNumber'; +// import FindPassword from 'page/Auth/FindPassword/SendAuthNumber'; import NewPassword from 'page/Auth/FindPassword/NewPassword'; import CompleteChangePassword from 'page/Auth/FindPassword/CompleteChangePassword'; import AuthLayout from 'layout/AuthLayout'; @@ -23,6 +23,7 @@ import AddingEvent from 'page/ManageEvent/AddingEvent'; import ModifyEvent from 'page/ManageEvent/ModifyEvent'; import LogPage from 'component/common/PageLog'; import CommonLayout from 'page/Auth/components/Common'; +import FindPassword from 'page/Auth/FindPassword'; interface ProtectedRouteProps { userTypeRequired: UserType; diff --git a/src/api/auth/index.ts b/src/api/auth/index.ts index 1e670088..7ea41d9b 100644 --- a/src/api/auth/index.ts +++ b/src/api/auth/index.ts @@ -34,3 +34,11 @@ export const findPassword = ({ }); export const newPassword = ({ address, password }: { address: string, password: string }) => client.put('/owners/password/reset', { address, password }); + +export const sendVerifyCode = (phone_number: string) => client.post('/owners/password/reset/verification/sms', { + phone_number, +}); + +export const verifyCode = ({ phone_number, certification_code } : { phone_number:string, certification_code:string }) => client.post('/owners/password/reset/send/sms', { + phone_number, certification_code, +}); diff --git a/src/page/Auth/components/Common/index.tsx b/src/page/Auth/components/Common/index.tsx index a56de627..5a2e2192 100644 --- a/src/page/Auth/components/Common/index.tsx +++ b/src/page/Auth/components/Common/index.tsx @@ -21,7 +21,7 @@ interface Register extends FindPassword { shop_name: string, attachment_urls: { file_url: string - }[] + }[], } export default function CommonLayout() { From 65ad31849d3aae19bde2e2b36a7524c466aade5e Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Thu, 6 Jun 2024 23:42:14 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=EB=AC=B8=EC=9E=90=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20response=20=EC=9D=B8=ED=84=B0=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/auth/index.ts | 3 ++- src/model/auth/index.ts | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/api/auth/index.ts b/src/api/auth/index.ts index 7ea41d9b..dd3ca8a6 100644 --- a/src/api/auth/index.ts +++ b/src/api/auth/index.ts @@ -1,5 +1,6 @@ import { accessClient, client } from 'api'; import { + CertificationResponse, LoginParams, LoginResponse, OwnerResponse, UserTypeResponse, } from 'model/auth'; @@ -39,6 +40,6 @@ export const sendVerifyCode = (phone_number: string) => client.post('/owners/pas phone_number, }); -export const verifyCode = ({ phone_number, certification_code } : { phone_number:string, certification_code:string }) => client.post('/owners/password/reset/send/sms', { +export const verifyCode = ({ phone_number, certification_code } : { phone_number:string, certification_code:string }) => client.post('/owners/password/reset/send/sms', { phone_number, certification_code, }); diff --git a/src/model/auth/index.ts b/src/model/auth/index.ts index c2d410aa..40d4c0f1 100644 --- a/src/model/auth/index.ts +++ b/src/model/auth/index.ts @@ -77,3 +77,7 @@ export type User = z.infer; export interface LoginForm extends LoginParams { isAutoLogin: boolean; } + +export interface CertificationResponse { + token: string; +} From c2bc446b1e93963d35d6d257366d8a362efff859 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Thu, 6 Jun 2024 23:42:44 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B0=BE=EA=B8=B0=20=EB=AC=B8=EC=9E=90=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FindPassword/Verify/index.module.scss | 35 +++++++- src/page/Auth/FindPassword/Verify/index.tsx | 79 +++++++++++++------ 2 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/page/Auth/FindPassword/Verify/index.module.scss b/src/page/Auth/FindPassword/Verify/index.module.scss index c9650ca2..62c23953 100644 --- a/src/page/Auth/FindPassword/Verify/index.module.scss +++ b/src/page/Auth/FindPassword/Verify/index.module.scss @@ -14,6 +14,11 @@ font-weight: bold; } +.verify { + display: flex; + justify-content: space-between; +} + .input { background-color: #f5f5f5; border-radius: 4px; @@ -21,16 +26,42 @@ height: 50px; padding: 2px 10px; box-sizing: border-box; + + &--verify { + background-color: #f5f5f5; + border-radius: 4px; + border: none; + height: 50px; + padding: 2px 10px; + box-sizing: border-box; + width: 55%; + } } .button { background-color: #eeeeee; - border: 4px; + border-radius: 4px; height: 50px; width: 40%; + + &--active { + background-color: #175C8E; + color: white; + border-radius: 4px; + height: 50px; + width: 40%; + } + + &--error { + background-color: #F7941E; + color: white; + border-radius: 4px; + height: 50px; + width: 40%; + } } .error { color: #f7941e; - font-size: 10px; + font-size: 11px; } \ No newline at end of file diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx index 78b56a33..6d3c9aff 100644 --- a/src/page/Auth/FindPassword/Verify/index.tsx +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -1,11 +1,15 @@ import { isKoinError } from '@bcsdlab/koin'; -import { useMutation } from '@tanstack/react-query'; import { sendVerifyCode, verifyCode } from 'api/auth'; -import { useState } from 'react'; +import { ChangeEvent, useEffect, useState } from 'react'; import { + UseFormClearErrors, useFormContext, UseFormGetValues, UseFormSetError, } from 'react-hook-form'; +import { useOutletContext } from 'react-router-dom'; +import cn from 'utils/ts/className'; import styles from './index.module.scss'; +// eslint-disable-next-line +import { OutletProps } from '..'; // 코드 발송 및 에러 처리 const code = ( @@ -22,21 +26,36 @@ const code = ( }); }; -const useCheckCode = () => { - const mutate = useMutation({ - mutationFn: ({ - phone_number, - certification_code, - }: { phone_number: string, certification_code: string }) => verifyCode({ - phone_number, - certification_code, - }), - onError: () => { - // - }, - }); +const useCheckCode = ( + setIsStepComplete: React.Dispatch>, + getValues: UseFormGetValues, + setError: UseFormSetError, + clearErrors: UseFormClearErrors, +) => { + const [certificationCode, setCertificationCode] = useState(''); + const [isCertified, setIsCertified] = useState(false); + + useEffect(() => { + if (certificationCode.length === 6) { + verifyCode({ + certification_code: certificationCode, + phone_number: getValues('phone_number'), + }).then((data) => { + setIsStepComplete(true); + setIsCertified(true); + clearErrors(); + sessionStorage.setItem('accessToken', data.data.token); + }) + .catch((e) => { + if (isKoinError(e)) { + setError('certification_code', { type: 'error', message: e.message }); + } + setIsStepComplete(false); + }); + } + }, [certificationCode, setIsStepComplete, getValues, setError, clearErrors]); - return mutate; + return { setCertificationCode, isCertified }; }; interface Verify { @@ -47,12 +66,18 @@ interface Verify { export default function Verify() { const method = useFormContext(); const { - register, getValues, setError, formState: { errors }, + register, getValues, setError, formState: { errors }, watch, clearErrors, } = method; const [isSent, setIsSent] = useState(false); const [id, setId] = useState(null); - const mutate = useCheckCode(); - console.log(mutate); + const steps: OutletProps = useOutletContext(); + + const { setCertificationCode, isCertified } = useCheckCode( + steps.setIsStepComplete, + getValues, + setError, + clearErrors, + ); // 디바운싱 const debounce = () => { @@ -69,6 +94,8 @@ export default function Verify() { debounce(); }; + const setCode = (e: ChangeEvent) => setCertificationCode(e.target.value); + return (
@@ -80,6 +107,7 @@ export default function Verify() { value: true, message: '필수 입력 항목입니다.', }, + maxLength: 11, })} type="text" placeholder="-없이 번호를 입력해주세요." @@ -90,18 +118,25 @@ export default function Verify() {
인증번호
-
+
From a9fed85794c469fe0a27057786a6ffa09a88c431 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 11:58:28 +0900 Subject: [PATCH 05/16] =?UTF-8?q?refactor:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B3=80=EA=B2=BD=20api=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=ED=83=80=EC=9E=85=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/auth/index.ts | 5 +++ src/model/auth/index.ts | 22 +++++++++++++ src/page/Auth/FindPassword/index.tsx | 6 +++- src/page/Auth/components/Common/index.tsx | 38 ++++++++++++----------- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/api/auth/index.ts b/src/api/auth/index.ts index dd3ca8a6..937bd61a 100644 --- a/src/api/auth/index.ts +++ b/src/api/auth/index.ts @@ -43,3 +43,8 @@ export const sendVerifyCode = (phone_number: string) => client.post('/owners/pas export const verifyCode = ({ phone_number, certification_code } : { phone_number:string, certification_code:string }) => client.post('/owners/password/reset/send/sms', { phone_number, certification_code, }); + +export const changePassword = ({ phone_number, password } : { phone_number:string, password:string }) => client.put('/owners/password/reset/sms', { + phone_number, + password, +}); diff --git a/src/model/auth/index.ts b/src/model/auth/index.ts index 40d4c0f1..5edb3e1a 100644 --- a/src/model/auth/index.ts +++ b/src/model/auth/index.ts @@ -81,3 +81,25 @@ export interface LoginForm extends LoginParams { export interface CertificationResponse { token: string; } + +export interface ChangePasswordForm { + password: string; + passwordCheck: string; + phone_number: string; +} + +interface FindPassword { + phone_number: string; + certification_code: string; + password: string; +} + +export interface Register extends FindPassword { + company_number: string, + name: string, + shop_id: number, + shop_name: string, + attachment_urls: { + file_url: string + }[], +} diff --git a/src/page/Auth/FindPassword/index.tsx b/src/page/Auth/FindPassword/index.tsx index e844813f..087ef37e 100644 --- a/src/page/Auth/FindPassword/index.tsx +++ b/src/page/Auth/FindPassword/index.tsx @@ -1,5 +1,7 @@ import { useOutletContext } from 'react-router-dom'; // eslint-disable-next-line +import ChangePassword from './ChangePassword'; +// eslint-disable-next-line import Verify from './Verify'; export interface OutletProps { @@ -10,6 +12,8 @@ export interface OutletProps { totalStep: number; isComplete: boolean; setIsComplete: React.Dispatch>; + isStepComplete: boolean; + setIsStepComplete: React.Dispatch>; } export default function FindPassword() { @@ -18,7 +22,7 @@ export default function FindPassword() { return ( <> {index === 0 && } - {index === 1 &&
비밀번호 변경
} + {index === 1 && } ); } diff --git a/src/page/Auth/components/Common/index.tsx b/src/page/Auth/components/Common/index.tsx index 332f9a57..5d042f8c 100644 --- a/src/page/Auth/components/Common/index.tsx +++ b/src/page/Auth/components/Common/index.tsx @@ -1,28 +1,29 @@ import { ReactComponent as BackArrow } from 'assets/svg/common/back-arrow.svg'; -import { FormProvider, useForm } from 'react-hook-form'; +import { FormProvider, useForm, UseFormSetError } from 'react-hook-form'; import { Outlet, useLocation, useNavigate } from 'react-router-dom'; import cn from 'utils/ts/className'; +import { Register } from 'model/auth'; // eslint-disable-next-line -import { useStep } from '../../hook/useStep'; +import { changePassword } from 'api/auth'; +import { isKoinError } from '@bcsdlab/koin'; +import { useStep } from 'page/Auth/hook/useStep'; // eslint-disable-next-line import Done from '../Done/index'; import styles from './index.module.scss'; -interface FindPassword { - phone_number: string; - certification_code: string; - password: string; -} - -interface Register extends FindPassword { - company_number: string, - name: string, - shop_id: number, - shop_name: string, - attachment_urls: { - file_url: string - }[], -} +const setNewPassword = ( + phone_number: string, + password: string, + setError: UseFormSetError, +) => { + changePassword({ phone_number, password }) + .then(() => sessionStorage.removeItem('accessToken')) + .catch((e) => { + if (isKoinError(e)) { + setError('password', { type: 'custom', message: e.message }); + } + }); +}; export default function CommonLayout() { const location = useLocation(); @@ -34,7 +35,7 @@ export default function CommonLayout() { const method = useForm({ mode: 'onChange', }); - const { formState: { errors } } = method; + const { formState: { errors }, setError, getValues } = method; const steps = useStep(isFindPassword ? 'find' : 'register'); const { @@ -48,6 +49,7 @@ export default function CommonLayout() { const stepCheck = () => { if (isComplete) navigate('/login'); if (!errors.root) { + if (index + 1 === totalStep && isFindPassword) setNewPassword(getValues('phone_number'), getValues('password'), setError); nextStep(); } }; From e2c79eb534cea8780c3feb1e59541a8e5af47956 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 11:58:47 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B3=80=EA=B2=BD=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FindPassword/ChangePassword/index.tsx | 71 +++++++++++++++++++ .../FindPassword/Verify/index.module.scss | 5 ++ 2 files changed, 76 insertions(+) create mode 100644 src/page/Auth/FindPassword/ChangePassword/index.tsx diff --git a/src/page/Auth/FindPassword/ChangePassword/index.tsx b/src/page/Auth/FindPassword/ChangePassword/index.tsx new file mode 100644 index 00000000..7262f00f --- /dev/null +++ b/src/page/Auth/FindPassword/ChangePassword/index.tsx @@ -0,0 +1,71 @@ +import { useEffect } from 'react'; +import { useFormContext } from 'react-hook-form'; +import { useOutletContext } from 'react-router-dom'; +import { ChangePasswordForm } from 'model/auth'; +// eslint-disable-next-line +import { OutletProps } from 'page/Auth/FindPassword/index'; +// eslint-disable-next-line +import styles from '../Verify/index.module.scss'; + +const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,18}$/; + +export default function ChangePassword() { + const method = useFormContext(); + const { + register, formState: { errors, isValid }, getValues, + } = method; + const steps: OutletProps = useOutletContext(); + const { setIsStepComplete } = steps; + + useEffect(() => { + if (isValid) { + setIsStepComplete(true); + } else { + setIsStepComplete(false); + } + }); + + return ( + +
+
새 비밀번호
+ + {errors.password + ? ( +
+ {errors.password.message} +
+ ) :
* 특수문자 포함 영어와 숫자 6~18 자리
} + +
+
+
새 비밀번호 확인
+ value === getValues('password') || '비밀번호가 일치하지 않습니다.', + })} + /> +
+ {errors.passwordCheck && errors.passwordCheck.message} +
+
+ + ); +} diff --git a/src/page/Auth/FindPassword/Verify/index.module.scss b/src/page/Auth/FindPassword/Verify/index.module.scss index 62c23953..21561641 100644 --- a/src/page/Auth/FindPassword/Verify/index.module.scss +++ b/src/page/Auth/FindPassword/Verify/index.module.scss @@ -64,4 +64,9 @@ .error { color: #f7941e; font-size: 11px; +} + +.comment { + color: #cacaca; + font-size: 11px; } \ No newline at end of file From 9c344e6d09a5d64221b40207ec9435fbb610a118 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 11:58:58 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B0=BE=EA=B8=B0=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 9bb58b0b..f0341d2d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,6 @@ import OwnerLayout from 'layout/OwnerLayout'; import CoopLayout from 'layout/CoopLayout'; import Login from 'page/Auth/Login'; import Signup from 'page/Auth/Signup'; -// import FindPassword from 'page/Auth/FindPassword/SendAuthNumber'; import NewPassword from 'page/Auth/FindPassword/NewPassword'; import CompleteChangePassword from 'page/Auth/FindPassword/CompleteChangePassword'; import AuthLayout from 'layout/AuthLayout'; From bf909a76c3898e1a7dc4e1db796f294e5caf2702 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 18:27:24 +0900 Subject: [PATCH 08/16] =?UTF-8?q?refactor:=20warning=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FindPassword/ChangePassword/index.tsx | 13 ++++++++--- .../FindPassword/Verify/index.module.scss | 3 +++ src/page/Auth/FindPassword/Verify/index.tsx | 22 ++++++++++++++----- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/page/Auth/FindPassword/ChangePassword/index.tsx b/src/page/Auth/FindPassword/ChangePassword/index.tsx index 7262f00f..da6f1fc6 100644 --- a/src/page/Auth/FindPassword/ChangePassword/index.tsx +++ b/src/page/Auth/FindPassword/ChangePassword/index.tsx @@ -4,6 +4,7 @@ import { useOutletContext } from 'react-router-dom'; import { ChangePasswordForm } from 'model/auth'; // eslint-disable-next-line import { OutletProps } from 'page/Auth/FindPassword/index'; +import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; // eslint-disable-next-line import styles from '../Verify/index.module.scss'; @@ -47,6 +48,7 @@ export default function ChangePassword() { {errors.password ? (
+ {errors.password.message}
) :
* 특수문자 포함 영어와 숫자 6~18 자리
} @@ -62,9 +64,14 @@ export default function ChangePassword() { validate: (value) => value === getValues('password') || '비밀번호가 일치하지 않습니다.', })} /> -
- {errors.passwordCheck && errors.passwordCheck.message} -
+ + {errors.passwordCheck + && ( +
+ + {errors.passwordCheck.message} +
+ )}
); diff --git a/src/page/Auth/FindPassword/Verify/index.module.scss b/src/page/Auth/FindPassword/Verify/index.module.scss index 21561641..6478dae6 100644 --- a/src/page/Auth/FindPassword/Verify/index.module.scss +++ b/src/page/Auth/FindPassword/Verify/index.module.scss @@ -64,6 +64,9 @@ .error { color: #f7941e; font-size: 11px; + display: flex; + align-items: center; + gap: 5px; } .comment { diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx index 6d3c9aff..78a60d2a 100644 --- a/src/page/Auth/FindPassword/Verify/index.tsx +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -7,6 +7,7 @@ import { } from 'react-hook-form'; import { useOutletContext } from 'react-router-dom'; import cn from 'utils/ts/className'; +import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; import styles from './index.module.scss'; // eslint-disable-next-line import { OutletProps } from '..'; @@ -112,9 +113,14 @@ export default function Verify() { type="text" placeholder="-없이 번호를 입력해주세요." /> -
- {errors.phone_number && errors.phone_number.message} -
+ + {errors.phone_number + && ( +
+ + {errors.phone_number.message} +
+ )}
인증번호
@@ -141,9 +147,13 @@ export default function Verify() { {isSent ? '인증번호 재발송' : '인증번호 발송'} -
- {errors.certification_code && errors.certification_code.message} -
+ {errors.certification_code + && ( +
+ + {errors.certification_code.message} +
+ )}
); From 29cd4fd20f0f93ba9c27272f5cf5474629d063a6 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 18:29:02 +0900 Subject: [PATCH 09/16] =?UTF-8?q?chore:=20scss=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FindPassword/ChangePassword/index.tsx | 3 +- src/page/Auth/FindPassword/Verify/index.tsx | 2 +- src/page/Auth/FindPassword/index.module.scss | 75 +++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/page/Auth/FindPassword/index.module.scss diff --git a/src/page/Auth/FindPassword/ChangePassword/index.tsx b/src/page/Auth/FindPassword/ChangePassword/index.tsx index da6f1fc6..12751105 100644 --- a/src/page/Auth/FindPassword/ChangePassword/index.tsx +++ b/src/page/Auth/FindPassword/ChangePassword/index.tsx @@ -5,8 +5,7 @@ import { ChangePasswordForm } from 'model/auth'; // eslint-disable-next-line import { OutletProps } from 'page/Auth/FindPassword/index'; import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; -// eslint-disable-next-line -import styles from '../Verify/index.module.scss'; +import styles from 'page/Auth/FindPassword/index.module.scss'; const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,18}$/; diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx index 78a60d2a..4cd30edb 100644 --- a/src/page/Auth/FindPassword/Verify/index.tsx +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -8,7 +8,7 @@ import { import { useOutletContext } from 'react-router-dom'; import cn from 'utils/ts/className'; import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; -import styles from './index.module.scss'; +import styles from 'page/Auth/FindPassword/index.module.scss'; // eslint-disable-next-line import { OutletProps } from '..'; diff --git a/src/page/Auth/FindPassword/index.module.scss b/src/page/Auth/FindPassword/index.module.scss new file mode 100644 index 00000000..6478dae6 --- /dev/null +++ b/src/page/Auth/FindPassword/index.module.scss @@ -0,0 +1,75 @@ +.container { + height: calc(100vh - 30vh); +} + +.section { + display: flex; + flex-direction: column; + justify-content: center; + gap: 10px; + margin-top: 25px; +} + +.title { + font-weight: bold; +} + +.verify { + display: flex; + justify-content: space-between; +} + +.input { + background-color: #f5f5f5; + border-radius: 4px; + border: none; + height: 50px; + padding: 2px 10px; + box-sizing: border-box; + + &--verify { + background-color: #f5f5f5; + border-radius: 4px; + border: none; + height: 50px; + padding: 2px 10px; + box-sizing: border-box; + width: 55%; + } +} + +.button { + background-color: #eeeeee; + border-radius: 4px; + height: 50px; + width: 40%; + + &--active { + background-color: #175C8E; + color: white; + border-radius: 4px; + height: 50px; + width: 40%; + } + + &--error { + background-color: #F7941E; + color: white; + border-radius: 4px; + height: 50px; + width: 40%; + } +} + +.error { + color: #f7941e; + font-size: 11px; + display: flex; + align-items: center; + gap: 5px; +} + +.comment { + color: #cacaca; + font-size: 11px; +} \ No newline at end of file From 9830cf4bfe93f659b6b6ea7ab5f6c349cf473e82 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 20:09:42 +0900 Subject: [PATCH 10/16] =?UTF-8?q?chore:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 6 - .../CompleteChangePassword.module.scss | 51 ------ .../CompleteChangePassword/index.tsx | 32 ---- .../NewPassword/NewPassword.module.scss | 107 ------------- .../Auth/FindPassword/NewPassword/index.tsx | 146 ------------------ .../SendAuthNumber/SendAuthNumber.module.scss | 94 ----------- .../FindPassword/SendAuthNumber/index.tsx | 98 ------------ .../Auth/FindPassword/hooks/useRouteCheck.ts | 16 -- 8 files changed, 550 deletions(-) delete mode 100644 src/page/Auth/FindPassword/CompleteChangePassword/CompleteChangePassword.module.scss delete mode 100644 src/page/Auth/FindPassword/CompleteChangePassword/index.tsx delete mode 100644 src/page/Auth/FindPassword/NewPassword/NewPassword.module.scss delete mode 100644 src/page/Auth/FindPassword/NewPassword/index.tsx delete mode 100644 src/page/Auth/FindPassword/SendAuthNumber/SendAuthNumber.module.scss delete mode 100644 src/page/Auth/FindPassword/SendAuthNumber/index.tsx delete mode 100644 src/page/Auth/FindPassword/hooks/useRouteCheck.ts diff --git a/src/App.tsx b/src/App.tsx index f0341d2d..e5c7f820 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,8 +5,6 @@ import OwnerLayout from 'layout/OwnerLayout'; import CoopLayout from 'layout/CoopLayout'; import Login from 'page/Auth/Login'; import Signup from 'page/Auth/Signup'; -import NewPassword from 'page/Auth/FindPassword/NewPassword'; -import CompleteChangePassword from 'page/Auth/FindPassword/CompleteChangePassword'; import AuthLayout from 'layout/AuthLayout'; import MyShopPage from 'page/MyShopPage'; import ShopRegistration from 'page/ShopRegistration'; @@ -80,11 +78,7 @@ function App() { } /> } /> - } /> - } /> - } /> - } /> diff --git a/src/page/Auth/FindPassword/CompleteChangePassword/CompleteChangePassword.module.scss b/src/page/Auth/FindPassword/CompleteChangePassword/CompleteChangePassword.module.scss deleted file mode 100644 index bf6a6cc7..00000000 --- a/src/page/Auth/FindPassword/CompleteChangePassword/CompleteChangePassword.module.scss +++ /dev/null @@ -1,51 +0,0 @@ -.template { - display: flex; - justify-content: center; - align-items: center; - padding-top: 220px; - padding-bottom: 120px; - flex-direction: column; -} - -.circle-icon { - width: 160px; - height: 160px; - border-radius: 160px; - border: 8px solid #f7941e; - display: flex; - justify-content: center; - align-items: center; -} - -.content { - font-style: normal; - line-height: normal; - - &__title { - margin-top: 70px; - color: #175c8e; - text-align: center; - font-size: 36px; - font-weight: 700; - } - - &__description { - margin-top: 20px; - color: #858585; - text-align: center; - font-size: 18px; - font-weight: 400; - } - - &__button { - margin-top: 80px; - width: 368px; - height: 48px; - background-color: #175c8e; - color: white; - font-size: 16px; - font-style: normal; - font-weight: 500; - cursor: pointer; - } -} diff --git a/src/page/Auth/FindPassword/CompleteChangePassword/index.tsx b/src/page/Auth/FindPassword/CompleteChangePassword/index.tsx deleted file mode 100644 index 25cb16ba..00000000 --- a/src/page/Auth/FindPassword/CompleteChangePassword/index.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { ReactComponent as Check } from 'assets/svg/auth/check.svg'; -import { useNavigate } from 'react-router-dom'; -import { useRouteCheck } from 'page/Auth/FindPassword/hooks/useRouteCheck'; -import styles from './CompleteChangePassword.module.scss'; - -export default function CompleteChangePassword() { - const navigate = useNavigate(); - useRouteCheck('new-password', '/new-password'); - - return ( -
-
- -
-
-
비밀번호 변경 완료
-
- 비밀번호가 변경되었습니다. -
- 새로운 비밀번호로 로그인 부탁드립니다. -
- -
-
- ); -} diff --git a/src/page/Auth/FindPassword/NewPassword/NewPassword.module.scss b/src/page/Auth/FindPassword/NewPassword/NewPassword.module.scss deleted file mode 100644 index ca890b73..00000000 --- a/src/page/Auth/FindPassword/NewPassword/NewPassword.module.scss +++ /dev/null @@ -1,107 +0,0 @@ -.template { - display: flex; - justify-content: center; - align-items: center; - padding-top: 220px; - padding-bottom: 120px; - flex-direction: column; -} - -.logo { - margin: auto; -} - -.cursor-pointer { - cursor: pointer; - background: none; - border: none; -} - -.form { - width: 368px; - margin-top: 48px; - display: flex; - flex-direction: column; - gap: 16px; - - &__input { - width: 368px; - height: 48px; - padding: 14px 16px; - color: #222; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: normal; - box-sizing: border-box; - outline: none; - border: none; - } - - &__input-container { - display: flex; - align-items: center; - border: 1px solid #d2dae2; - padding-right: 16px; - - &--error { - border: 1px solid #f7941e; - } - - &--normal { - border: 1px solid #d2dae2; - } - } - - &__label { - color: #252525; - font-size: 18px; - font-style: normal; - font-weight: 500; - line-height: normal; - display: flex; - flex-direction: column; - gap: 8px; - } - - &__tip { - color: #d2dae2; - font-size: 12px; - font-style: normal; - font-weight: 400; - line-height: normal; - - &--error { - display: none; - } - } - - &__button { - width: 368px; - height: 48px; - color: white; - background: #175c8e; - cursor: pointer; - margin-top: 250px; - box-sizing: border-box; - - &:disabled { - background-color: #c4c4c4; - } - } - - &__error { - display: flex; - color: #f7941e; - font-size: 12px; - align-items: center; - gap: 8px; - } -} - -.input-container { - display: flex; - align-items: center; - border: 1px solid #d2dae2; - padding-right: 16px; -} diff --git a/src/page/Auth/FindPassword/NewPassword/index.tsx b/src/page/Auth/FindPassword/NewPassword/index.tsx deleted file mode 100644 index 91ca1666..00000000 --- a/src/page/Auth/FindPassword/NewPassword/index.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { ReactComponent as KoinLogo } from 'assets/svg/auth/koin-logo.svg'; -import { ReactComponent as ShowIcon } from 'assets/svg/auth/show.svg'; -import { ReactComponent as BlindIcon } from 'assets/svg/auth/blind.svg'; -import { ReactComponent as ErrorIcon } from 'assets/svg/error/auth-error.svg'; -import { useRouteCheck } from 'page/Auth/FindPassword/hooks/useRouteCheck'; -import useBooleanState from 'utils/hooks/useBooleanState'; -import { useState } from 'react'; -import { useNewPassword } from 'query/auth'; -import useEmailAuthStore from 'store/useEmailAuth'; -import cn from 'utils/ts/className'; -import sha256 from 'utils/ts/SHA-256'; -import styles from './NewPassword.module.scss'; - -export default function NewPassword() { - const [password, setPassword] = useState(''); - const [passwordCheck, setPasswordCheck] = useState(''); - const [passwordError, setPasswordError] = useState(''); - const [passwordCheckError, setPasswordCheckError] = useState(''); - const { value: isBlind, changeValue: changeIsBlind } = useBooleanState(true); - const { email } = useEmailAuthStore(); - const submit = useNewPassword(); - useRouteCheck('find-password', '/find-password'); - - const handlePasswordChange = (e: React.ChangeEvent) => { - const { value } = e.target; - setPassword(value); - - const PASSWORD_REG_EX = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{6,18}$/; - if (!PASSWORD_REG_EX.test(value)) { - setPasswordError('비밀번호가 조건에 충족하지 않습니다.'); - } else { - setPasswordError(''); - } - }; - - const handlePasswordCheckChange = (e: React.ChangeEvent) => { - const { value } = e.target; - setPasswordCheck(value); - - if (password !== value) { - setPasswordCheckError('비밀번호가 일치하지 않습니다.'); - } else { - setPasswordCheckError(''); - } - }; - - const handleSubmit = async (e: React.MouseEvent) => { - e.preventDefault(); - const hashedPassword = await sha256(password); - if (!passwordError) { - submit({ email, password: hashedPassword }); - } - }; - - return ( -
- -
- - - * 특수문자 포함 영어와 숫자 조합 6~18자리 - - - -
-
- ); -} diff --git a/src/page/Auth/FindPassword/SendAuthNumber/SendAuthNumber.module.scss b/src/page/Auth/FindPassword/SendAuthNumber/SendAuthNumber.module.scss deleted file mode 100644 index ae3d1172..00000000 --- a/src/page/Auth/FindPassword/SendAuthNumber/SendAuthNumber.module.scss +++ /dev/null @@ -1,94 +0,0 @@ -.template { - display: flex; - justify-content: center; - align-items: center; - padding-top: 220px; - padding-bottom: 120px; - flex-direction: column; -} - -.logo { - margin: auto; -} - -.form { - width: 368px; - margin-top: 48px; - display: flex; - flex-direction: column; - gap: 20px; - - &__input { - width: 368px; - height: 48px; - padding: 14px 16px; - border: 1px solid #d2dae2; - color: #222; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: normal; - box-sizing: border-box; - - &--auth { - width: 255px; - } - - &--error { - border: 1px solid #f7941e; - } - - &--normal { - border: 1px solid #d2dae2; - } - } - - &__label { - color: #252525; - font-size: 18px; - font-style: normal; - font-weight: 500; - line-height: normal; - cursor: pointer; - display: flex; - flex-direction: column; - gap: 8px; - } - - &__error { - display: flex; - color: #f7941e; - font-size: 12px; - align-items: center; - gap: 8px; - } -} - -.auth-button { - width: 97px; - height: 48px; - background-color: #175c8e; - color: white; - cursor: pointer; -} - -.submit { - width: 368px; - height: 48px; - color: white; - background: #175c8e; - cursor: pointer; - margin-top: 250px; - box-sizing: border-box; - - &:disabled { - background-color: #c4c4c4; - } -} - -.auth-container { - display: flex; - flex-direction: row; - align-items: center; - gap: 16px; -} diff --git a/src/page/Auth/FindPassword/SendAuthNumber/index.tsx b/src/page/Auth/FindPassword/SendAuthNumber/index.tsx deleted file mode 100644 index 40a250dc..00000000 --- a/src/page/Auth/FindPassword/SendAuthNumber/index.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { Outlet } from 'react-router-dom'; -import { ReactComponent as KoinLogo } from 'assets/svg/auth/koin-logo.svg'; -import { ReactComponent as ErrorIcon } from 'assets/svg/error/auth-error.svg'; -import { useEffect, useState } from 'react'; -import cn from 'utils/ts/className'; -import { useVerifyEmail, useSubmit } from 'query/auth'; -import useEmailAuthStore from 'store/useEmailAuth'; -import styles from './SendAuthNumber.module.scss'; - -export default function FindPassword() { - const { email, setEmail } = useEmailAuthStore(); - const [verify, setVerify] = useState(''); - const { verifyEmail } = useVerifyEmail(); - const { authNumber } = useSubmit(); - - useEffect(() => { - const handleBeforeUnload = () => { - sessionStorage.removeItem('email-storage'); - setEmail(''); - }; - window.addEventListener('beforeunload', handleBeforeUnload); - - return () => { - window.removeEventListener('beforeunload', handleBeforeUnload); - }; - }, [setEmail]); - - return ( - <> -
- -
- - - -
-
- - - ); -} diff --git a/src/page/Auth/FindPassword/hooks/useRouteCheck.ts b/src/page/Auth/FindPassword/hooks/useRouteCheck.ts deleted file mode 100644 index a6fc4f97..00000000 --- a/src/page/Auth/FindPassword/hooks/useRouteCheck.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { useEffect } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; - -type Route = 'new-password' | 'find-password'; - -export const useRouteCheck = (prevRoute: Route, entryRoute: string) => { - const location = useLocation(); - const navigate = useNavigate(); - - useEffect(() => { - const hasPrevState = location.state && (prevRoute in location.state); - if (!hasPrevState) { - navigate(entryRoute, { replace: true }); - } - }, [location.state, navigate, entryRoute, prevRoute]); -}; From 297e8b30d067aacf5c7fa77a5d31e922fd2660b3 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 20:10:13 +0900 Subject: [PATCH 11/16] =?UTF-8?q?refactor:=20import=20cycle=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Auth/FindPassword/ChangePassword/index.tsx | 3 +-- src/page/Auth/FindPassword/Verify/index.tsx | 3 +-- src/page/Auth/FindPassword/entity.ts | 11 +++++++++++ src/page/Auth/FindPassword/index.tsx | 15 +-------------- 4 files changed, 14 insertions(+), 18 deletions(-) create mode 100644 src/page/Auth/FindPassword/entity.ts diff --git a/src/page/Auth/FindPassword/ChangePassword/index.tsx b/src/page/Auth/FindPassword/ChangePassword/index.tsx index 12751105..4ccefd5c 100644 --- a/src/page/Auth/FindPassword/ChangePassword/index.tsx +++ b/src/page/Auth/FindPassword/ChangePassword/index.tsx @@ -2,8 +2,7 @@ import { useEffect } from 'react'; import { useFormContext } from 'react-hook-form'; import { useOutletContext } from 'react-router-dom'; import { ChangePasswordForm } from 'model/auth'; -// eslint-disable-next-line -import { OutletProps } from 'page/Auth/FindPassword/index'; +import { OutletProps } from 'page/Auth/FindPassword/entity'; import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; import styles from 'page/Auth/FindPassword/index.module.scss'; diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx index 4cd30edb..06927be2 100644 --- a/src/page/Auth/FindPassword/Verify/index.tsx +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -9,8 +9,7 @@ import { useOutletContext } from 'react-router-dom'; import cn from 'utils/ts/className'; import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; import styles from 'page/Auth/FindPassword/index.module.scss'; -// eslint-disable-next-line -import { OutletProps } from '..'; +import { OutletProps } from 'page/Auth/FindPassword/entity'; // 코드 발송 및 에러 처리 const code = ( diff --git a/src/page/Auth/FindPassword/entity.ts b/src/page/Auth/FindPassword/entity.ts new file mode 100644 index 00000000..661e5788 --- /dev/null +++ b/src/page/Auth/FindPassword/entity.ts @@ -0,0 +1,11 @@ +export interface OutletProps { + nextStep: () => void; + previousStep: () => void; + currentStep: string; + index: number; + totalStep: number; + isComplete: boolean; + setIsComplete: React.Dispatch>; + isStepComplete: boolean; + setIsStepComplete: React.Dispatch>; +} diff --git a/src/page/Auth/FindPassword/index.tsx b/src/page/Auth/FindPassword/index.tsx index 087ef37e..a5418a56 100644 --- a/src/page/Auth/FindPassword/index.tsx +++ b/src/page/Auth/FindPassword/index.tsx @@ -1,21 +1,8 @@ import { useOutletContext } from 'react-router-dom'; -// eslint-disable-next-line import ChangePassword from './ChangePassword'; -// eslint-disable-next-line +import { OutletProps } from './entity'; import Verify from './Verify'; -export interface OutletProps { - nextStep: () => void; - previousStep: () => void; - currentStep: string; - index: number; - totalStep: number; - isComplete: boolean; - setIsComplete: React.Dispatch>; - isStepComplete: boolean; - setIsStepComplete: React.Dispatch>; -} - export default function FindPassword() { const steps: OutletProps = useOutletContext(); const { index } = steps; From c6c1c903d621eb91460049f06ad3a940f97a4897 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 20:21:08 +0900 Subject: [PATCH 12/16] =?UTF-8?q?fix:=20lint=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/Auth/FindPassword/Verify/index.module.scss | 8 ++++---- src/page/Auth/FindPassword/index.module.scss | 8 ++++---- src/page/Auth/components/Common/index.module.scss | 13 +++++++------ src/page/Auth/components/Done/index.module.scss | 4 ++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/page/Auth/FindPassword/Verify/index.module.scss b/src/page/Auth/FindPassword/Verify/index.module.scss index 6478dae6..f214a248 100644 --- a/src/page/Auth/FindPassword/Verify/index.module.scss +++ b/src/page/Auth/FindPassword/Verify/index.module.scss @@ -28,7 +28,7 @@ box-sizing: border-box; &--verify { - background-color: #f5f5f5; + background-color: #f5f5f5; border-radius: 4px; border: none; height: 50px; @@ -45,7 +45,7 @@ width: 40%; &--active { - background-color: #175C8E; + background-color: #175c8e; color: white; border-radius: 4px; height: 50px; @@ -53,7 +53,7 @@ } &--error { - background-color: #F7941E; + background-color: #f7941e; color: white; border-radius: 4px; height: 50px; @@ -72,4 +72,4 @@ .comment { color: #cacaca; font-size: 11px; -} \ No newline at end of file +} diff --git a/src/page/Auth/FindPassword/index.module.scss b/src/page/Auth/FindPassword/index.module.scss index 6478dae6..f214a248 100644 --- a/src/page/Auth/FindPassword/index.module.scss +++ b/src/page/Auth/FindPassword/index.module.scss @@ -28,7 +28,7 @@ box-sizing: border-box; &--verify { - background-color: #f5f5f5; + background-color: #f5f5f5; border-radius: 4px; border: none; height: 50px; @@ -45,7 +45,7 @@ width: 40%; &--active { - background-color: #175C8E; + background-color: #175c8e; color: white; border-radius: 4px; height: 50px; @@ -53,7 +53,7 @@ } &--error { - background-color: #F7941E; + background-color: #f7941e; color: white; border-radius: 4px; height: 50px; @@ -72,4 +72,4 @@ .comment { color: #cacaca; font-size: 11px; -} \ No newline at end of file +} diff --git a/src/page/Auth/components/Common/index.module.scss b/src/page/Auth/components/Common/index.module.scss index 2e0ee9ab..00c402a1 100644 --- a/src/page/Auth/components/Common/index.module.scss +++ b/src/page/Auth/components/Common/index.module.scss @@ -20,9 +20,9 @@ &__back { position: absolute; - left: 0px; + left: 0; cursor: pointer; - + @include media.media-breakpoint-up(mobile) { display: none; } @@ -42,7 +42,7 @@ &__progress { display: flex; justify-content: space-between; - color: #175C8E; + color: #175c8e; font-weight: 600; margin: 10px 0; } @@ -79,10 +79,11 @@ font-weight: 600; &--active { - width: 100%; - background-color: #175C8E; + width: 100%; + background-color: #175c8e; height: 50px; border-radius: 4px; font-weight: 600; + color: white; } -} \ No newline at end of file +} diff --git a/src/page/Auth/components/Done/index.module.scss b/src/page/Auth/components/Done/index.module.scss index 6697498c..923c1136 100644 --- a/src/page/Auth/components/Done/index.module.scss +++ b/src/page/Auth/components/Done/index.module.scss @@ -11,11 +11,11 @@ } .title { - color: #175C8E; + color: #175c8e; font-weight: bold; } .content { color: #8e8e8e; text-align: center; -} \ No newline at end of file +} From 6331b929583e27a201c143523f5cbb80503bd66f Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 20:30:24 +0900 Subject: [PATCH 13/16] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=20=EC=9E=85=EB=A0=A5=EC=9C=BC=EB=A1=9C=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=8B=9C=20=EC=97=90=EB=9F=AC=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/Auth/FindPassword/ChangePassword/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/page/Auth/FindPassword/ChangePassword/index.tsx b/src/page/Auth/FindPassword/ChangePassword/index.tsx index 4ccefd5c..795bac47 100644 --- a/src/page/Auth/FindPassword/ChangePassword/index.tsx +++ b/src/page/Auth/FindPassword/ChangePassword/index.tsx @@ -11,13 +11,14 @@ const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6 export default function ChangePassword() { const method = useFormContext(); const { - register, formState: { errors, isValid }, getValues, + register, formState: { errors, isValid }, getValues, clearErrors, } = method; const steps: OutletProps = useOutletContext(); const { setIsStepComplete } = steps; useEffect(() => { if (isValid) { + clearErrors(); setIsStepComplete(true); } else { setIsStepComplete(false); From 7f4a4d619098e9c18dbe9cb5bb54cb0780528cec Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 22:18:26 +0900 Subject: [PATCH 14/16] =?UTF-8?q?feat:=20useDebounce=20=ED=9B=85=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks/useDebounce.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/utils/hooks/useDebounce.ts diff --git a/src/utils/hooks/useDebounce.ts b/src/utils/hooks/useDebounce.ts new file mode 100644 index 00000000..abf1cd46 --- /dev/null +++ b/src/utils/hooks/useDebounce.ts @@ -0,0 +1,13 @@ +import { useState } from 'react'; + +export function useDebounce(func: (data: T) => void, param: T, delay?: number): () => void { + const [id, setId] = useState(null); + + const debounce = () => { + if (id) clearTimeout(id); + const timeId = setTimeout(() => func(param), delay ?? 200); + setId(timeId); + }; + + return debounce; +} From 00213a12c69251b1dc26480828cc29162b7fd3e3 Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Fri, 7 Jun 2024 22:18:48 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20useDebouce=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/page/Auth/FindPassword/Verify/index.tsx | 28 ++++++++++++--------- src/page/Auth/components/Common/index.tsx | 4 ++- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx index 06927be2..125cee71 100644 --- a/src/page/Auth/FindPassword/Verify/index.tsx +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -1,4 +1,4 @@ -import { isKoinError } from '@bcsdlab/koin'; +import { isKoinError, sendClientError } from '@bcsdlab/koin'; import { sendVerifyCode, verifyCode } from 'api/auth'; import { ChangeEvent, useEffect, useState } from 'react'; import { @@ -10,12 +10,21 @@ import cn from 'utils/ts/className'; import { ReactComponent as Warning } from 'assets/svg/auth/warning.svg'; import styles from 'page/Auth/FindPassword/index.module.scss'; import { OutletProps } from 'page/Auth/FindPassword/entity'; +import { useDebounce } from 'utils/hooks/useDebounce'; + +interface SendCode { + getValues: UseFormGetValues; + setError: UseFormSetError; + setIsSent: React.Dispatch>; +} // 코드 발송 및 에러 처리 const code = ( - getValues: UseFormGetValues, - setError: UseFormSetError, - setIsSent: React.Dispatch>, + { + getValues, + setError, + setIsSent, + }: SendCode, ) => { sendVerifyCode(getValues('phone_number')) .then(() => setIsSent(true)) @@ -49,6 +58,8 @@ const useCheckCode = ( .catch((e) => { if (isKoinError(e)) { setError('certification_code', { type: 'error', message: e.message }); + } else { + sendClientError(e); } setIsStepComplete(false); }); @@ -69,7 +80,7 @@ export default function Verify() { register, getValues, setError, formState: { errors }, watch, clearErrors, } = method; const [isSent, setIsSent] = useState(false); - const [id, setId] = useState(null); + const debounce = useDebounce(code, { getValues, setError, setIsSent }); const steps: OutletProps = useOutletContext(); const { setCertificationCode, isCertified } = useCheckCode( @@ -79,13 +90,6 @@ export default function Verify() { clearErrors, ); - // 디바운싱 - const debounce = () => { - if (id) clearTimeout(id); - const timeId = setTimeout(() => code(getValues, setError, setIsSent), 200); - setId(timeId); - }; - const sendCode = () => { if (getValues('phone_number').length === 0) { setError('phone_number', { type: 'custom', message: '필수 입력 항목입니다.' }); diff --git a/src/page/Auth/components/Common/index.tsx b/src/page/Auth/components/Common/index.tsx index 5d042f8c..ba1fb073 100644 --- a/src/page/Auth/components/Common/index.tsx +++ b/src/page/Auth/components/Common/index.tsx @@ -5,7 +5,7 @@ import cn from 'utils/ts/className'; import { Register } from 'model/auth'; // eslint-disable-next-line import { changePassword } from 'api/auth'; -import { isKoinError } from '@bcsdlab/koin'; +import { isKoinError, sendClientError } from '@bcsdlab/koin'; import { useStep } from 'page/Auth/hook/useStep'; // eslint-disable-next-line import Done from '../Done/index'; @@ -21,6 +21,8 @@ const setNewPassword = ( .catch((e) => { if (isKoinError(e)) { setError('password', { type: 'custom', message: e.message }); + } else { + sendClientError(e); } }); }; From ad8b69a0eadf43912ef20980cc4ffd76896c155b Mon Sep 17 00:00:00 2001 From: chaeseungyun Date: Sat, 8 Jun 2024 17:43:20 +0900 Subject: [PATCH 16/16] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B0=80=EB=8F=85=EC=84=B1=20=ED=96=A5=EC=83=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FindPassword/ChangePassword/index.tsx | 32 +++++++++++-------- src/page/Auth/FindPassword/Verify/index.tsx | 11 ++++--- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/page/Auth/FindPassword/ChangePassword/index.tsx b/src/page/Auth/FindPassword/ChangePassword/index.tsx index 795bac47..a2d0f933 100644 --- a/src/page/Auth/FindPassword/ChangePassword/index.tsx +++ b/src/page/Auth/FindPassword/ChangePassword/index.tsx @@ -9,10 +9,10 @@ import styles from 'page/Auth/FindPassword/index.module.scss'; const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,18}$/; export default function ChangePassword() { - const method = useFormContext(); const { register, formState: { errors, isValid }, getValues, clearErrors, - } = method; + } = useFormContext(); + const steps: OutletProps = useOutletContext(); const { setIsStepComplete } = steps; @@ -44,13 +44,19 @@ export default function ChangePassword() { }, })} /> - {errors.password - ? ( -
- - {errors.password.message} -
- ) :
* 특수문자 포함 영어와 숫자 6~18 자리
} + { + errors.password + ? ( +
+ + {errors.password.message} +
+ ) : ( +
+ * 특수문자 포함 영어와 숫자 6~18 자리 +
+ ) + }
@@ -63,14 +69,14 @@ export default function ChangePassword() { validate: (value) => value === getValues('password') || '비밀번호가 일치하지 않습니다.', })} /> - - {errors.passwordCheck - && ( + { + errors.passwordCheck && (
{errors.passwordCheck.message}
- )} + ) + }
); diff --git a/src/page/Auth/FindPassword/Verify/index.tsx b/src/page/Auth/FindPassword/Verify/index.tsx index 125cee71..072c4dd2 100644 --- a/src/page/Auth/FindPassword/Verify/index.tsx +++ b/src/page/Auth/FindPassword/Verify/index.tsx @@ -75,10 +75,10 @@ interface Verify { } export default function Verify() { - const method = useFormContext(); const { register, getValues, setError, formState: { errors }, watch, clearErrors, - } = method; + } = useFormContext(); + const [isSent, setIsSent] = useState(false); const debounce = useDebounce(code, { getValues, setError, setIsSent }); const steps: OutletProps = useOutletContext(); @@ -150,13 +150,14 @@ export default function Verify() { {isSent ? '인증번호 재발송' : '인증번호 발송'} - {errors.certification_code - && ( + { + errors.certification_code && (
{errors.certification_code.message}
- )} + ) + } );