@@ -2,37 +2,51 @@ import styles from "./LoginForm.module.css";
22import { useState } from "react" ;
33import Image from "next/image" ;
44import Link from "next/link" ;
5+ import { loginSchema , LoginRequest } from "@/types" ;
6+ import { useForm , SubmitHandler } from "react-hook-form" ;
7+ import { zodResolver } from "@hookform/resolvers/zod" ;
58
69interface LoginFormProps {
7- onSubmit : ( formData : { email : string ; password : string } ) => Promise < void > ;
10+ onSubmit : ( request : LoginRequest ) => Promise < void > ;
811}
912
1013export default function LoginForm ( { onSubmit } : LoginFormProps ) {
1114 const [ showPassword , setShowPassword ] = useState ( false ) ;
12- const [ email , setEmail ] = useState ( "" ) ;
13- const [ password , setPassword ] = useState ( "" ) ;
15+ const {
16+ register,
17+ handleSubmit,
18+ formState : { errors } ,
19+ reset,
20+ } = useForm < LoginRequest > ( {
21+ resolver : zodResolver ( loginSchema ) ,
22+ } ) ;
1423
15- const handleSubmit = async ( e : React . FormEvent ) => {
16- e . preventDefault ( ) ;
17- await onSubmit ( { email, password } ) ;
24+ const onFormSubmit : SubmitHandler < LoginRequest > = async ( data ) => {
25+ try {
26+ await onSubmit ( data ) ;
27+ reset ( ) ;
28+ } catch ( err ) {
29+ console . error ( "서버오류" , err ) ;
30+ alert ( "로그인 중 오류가 발생했습니다. 다시 시도해주세요." ) ;
31+ }
1832 } ;
1933
2034 return (
21- < form onSubmit = { handleSubmit } >
35+ < form onSubmit = { handleSubmit ( onFormSubmit ) } >
2236 < div className = { styles . formGroup } >
2337 < label className = { styles . label } htmlFor = "email" >
2438 이메일
2539 </ label >
2640 < div className = { styles . inputContainer } >
2741 < input
42+ { ...register ( "email" ) }
2843 type = "email"
2944 id = "email"
3045 placeholder = "이메일을 입력해주세요"
31- className = { styles . inputField }
32- value = { email }
33- onChange = { ( e ) => setEmail ( e . target . value ) }
46+ className = { `${ styles . inputField } ${ errors . email ? styles . errorInput : "" } ` }
3447 />
3548 </ div >
49+ { errors . email && < p className = { styles . errorMessage } > { errors . email . message } </ p > }
3650 </ div >
3751
3852 < div className = { styles . formGroup } >
@@ -41,17 +55,17 @@ export default function LoginForm({ onSubmit }: LoginFormProps) {
4155 </ label >
4256 < div className = { styles . inputContainer } >
4357 < input
58+ { ...register ( "password" ) }
4459 type = { showPassword ? "text" : "password" }
4560 id = "password"
4661 placeholder = "비밀번호를 입력해주세요"
47- className = { styles . inputField }
48- value = { password }
49- onChange = { ( e ) => setPassword ( e . target . value ) }
62+ className = { `${ styles . inputField } ${ errors . password ? styles . errorInput : "" } ` }
5063 />
5164 < button type = "button" onClick = { ( ) => setShowPassword ( ! showPassword ) } className = { styles . toggleButton } >
5265 { showPassword ? "O" : "X" }
5366 </ button >
5467 </ div >
68+ { errors . password && < p className = { styles . errorMessage } > { errors . password . message } </ p > }
5569 </ div >
5670
5771 < button type = "submit" className = { styles . button } >
0 commit comments