import { Card, CardContent, CardHeader, CardFooter } from '@/components/ui/card'; import { ResetPasswordSchema } from '@/data/form'; import { Field, FieldError, FieldLabel } from '@/components/ui/field'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { zodResolver } from '@hookform/resolvers/zod'; import { useState, useCallback } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { PageRouting } from '@/const/PageRouting'; import { Stepper, StepperContent, StepperIndicator, StepperItem, StepperNav, StepperPanel, StepperSeparator, StepperTrigger } from '@/components/ui/stepper'; import * as z from 'zod'; import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/input-otp'; import { Validator } from '@/util/Validator'; import { Eye, EyeOff, LoaderCircleIcon, CircleCheckBigIcon } from 'lucide-react'; import { AccountNetwork } from '@/network/AccountNetwork'; import { Label } from '@/components/ui/label'; const steps = [1, 2, 3, 4]; export default function ResetPasswordPage() { const [currentStep, setCurrentStep] = useState(1); const [showPassword, setShowPassword] = useState(false); const [showPasswordConfirm, setShowPasswordConfirm] = useState(false); const [isLoading, setIsLoading] = useState(false); const navigate = useNavigate(); const accountNetwork = new AccountNetwork(); const resetPasswordForm = useForm>({ resolver: zodResolver(ResetPasswordSchema), defaultValues: { email: "", code: "", password: "", passwordConfirm: "" } }); const { email, code, password, passwordConfirm } = resetPasswordForm.watch(); const moveToLoginPage = useCallback(() => { navigate(PageRouting["LOGIN"].path); }, []); const handleClickFirstStepButton = async () => { if (isLoading) return; if (!email || email.trim().length === 0) { resetPasswordForm.setError('email', { type: 'manual', message: '이메일을 입력해주십시오' }); return; } const isEmailValid = await resetPasswordForm.trigger('email'); if (!isEmailValid) { resetPasswordForm.setError('email', { type: 'validate', message: '이메일 형식이 올바르지 않습니다' }); return; } setIsLoading(true); try { const response = await accountNetwork.sendResetPasswordCode({ email: email }); const resData = response.data; if (!resData.success) { resetPasswordForm.setError('email', { message: '서버 오류로 코드 발송에 실패하였습니다. 잠시 후 다시 시도해주십시오.' }); return; } setCurrentStep(current => current + 1); } catch (err) { resetPasswordForm.setError('email', { message: '서버 오류로 코드 발송에 실패하였습니다. 잠시 후 다시 시도해주십시오.' }); } finally { setIsLoading(false); } } const handleSecondStepOTPCompleted = async () => { if (isLoading) return; const codeValid = await resetPasswordForm.trigger('code'); if (!codeValid) { return; } const data = { email: email, code: code } setIsLoading(true); try { const response = await accountNetwork.verifyResetPasswordCode(data); const resData = response.data; console.log(resData); if (!resData.success || !resData.verified) { resetPasswordForm.setError('code', { type: 'value', message: resData.error }); return; } setCurrentStep(current => current + 1); } catch (err) { resetPasswordForm.setError('code', { type: 'value', message: '서버 오류로 코드 인증에 실패하였습니다. 잠시 후 다시 시도해주십시오.' }); } finally { setIsLoading(false); } } const handleThirdStepButton = async () => { if (isLoading) return; const passwordValid = await resetPasswordForm.trigger('password'); if (!passwordValid) return; const passwordConfirmValid = await resetPasswordForm.trigger('passwordConfirm'); if (!passwordConfirmValid) return; const data = { email: email, password: password } setIsLoading(true); try { const response = await accountNetwork.resetPassword(data); const resData = response.data; if (!resData.success) { resetPasswordForm.setError('password', { message: '서버 오류로 비밀번호 변경에 실패하였습니다. 잠시 후 다시 시도해주십시오.' }); return; } setCurrentStep(current => current + 1); } catch (err) { resetPasswordForm.setError('password', { message: '서버 오류로 비밀번호 변경에 실패하였습니다. 잠시 후 다시 시도해주십시오.' }); } finally { setIsLoading(false); } } return ( }} > 비밀번호 초기화 {steps.map((step) => ( {step} { steps.length > step && } ))} 이메일 ( <> { if (e.key === 'Enter') { e.preventDefault(); if (email.length === 0) return; handleClickFirstStepButton(); } }} /> )} /> (
코드 입력
field.onChange(value)} onBlur={field.onBlur} required > { [0, 1, 2, 3, 4, 5, 6, 7].map((idx) => ( )) }
) } />
새 비밀번호 ( <>
)} /> 새 비밀번호 확인 ( <>
)} />
) }