@@ -3,25 +3,29 @@ import useNext from "../../../hooks/useNext";
33import useUser from "../../../hooks/useUser" ;
44import { Message } from "../../common/Message" ;
55import Button from "../../ui/Button" ;
6- import { yupResolver } from "@hookform/resolvers/yup" ;
6+ import {
7+ Form ,
8+ FormControl ,
9+ FormDescription ,
10+ FormField ,
11+ FormItem ,
12+ FormLabel ,
13+ FormMessage ,
14+ } from "../../ui/Form" ;
15+ import { Input } from "../../ui/Input" ;
16+ import { zodResolver } from "@hookform/resolvers/zod" ;
717import { useMutation } from "@tanstack/react-query" ;
818import { Auth , signInWithEmailAndPassword } from "firebase/auth" ;
9- import { Fragment } from "react" ;
1019import { useForm } from "react-hook-form" ;
1120import { Link , Navigate , useNavigate } from "react-router-dom" ;
12- import { object , string } from "yup " ;
21+ import { z } from "zod " ;
1322
14- type LogInFormFieldsType = {
15- email : string ;
16- password : string ;
17- } ;
23+ const logInSchema = z . object ( {
24+ email : z . string ( ) . email ( ) ,
25+ password : z . string ( ) . nonempty ( { message : "Password is required." } ) ,
26+ } ) ;
1827
19- const loginSchema = object ( )
20- . shape ( {
21- email : string ( ) . required ( ) . email ( "Invalid email address" ) ,
22- password : string ( ) . required ( ) . min ( 8 , "Invalid password" ) ,
23- } )
24- . required ( ) ;
28+ type LogInFormFieldsType = z . infer < typeof logInSchema > ;
2529
2630const logIn = async ( {
2731 auth,
@@ -37,11 +41,11 @@ const logIn = async ({
3741
3842const LogIn = ( ) => {
3943 const form = useForm < LogInFormFieldsType > ( {
44+ resolver : zodResolver ( logInSchema ) ,
4045 defaultValues : {
4146 email : "" ,
4247 password : "" ,
4348 } ,
44- resolver : yupResolver ( loginSchema ) ,
4549 } ) ;
4650 const navigate = useNavigate ( ) ;
4751 const { next, nextSearch } = useNext ( ) ;
@@ -64,69 +68,79 @@ const LogIn = () => {
6468 }
6569
6670 return (
67- < Fragment >
68- < form
69- className = "m-auto flex max-w-md flex-col gap-4"
70- onSubmit = { form . handleSubmit ( ( data ) =>
71- signIn ( {
72- auth : firebase . auth ,
73- email : data . email ,
74- password : data . password ,
75- } ) ,
76- ) }
77- >
78- < h2 className = "font-tall text-2xl uppercase md:text-4xl" > Log In</ h2 >
79- < div className = "flex flex-col gap-2" >
80- < input
81- { ...form . register ( "email" ) }
82- type = "email"
83- className = "rounded-sm border border-stone-500 p-2"
84- placeholder = "email@example.com"
85- />
86- < Message
87- message = { form . formState . errors . email ?. message }
88- type = "error"
71+ < div className = "flex flex-col items-center gap-8" >
72+ < Form { ...form } >
73+ < form
74+ className = "m-auto flex w-full max-w-md flex-col gap-4"
75+ onSubmit = { form . handleSubmit ( ( data ) =>
76+ signIn ( {
77+ auth : firebase . auth ,
78+ email : data . email ,
79+ password : data . password ,
80+ } ) ,
81+ ) }
82+ >
83+ < h2 className = "font-tall text-2xl uppercase md:text-4xl" > Log In</ h2 >
84+ < FormField
85+ control = { form . control }
86+ name = "email"
87+ render = { ( { field } ) => (
88+ < FormItem >
89+ < FormLabel > Email</ FormLabel >
90+ < FormControl >
91+ < Input
92+ { ...field }
93+ type = "email"
94+ placeholder = "email@example.com"
95+ />
96+ </ FormControl >
97+ < FormDescription > Enter your email address.</ FormDescription >
98+ < FormMessage />
99+ </ FormItem >
100+ ) }
89101 />
90- </ div >
91- < div className = "flex flex-col gap-2" >
92- < input
93- { ...form . register ( "password" ) }
94- type = "password"
95- className = "rounded-sm border border-stone-500 p-2"
96- placeholder = "password"
102+ < FormField
103+ control = { form . control }
104+ name = "password"
105+ render = { ( { field } ) => (
106+ < FormItem >
107+ < FormLabel > Password</ FormLabel >
108+ < FormControl >
109+ < Input { ...field } type = "password" placeholder = "password" />
110+ </ FormControl >
111+ < FormDescription > A very secure password.</ FormDescription >
112+ < FormMessage />
113+ </ FormItem >
114+ ) }
97115 />
116+ < div >
117+ < Button className = "uppercase" asChild >
118+ < input type = "submit" value = "log in" />
119+ </ Button >
120+ </ div >
98121 < Message
99- message = { form . formState . errors . password ?. message }
100- type = "error"
122+ message = {
123+ isSuccess
124+ ? "Successfully logged you in."
125+ : isError
126+ ? "There was an issue logging you in."
127+ : ""
128+ }
129+ type = { isError ? "error" : "info" }
101130 />
102- </ div >
103- < div >
104- < Button className = "uppercase" asChild >
105- < input type = "submit" value = "log in" />
106- </ Button >
107- </ div >
108- < Message
109- message = {
110- isSuccess
111- ? "Successfully logged you in."
112- : isError
113- ? "There was an issue logging you in."
114- : ""
115- }
116- type = { isError ? "error" : "info" }
117- />
118- < Button variant = "link" size = "link" asChild >
119- < Link
120- to = { {
121- pathname : "/reset-password" ,
122- search : nextSearch ,
123- } }
124- >
125- Forgot your password?
126- </ Link >
127- </ Button >
128- </ form >
129- </ Fragment >
131+ </ form >
132+ </ Form >
133+ < Button variant = "link" size = "link" asChild >
134+ < Link
135+ to = { {
136+ pathname : "/reset-password" ,
137+ search : nextSearch ,
138+ } }
139+ >
140+ Forgot your password?
141+ </ Link >
142+ </ Button >
143+ </ div >
130144 ) ;
131145} ;
132146
0 commit comments