Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: #69 유저 정보 설정 페이지 UI 구현 #78

Merged
merged 19 commits into from
Aug 23, 2024
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a1a0143
Feat: #69 유저 개인정보 설정 페이지 구현
Yoonyesol Aug 16, 2024
6db43d9
Refactor: #69 UserSettingPage에서 이미지, 링크 관련 코드를 컴포넌트로 분리
Yoonyesol Aug 17, 2024
a372a22
Refactor: #69 SignUpPage에서 이미지, 링크 관련 코드를 컴포넌트로 분리
Yoonyesol Aug 17, 2024
80ef5f4
Refactor: #69 이미지 전송을 위해 폼에서 이미지를 처리할 수 있도록 코드 리팩토링
Yoonyesol Aug 17, 2024
1c786b6
Refactor: #69 UserAuthenticatePage의 이메일 인증 로직을 훅으로 분리 및 인증 submit 버튼을…
Yoonyesol Aug 18, 2024
7cf194c
Refactor: #69 SignUpPage의 이메일 인증 로직, 인증 submit 버튼 분리
Yoonyesol Aug 18, 2024
d158e4f
Merge branch 'develop' of https://github.com/GU-99/grow-up-fe into fe…
Yoonyesol Aug 19, 2024
ca4aa5f
Refactor: #69 인증코드 확인 로직 분리
Yoonyesol Aug 19, 2024
b668810
Rename: #69 유저설정 페이지 관련 컴포넌트 이름 수정 및 auth-form 폴더 구조 수정
Yoonyesol Aug 19, 2024
517a68d
Feat: #69 인증버튼 라벨 props 추가
Yoonyesol Aug 19, 2024
f1c3614
Merge branch 'develop' of https://github.com/GU-99/grow-up-fe into fe…
Yoonyesol Aug 20, 2024
d9bebc1
Fix: #69 conflict 에러 해결
Yoonyesol Aug 20, 2024
6d82610
UI: #69 전체적인 코드 태그 수정 및 디자인 코드 수정, 로고 수정
Yoonyesol Aug 21, 2024
280c55b
Refactor: #69 인증번호관리 훅에서 타이머 visible 코드 삭제 및 타이머 visible 로직 수정
Yoonyesol Aug 21, 2024
87da504
UI: #69 일부 코드 태그 수정 및 디자인 코드 수정
Yoonyesol Aug 22, 2024
f8265b4
UI: #69 링크 컴포넌트 버튼 내부 아이콘 크기 조절
Yoonyesol Aug 22, 2024
22e0104
Comment: #69 타이머 만료 코드 주석 수정
Yoonyesol Aug 23, 2024
d5cb38f
Merge branch 'develop' of https://github.com/GU-99/grow-up-fe into fe…
Yoonyesol Aug 23, 2024
5d5b59b
UI: #69 label 태그 중첩 해결 및 input 태그 height 수정
Yoonyesol Aug 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Refactor: #69 UserAuthenticatePage의 이메일 인증 로직을 훅으로 분리 및 인증 submit 버튼을…
… 컴포넌트로 분리
Yoonyesol committed Aug 18, 2024
commit 1c786b6296001104e8e876abbea836894c378206
44 changes: 44 additions & 0 deletions src/components/user/VerificationButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Timer from '@/components/common/Timer';

type VerificationButtonProps = {
isVerificationRequested: boolean;
isTimerVisible: boolean;
isSubmitting: boolean;
requestCode: () => void;
handleTimerTimeout: () => void;
};

export default function VerificationButton({
isVerificationRequested,
isTimerVisible,
isSubmitting,
requestCode,
handleTimerTimeout,
}: VerificationButtonProps) {
return (
<div className="flex flex-col gap-8 text-center">
{!isVerificationRequested ? (
<button
type="submit"
className="flex h-30 items-center justify-center rounded-lg bg-sub px-8 font-bold"
onClick={requestCode}
>
<span>인증요청</span>
</button>
) : (
<button
type="submit"
className="relative flex h-30 items-center justify-center rounded-lg bg-sub px-8 font-bold"
disabled={isSubmitting}
>
{isTimerVisible && (
<div className="absolute left-10">
<Timer time={180} onTimeout={handleTimerTimeout} />
</div>
)}
<span>확인</span>
</button>
)}
</div>
);
}
38 changes: 38 additions & 0 deletions src/hooks/useEmailVerification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useState } from 'react';
import useToast from '@/hooks/useToast';

export default function useEmailVerification() {
const [isVerificationRequested, setIsVerificationRequested] = useState(false);
const [isTimerVisible, setIsTimerVisible] = useState(false);
const { toastSuccess, toastError } = useToast();

// 이메일 인증번호 요청 함수
const requestVerificationCode = () => {
if (!isVerificationRequested) {
setIsVerificationRequested(true);
toastSuccess('인증번호가 발송되었습니다. 이메일을 확인해 주세요.');
setIsTimerVisible(true);
}
};

// 인증번호 확인 함수
const verifyCode = (verificationCode: string) => {
if (verificationCode === '1234') return true;
return false;
};

// 타이머 만료
const handleTimerTimeout = () => {
setIsTimerVisible(false);
setIsVerificationRequested(false);
toastError('인증 시간이 만료되었습니다. 다시 시도해 주세요.');
};

return {
isVerificationRequested,
isTimerVisible,
requestVerificationCode,
verifyCode,
handleTimerTimeout,
};
}
89 changes: 24 additions & 65 deletions src/pages/setting/UserAuthenticatePage.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,40 @@
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import useToast from '@/hooks/useToast';
import ValidationInput from '@/components/common/ValidationInput';
import { USER_AUTH_VALIDATION_RULES } from '@/constants/formValidationRules';
import Timer from '@/components/common/Timer';
import { EmailVerificationForm } from '@/types/UserType';
import useEmailVerification from '@/hooks/useEmailVerification';
import useToast from '@/hooks/useToast';
import VerificationButton from '@/components/user/VerificationButton';

// TODO: 회원가입 폼과 겹치는 로직 컴포넌트로 분리
function UserAuthenticatePage() {
const [isVerificationRequested, setIsVerificationRequested] = useState(false);
const [isTimerVisible, setIsTimerVisible] = useState(false);
const { toastSuccess, toastError } = useToast();
const { isVerificationRequested, isTimerVisible, requestVerificationCode, verifyCode, handleTimerTimeout } =
useEmailVerification();

const { toastError } = useToast();

const {
register,
handleSubmit,
setError,
watch,
formState: { errors, isSubmitting },
watch,
} = useForm<EmailVerificationForm>({
mode: 'onChange',
});

// 이메일 인증번호 요청 함수
const requestCode = () => {
if (!isVerificationRequested) {
setIsVerificationRequested(true);
toastSuccess('인증번호가 발송되었습니다. 이메일을 확인해 주세요.');
setIsTimerVisible(true);
}
};

// 인증번호 체크 함수
const verifyCode = (code: string) => {
if (code === '1234') {
return true;
}

// 인증번호 불일치
setError('code', {
type: 'manual',
message: '인증번호가 일치하지 않습니다.',
});
return false;
};

// 타이머 만료
const handleTimerTimeout = () => {
setIsTimerVisible(false);
setIsVerificationRequested(false);
toastError('인증 시간이 만료되었습니다. 다시 시도해 주세요.');
};

const onSubmit = async (data: EmailVerificationForm) => {
console.log(data);

const verifyResult = verifyCode(watch('code'));
if (!verifyResult) return toastError('인증번호가 유효하지 않습니다. 다시 시도해 주세요.');
if (!verifyResult) {
// 인증번호 불일치
setError('code', {
type: 'manual',
message: '인증번호가 일치하지 않습니다.',
});
return toastError('인증번호가 유효하지 않습니다. 다시 시도해 주세요.');
}

// TODO: 인증 성공 후 전역 상태관리 및 리다이렉트 로직 작성
console.log(data);
};

return (
@@ -86,30 +62,13 @@ function UserAuthenticatePage() {
)}

{/* 인증 요청 및 확인 버튼 */}
<div className="flex flex-col gap-8 text-center">
{!isVerificationRequested ? (
<button
type="submit"
className="flex h-30 items-center justify-center rounded-lg bg-sub px-8 font-bold"
onClick={handleSubmit(requestCode)}
>
<span>인증요청</span>
</button>
) : (
<button
type="submit"
className="relative flex h-30 items-center justify-center rounded-lg bg-sub px-8 font-bold"
disabled={isSubmitting}
>
{isTimerVisible && (
<div className="absolute left-10">
<Timer time={180} onTimeout={handleTimerTimeout} />
</div>
)}
<span>확인</span>
</button>
)}
</div>
<VerificationButton
isVerificationRequested={isVerificationRequested}
isTimerVisible={isTimerVisible}
isSubmitting={isSubmitting}
requestCode={handleSubmit(requestVerificationCode)}
handleTimerTimeout={handleTimerTimeout}
/>
</form>
</div>
</div>