import { useCallback, useEffect, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent, CardHeader, CardFooter } from '@/components/ui/card'; import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field'; import { SignUpSchema } from '@/data/form'; import { Controller, useForm } from 'react-hook-form'; import * as z from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; import EmailVerificationModal from '@/ui/component/modal/EmailVerificationModal'; import { CheckDuplicationRequest, SignupRequest } from '@/data/request'; import { AccountNetwork } from '@/network/AccountNetwork'; import { toast } from 'sonner'; import { useNavigate } from 'react-router-dom'; import { PageRouting } from '@/const/PageRouting'; export default function SignUpPage() { const [emailVerificationModalOpen, setEmailVerificationModalOpen] = useState(false); const [isCheckedEmailDuplication, setIsCheckedEmailDuplication] = useState(false); const [isCheckedAccountIdDuplication, setIsCheckedAccountIdDuplication] = useState(false); const [duplicationCheckedEmail, setDuplicationCheckedEmail] = useState(""); const [duplicationCheckedAccountId, setDuplicationCheckedAccountId] = useState(""); const accountNetwork = new AccountNetwork(); const navigate = useNavigate(); const signUpForm = useForm>({ resolver: zodResolver(SignUpSchema), defaultValues: { accountId: "", email: "", password: "", passwordConfirm: "", name: "", nickname: "", } }); const goToLogin = useCallback(() => { navigate(PageRouting["LOGIN"].path); }, [navigate]); const checkDuplication = async (type: 'email' | 'accountId', value: string) => { const data: CheckDuplicationRequest = new CheckDuplicationRequest(type, value); return await accountNetwork.checkDuplication(data); } const signup = async () => { const { email, accountId, name, nickname, password } = signUpForm.getValues(); const data: SignupRequest = new SignupRequest(accountId, email, name, nickname, password); const signupPromise = accountNetwork.signup(data); toast.promise( signupPromise, { loading: "회원가입 진행 중입니다.", success: (res) => { if (!res.data.success) return "회원가입에 실패하였습니다.\n잠시 후 다시 시도해주십시오."; return }, error: "회원가입에 실패하였습니다.\n잠시 후 다시 시도해주십시오.", } ); } const handleOnChangeAccountId = (e: React.ChangeEvent) => { setIsCheckedAccountIdDuplication( e.currentTarget.value === duplicationCheckedAccountId ); } const handleOnChangeEmail = (e: React.ChangeEvent) => { setIsCheckedEmailDuplication( e.currentTarget.value === duplicationCheckedEmail ); } const handleDuplicationCheckButtonClick = async (type: 'email' | 'accountId') => { const value = signUpForm.getValues(type); const duplicatedMessage = type === 'email' ? '사용할 수 없는 이메일입니다.' : '사용할 수 없는 아이디입니다.'; if (!value) return; const isDuplicated = (await checkDuplication(type, value)).data.isDuplicated; if (isDuplicated) { signUpForm.setError(type, { message: duplicatedMessage }); } else { signUpForm.clearErrors(type); if (type === 'email') { setIsCheckedEmailDuplication(true); setDuplicationCheckedEmail(value); } else { setIsCheckedAccountIdDuplication(true); setDuplicationCheckedAccountId(value); } } } const handleOnSignUpButtonClick = () => { if (!isCheckedAccountIdDuplication) { signUpForm.setError("accountId", { message: "아이디 중복 확인이 필요합니다."}); return; } if (!isCheckedEmailDuplication) { signUpForm.setError("email", { message: "이메일 중복 확인이 필요합니다." }); return; } setEmailVerificationModalOpen(true); } return (
회원가입
( 아이디
{ isCheckedAccountIdDuplication &&

사용할 수 있는 아이디입니다

}
)} /> ( 이름 )} /> ( 닉네임 )} /> ( 이메일
{ isCheckedEmailDuplication &&

사용할 수 있는 이메일입니다

}
)} /> ( 비밀번호 )} /> ( 비밀번호 확인 )} />
회원가입 } email={duplicationCheckedEmail} open={emailVerificationModalOpen} // ✅ 부모 상태 연결 setOpen={setEmailVerificationModalOpen} // ✅ 부모 상태 변경 함수 전달 onVerifySuccess={signup} // ✅ 인증 성공 시 signup 호출 />
); } function SuccessToast({ onClose }: { onClose: () => void }) { useEffect(() => { const timer = setTimeout(() => onClose(), 3000); // 3초 후 이동 return () => clearTimeout(timer); }, [onClose]); return (
회원가입 성공!
); }