Skip to content

Commit 0d79f10

Browse files
authored
Merge pull request #308 from prgrms-web-devcourse-final-project/refactor/sign-up-2
[REFACTOR] 회원가입 페이지 리펙토링
2 parents e548749 + 9c5ca0f commit 0d79f10

File tree

12 files changed

+100
-145
lines changed

12 files changed

+100
-145
lines changed

src/pages/editprofile/components/CurrentPasswordInput.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import { InputField } from '@/components/input';
22

33
interface CurrentPasswordInputPros {
4-
setValidity: (val: boolean) => void;
4+
onChange: (val: string) => void;
55
}
66

7-
function CurrentPasswordInput({ setValidity }: CurrentPasswordInputPros) {
7+
function CurrentPasswordInput({ onChange }: CurrentPasswordInputPros) {
88
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
9-
setValidity(e.target.value.length > 0);
9+
onChange(e.target.value);
1010
};
1111
return (
1212
<InputField
1313
type="password"
1414
id="current-password"
15-
name="current-password"
1615
onChange={handleChange}
1716
label="현재 비밀번호"
1817
placeholder="현재 비밀번호을 입력해 주세요"

src/pages/editprofile/components/PasswordEditForm.tsx

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,9 @@ function PasswordEditForm() {
1111
const navigate = useNavigate();
1212
const { openModal, closeModal } = useModalStore(); // 모달 관리
1313

14-
const [validity, setValidity] = useState({
15-
currentPassword: false,
16-
password: false,
17-
});
18-
19-
const buttonEnabled = Object.values(validity).every(Boolean);
20-
21-
// validity 업데이트 함수
22-
const updateValidity = (key: 'currentPassword' | 'password', value: boolean) => {
23-
setValidity((prev) => {
24-
if (prev[key] === value) return prev; // 값이 동일하면 변경 X
25-
return { ...prev, [key]: value };
26-
});
27-
};
28-
14+
const [currentPassword, setCurrentPassword] = useState('');
15+
const [password, setPassword] = useState('');
16+
const isButtonEnabled = currentPassword !== '' && password !== '';
2917
// 현재 비밀번호 확인 useMutation
3018
const {
3119
mutateAsync: checkCurrentPassword,
@@ -60,9 +48,6 @@ function PasswordEditForm() {
6048

6149
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
6250
e.preventDefault();
63-
const formData = new FormData(e.currentTarget);
64-
const currentPassword = formData.get('current-password') as string;
65-
const password = formData.get('password') as string;
6651
// 현재 비밀번호 확인
6752
try {
6853
await checkCurrentPassword(currentPassword);
@@ -103,9 +88,9 @@ function PasswordEditForm() {
10388
return (
10489
<form className="flex flex-col justify-between h-full p-5" onSubmit={handleSubmit}>
10590
<div className="flex flex-col">
106-
<CurrentPasswordInput setValidity={(value) => updateValidity('currentPassword', value)} />
91+
<CurrentPasswordInput onChange={setCurrentPassword} />
10792
<PasswordGroupSection
108-
setValidity={(value) => updateValidity('password', value)}
93+
onChange={setPassword}
10994
passwordLabel="새 비밀번호"
11095
confirmLabel="새 비밀번호 확인"
11196
passwordPlaceholder="새 비밀번호를 입력해 주세요"
@@ -116,7 +101,7 @@ function PasswordEditForm() {
116101
isLoading={isCheckingPassword || isChangingPassword}
117102
isSuccess={isSuccess}
118103
isError={isCheckPasswordError || isChangePasswordError}
119-
disabled={!buttonEnabled}
104+
disabled={!isButtonEnabled}
120105
type="submit"
121106
text="저장하기"
122107
/>

src/pages/editprofile/components/ProfileEditForm.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ function ProfileEditForm() {
3636

3737
const [isMusicSelect, setIsMusicSelect] = useState(false);
3838
const [nickname, setNickname] = useState(''); // 닉네임
39-
const [isNicknameValid, setIsNicknameValid] = useState(false); // 닉네임 유효성
39+
const [isNicknameValid] = useState(false); // 닉네임 유효성
4040

4141
const prevProfileMusic = useRef<ProfileMusic | null>(null);
4242
const prevNickname = useRef<string>('');
@@ -51,8 +51,6 @@ function ProfileEditForm() {
5151
staleTime: 5 * 60 * 1000,
5252
});
5353

54-
// // console.log(userData);
55-
5654
const { mutate, isPending, isSuccess, isError } = useMutation({
5755
mutationFn: patchEditProfile,
5856
onSuccess: (data) => {
@@ -182,7 +180,7 @@ function ProfileEditForm() {
182180
rightElement="button" // 오른쪽 요소 타입
183181
/>
184182
</div>
185-
<NicknameInput initialText={nickname} setValidity={(val) => setIsNicknameValid(val)} />
183+
<NicknameInput initialText={nickname} onChange={setNickname} />
186184
</div>
187185
<Button
188186
type="submit"

src/pages/signup/components/AuthCodeInput.tsx

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { useMutation } from '@tanstack/react-query';
77
import { useState } from 'react';
88

99
interface AuthCodeInputProps {
10+
tempEmail: string;
1011
email: string;
11-
emailValidity: boolean;
12-
setValidity: (val: boolean) => void; // 인증코드 유효성 바꾸는 함수
12+
onChange: (val: string) => void;
1313
}
14-
function AuthCodeInput({ email, emailValidity, setValidity }: AuthCodeInputProps) {
14+
function AuthCodeInput({ email, tempEmail, onChange }: AuthCodeInputProps) {
1515
const { openModal, closeModal } = useModalStore(); // 모달
1616
const [resendCount, setResendCount] = useState(0); // 재전송 횟수
1717
const [text, setText] = useState('');
@@ -25,9 +25,7 @@ function AuthCodeInput({ email, emailValidity, setValidity }: AuthCodeInputProps
2525
setText(value);
2626

2727
// 유효성 검사
28-
const isValid = AUTHCODE_REGEX.test(value);
29-
30-
if (isValid) {
28+
if (AUTHCODE_REGEX.test(value)) {
3129
setValidationStatus({ isValid: true, message: '' });
3230
} else {
3331
setValidationStatus({ isValid: false, message: '올바른 인증번호를 입력해주세요' });
@@ -36,7 +34,7 @@ function AuthCodeInput({ email, emailValidity, setValidity }: AuthCodeInputProps
3634

3735
// 이메일 재전송
3836
const { mutate: resendEmailVerification } = useMutation({
39-
mutationFn: () => postEmailVerificationRequest(email),
37+
mutationFn: () => postEmailVerificationRequest(tempEmail),
4038
onSuccess: ({ code }) => {
4139
if (code === 200) {
4240
setResendCount((count) => count + 1);
@@ -54,11 +52,11 @@ function AuthCodeInput({ email, emailValidity, setValidity }: AuthCodeInputProps
5452
});
5553
// 인증번호 확인
5654
const { mutate: verifyEmail, isPending } = useMutation({
57-
mutationFn: () => postEmailVerificationCheck(email, text),
55+
mutationFn: () => postEmailVerificationCheck(tempEmail, text),
5856
onSuccess: ({ code }) => {
5957
if (code === 200) {
6058
setValidationStatus({ isValid: true, message: '이메일 인증이 완료되었습니다' });
61-
setValidity(true); // 완료 처리
59+
onChange(tempEmail); // 완료 처리
6260
} else {
6361
setValidationStatus({ isValid: false, message: '인증 코드가 올바르지 않습니다' });
6462
}
@@ -107,13 +105,13 @@ function AuthCodeInput({ email, emailValidity, setValidity }: AuthCodeInputProps
107105
onTimeout={onTimeout} // 시간이 만료되었을 때 실행할 함수
108106
onResendEmail={handleResendEmail} // 재전송 요청
109107
resendCount={resendCount} // 재전송 횟수
110-
isEmailVerified={emailValidity}
108+
isEmailVerified={!!email}
111109
actionButton={
112110
<LoadingSpinnerButton
113111
isLoading={isPending}
114112
className="w-[65px] flex-shrink-0"
115-
text={emailValidity ? '인증완료' : '인증확인'}
116-
disabled={!validationStatus.isValid || emailValidity}
113+
text={!!email ? '인증완료' : '인증확인'}
114+
disabled={!validationStatus.isValid || !!email}
117115
onClick={() => verifyEmail()}
118116
/>
119117
}
@@ -122,11 +120,3 @@ function AuthCodeInput({ email, emailValidity, setValidity }: AuthCodeInputProps
122120
}
123121

124122
export default AuthCodeInput;
125-
126-
// setValidationMessage({
127-
// success: false,
128-
// message:
129-
// error.message === '최대 재전송 횟수를 초과'
130-
// ? '최대 재전송 횟수를 초과했습니다.'
131-
// : '이메일 재전송 중 오류가 발생했습니다. 다시 시도해주세요.',
132-
// });

src/pages/signup/components/EmailGroupSection.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ import { AuthCodeInput, EmailInput } from '@/pages/signup/components';
22
import { useState } from 'react';
33

44
interface EmailGroupSectionProps {
5-
setValidity: (val: boolean) => void;
6-
emailValidity: boolean;
5+
onChange: (val: string) => void;
6+
email: string;
77
}
88

9-
const EmailGroupSection = ({ setValidity, emailValidity }: EmailGroupSectionProps) => {
10-
const [email, setEmail] = useState('');
9+
const EmailGroupSection = ({ onChange, email }: EmailGroupSectionProps) => {
10+
// 인증번호 요청 전 입력된 임시 이메일 값
11+
const [tempEmail, setTempEmail] = useState('');
12+
1113
return (
1214
<>
13-
<EmailInput setValidity={setValidity} emailValidity={emailValidity} setEmail={setEmail} />
14-
{email !== '' && (
15-
<AuthCodeInput email={email} emailValidity={emailValidity} setValidity={setValidity} />
15+
<EmailInput onChange={setTempEmail} email={email} />
16+
{tempEmail !== '' && (
17+
<AuthCodeInput tempEmail={tempEmail} onChange={onChange} email={email} />
1618
)}
1719
</>
1820
);

src/pages/signup/components/EmailInput.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import { useMutation } from '@tanstack/react-query';
77
import { useState } from 'react';
88

99
interface EmailInputProps {
10-
setValidity: (val: boolean) => void;
11-
emailValidity: boolean; // 이메일 유효성
12-
setEmail: React.Dispatch<React.SetStateAction<string>>;
10+
onChange: (val: string) => void;
11+
email: string;
1312
}
1413

15-
function EmailInput({ setValidity, emailValidity, setEmail }: EmailInputProps) {
14+
function EmailInput({ onChange, email }: EmailInputProps) {
1615
const { openModal, closeModal } = useModalStore(); // 모달
1716
const [text, setText] = useState('');
1817
const [hasRequested, setHasRequested] = useState(false); // 이미 인증 요청을 했는지
@@ -24,12 +23,9 @@ function EmailInput({ setValidity, emailValidity, setEmail }: EmailInputProps) {
2423
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
2524
const value = e.target.value;
2625
setText(value);
27-
setValidity(false); // form validity 초기화
2826

2927
// 유효성 검사
30-
const isValid = EMAIL_REGEX.test(value);
31-
32-
if (isValid) {
28+
if (EMAIL_REGEX.test(value)) {
3329
setValidationStatus({ isValid: true, message: '' });
3430
} else {
3531
setValidationStatus({
@@ -75,7 +71,7 @@ function EmailInput({ setValidity, emailValidity, setEmail }: EmailInputProps) {
7571
'이메일 인증 메일이 발송되었습니다. 메일함에서 인증번호를 확인 후 입력해주세요',
7672
});
7773
setHasRequested(true);
78-
setEmail(text);
74+
onChange(text);
7975
}
8076
},
8177
onError: () => {
@@ -99,13 +95,13 @@ function EmailInput({ setValidity, emailValidity, setEmail }: EmailInputProps) {
9995
onChange={handleChange}
10096
isValid={validationStatus.isValid}
10197
message={validationStatus.message}
102-
disabled={emailValidity}
98+
disabled={!!email}
10399
actionButton={
104100
<LoadingSpinnerButton
105101
isLoading={isCheckingEmail || isRequestingEmailVerification}
106102
className="w-[65px]"
107-
text={emailValidity ? '인증완료' : '인증요청'}
108-
disabled={!validationStatus.isValid || emailValidity || hasRequested}
103+
text={!!email ? '인증완료' : '인증요청'}
104+
disabled={!validationStatus.isValid || !!email || hasRequested}
109105
onClick={() => checkEmailAvailability()}
110106
/>
111107
}

src/pages/signup/components/IdInput.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import { throttle } from 'lodash';
99
import { useMemo, useState } from 'react';
1010

1111
interface IdInputProps {
12-
setValidity: (val: boolean) => void;
12+
onChange: (val: string) => void;
1313
}
1414

15-
const IdInput = ({ setValidity }: IdInputProps) => {
15+
const IdInput = ({ onChange }: IdInputProps) => {
1616
const { openModal, closeModal } = useModalStore(); // 모달
1717
const [text, setText] = useState('');
1818
const [validationStatus, setValidationStatus] = useState({
@@ -23,7 +23,7 @@ const IdInput = ({ setValidity }: IdInputProps) => {
2323
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
2424
const value = e.target.value;
2525
setText(value);
26-
setValidity(false); // form validity 초기화
26+
onChange(''); // 데이터 초기화
2727

2828
if (ID_REGEX.test(value)) {
2929
setValidationStatus({ isValid: true, message: '' });
@@ -41,7 +41,7 @@ const IdInput = ({ setValidity }: IdInputProps) => {
4141
onSuccess: (data) => {
4242
if (data.code === 200) {
4343
setValidationStatus({ isValid: true, message: '사용 가능한 아이디입니다' });
44-
setValidity(true);
44+
onChange(text);
4545
} else if (data.code === 409) {
4646
setValidationStatus({ isValid: false, message: '이미 사용 중인 아이디입니다' });
4747
}
@@ -62,7 +62,6 @@ const IdInput = ({ setValidity }: IdInputProps) => {
6262
return (
6363
<InputField
6464
id="id"
65-
name="id"
6665
label="아이디"
6766
placeholder="아이디를 입력해 주세요"
6867
onChange={handleChange}

src/pages/signup/components/NicknameInput.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import { useEffect, useMemo, useState } from 'react';
88

99
interface NicknameInputProps {
1010
initialText?: string; // 초기값
11-
setValidity: (val: boolean) => void;
11+
onChange: (val: string) => void;
1212
}
1313

14-
function NicknameInput({ initialText = '', setValidity }: NicknameInputProps) {
14+
function NicknameInput({ initialText = '', onChange }: NicknameInputProps) {
1515
const [text, setText] = useState('');
1616
const [validationStatus, setValidationStatus] = useState({
1717
isValid: false, // 유효성 통과여부
@@ -21,7 +21,7 @@ function NicknameInput({ initialText = '', setValidity }: NicknameInputProps) {
2121
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
2222
const value = e.target.value;
2323
setText(value);
24-
setValidity(false); // form validity 초기화
24+
onChange(''); // form validity 초기화
2525

2626
// 유효성 검사
2727

@@ -47,7 +47,7 @@ function NicknameInput({ initialText = '', setValidity }: NicknameInputProps) {
4747
onSuccess: (data) => {
4848
if (data.code === 200) {
4949
setValidationStatus({ isValid: true, message: '사용 가능한 닉네임입니다' });
50-
setValidity(true);
50+
onChange(text);
5151
} else if (data.code === 409) {
5252
setValidationStatus({ isValid: false, message: '이미 사용 중인 닉네임입니다' });
5353
}
@@ -73,7 +73,6 @@ function NicknameInput({ initialText = '', setValidity }: NicknameInputProps) {
7373
label="닉네임"
7474
placeholder="닉네임을 입력해 주세요"
7575
value={text}
76-
name="nickname"
7776
onChange={handleChange}
7877
message={validationStatus.message}
7978
isValid={validationStatus.isValid}

0 commit comments

Comments
 (0)