From 9ce4434bff66a2ee12b9dd3ffb18e2ac8878c07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=A8=EC=A0=95=EC=9A=B1?= <113816822+HelloWook@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:53:49 +0900 Subject: [PATCH] =?UTF-8?q?fix=20:=20=ED=9A=8C=EC=9B=90=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#247)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore : toast 포지션 수정 * chore : 마이페이지 정규표현식 수정 --- src/features/Toast/ui/Toast.styeld.ts | 1 + src/shared/ui/InputForm/InputForm.tsx | 14 ++++++- src/shared/ui/InputForm/InputForm.types.tsx | 13 ++++--- src/widgets/Mypage/Mypage.tsx | 33 +++++++++------- src/widgets/Mypage/util/RegExp.ts | 7 ++++ src/widgets/Mypage/util/validator.ts | 43 +++++++++++++++++++++ src/widgets/Sign/Sign.tsx | 3 +- 7 files changed, 93 insertions(+), 21 deletions(-) create mode 100644 src/widgets/Mypage/util/RegExp.ts create mode 100644 src/widgets/Mypage/util/validator.ts diff --git a/src/features/Toast/ui/Toast.styeld.ts b/src/features/Toast/ui/Toast.styeld.ts index 23a0e92..daa8a60 100644 --- a/src/features/Toast/ui/Toast.styeld.ts +++ b/src/features/Toast/ui/Toast.styeld.ts @@ -25,6 +25,7 @@ const slideIn = keyframes` `; export const ToastStyled = styled.div` + z-index: 9999; display: flex; align-items: center; justify-content: center; diff --git a/src/shared/ui/InputForm/InputForm.tsx b/src/shared/ui/InputForm/InputForm.tsx index 25e7ec5..e4ac331 100644 --- a/src/shared/ui/InputForm/InputForm.tsx +++ b/src/shared/ui/InputForm/InputForm.tsx @@ -25,6 +25,7 @@ const InputForm = ({ isPassword = false, isDropdown = false, isTextarea = false, + isPhoneNumber = false, options = ['남성', '여성'], onChange, onKeyDown @@ -40,7 +41,14 @@ const InputForm = ({ HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement > ) => { - onChange(e.target.value); + if (isPhoneNumber) { + const formattedValue = e.target.value + .replace(/[^0-9]/g, '') // 숫자만 허용 + .replace(/(\d{3})(\d{3,4})(\d{4})/, '$1-$2-$3'); // 형식 적용 + onChange(formattedValue); + } else { + onChange(e.target.value); + } }; return ( @@ -86,6 +94,10 @@ const InputForm = ({ height={height} onChange={handleInputChange} onKeyDown={onKeyDown} + pattern={ + isPhoneNumber ? '\\d{3}-\\d{3,4}-\\d{4}' : undefined + } + title="전화번호 형식은 010-1234-5678 입니다." /> {isPassword && ( void; // 값 변경 시 호출되는 함수 - onKeyDown?: (e: React.KeyboardEvent) => void; // 엔터키 이벤트 + isPassword?: boolean; + isDropdown?: boolean; + isTextarea?: boolean; + isPhoneNumber?: boolean; + options?: string[]; + onChange: (value: string) => void; + onKeyDown?: (event: React.KeyboardEvent) => void; } diff --git a/src/widgets/Mypage/Mypage.tsx b/src/widgets/Mypage/Mypage.tsx index e8ad22c..6d83323 100644 --- a/src/widgets/Mypage/Mypage.tsx +++ b/src/widgets/Mypage/Mypage.tsx @@ -11,6 +11,7 @@ import useGetUser from '@/features/myPage/hook/useGetUser'; import { useAuthStore } from '@/features/login/hooks/useAuthStore'; import usePatch from '@/features/myPage/hook/usePatch'; import { useNavigate } from 'react-router-dom'; +import { validateForm } from './util/validator'; const Mypage = () => { const { addToast } = useToastStore(); @@ -31,6 +32,20 @@ const Mypage = () => { } }, [data]); + const handleUpdate = () => { + const isValid = validateForm(email, password, phoneNumber, addToast); + + if (!isValid) return; + + mutate({ + email, + username: name, + password, + gender, + phone_number: phoneNumber + }); + }; + return ( @@ -44,7 +59,7 @@ const Mypage = () => { value={name} width="100%" height="52px" - onChange={setPhoneNumber} + onChange={setName} placeholder="이름을 입력해주세요" /> @@ -56,11 +71,11 @@ const Mypage = () => { value={phoneNumber} width="100%" height="52px" - onChange={setName} - placeholder="이름을 입력해주세요" + onChange={setPhoneNumber} + placeholder="전화번호를 입력해주세요" + isPhoneNumber /> - 이메일 {email} @@ -92,15 +107,7 @@ const Mypage = () => { height="44px" width="240px" fontSize="16px" - onClick={() => { - mutate({ - email, - username: userName, - password, - gender, - phone_number: phoneNumber - }); - }} + onClick={handleUpdate} > 수정하기 diff --git a/src/widgets/Mypage/util/RegExp.ts b/src/widgets/Mypage/util/RegExp.ts new file mode 100644 index 0000000..9787264 --- /dev/null +++ b/src/widgets/Mypage/util/RegExp.ts @@ -0,0 +1,7 @@ +export const EMAIL_REG_EXP = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + +export const PASSWORD_REG_EXP = + /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/; + +export const PHONE_NUMBER_REG_EXP: RegExp = + /^(01[016789]-\d{3,4}-\d{4})$|^(0[2-8][0-5]?-?\d{3,4}-\d{4})$/; diff --git a/src/widgets/Mypage/util/validator.ts b/src/widgets/Mypage/util/validator.ts new file mode 100644 index 0000000..d5c9ec2 --- /dev/null +++ b/src/widgets/Mypage/util/validator.ts @@ -0,0 +1,43 @@ +import { + EMAIL_REG_EXP, + PHONE_NUMBER_REG_EXP, + PASSWORD_REG_EXP +} from './RegExp'; + +interface Validation { + condition: boolean; + message: string; +} +type ToastVariant = 'warning' | 'success' | 'error'; + +export function validateForm( + email: string, + password: string, + phoneNumber: string, + addToast: (message: string, type: ToastVariant) => void +): boolean { + const validations: Validation[] = [ + { + condition: !EMAIL_REG_EXP.test(email), + message: '잘못된 이메일 형식입니다.' + }, + { + condition: !PASSWORD_REG_EXP.test(password), + message: '잘못된 비밀번호 형식입니다.' + }, + { + condition: !PHONE_NUMBER_REG_EXP.test(phoneNumber), + message: '잘못된 전화번호 형식입니다.' + } + ]; + + const invalid = validations.some((validation) => { + if (validation.condition) { + addToast(validation.message, 'warning'); + return true; + } + return false; + }); + + return !invalid; +} diff --git a/src/widgets/Sign/Sign.tsx b/src/widgets/Sign/Sign.tsx index 5aa970b..36cdc2c 100644 --- a/src/widgets/Sign/Sign.tsx +++ b/src/widgets/Sign/Sign.tsx @@ -76,7 +76,8 @@ const Sign = () => { width="500px" height="52px" onChange={setPhoneNumber} - placeholder="010-1111-1111 형식으로 입력해주세요" + isPhoneNumber + placeholder="전화번호를 입력해주세요" />