33import Image from "next/image"
44import Link from "next/link" ;
55import { useState } from "react" ;
6+ import { useFormState } from "react-dom" ;
67import { FaEye } from "react-icons/fa" ;
7- import { IoCheckbox } from "react-icons/io5" ;
8- import { MdCheckBoxOutlineBlank } from "react-icons/md" ;
8+ import { startTransition } from "react" ;
9+
10+
11+
12+ // actions
13+ import { createUser } from "@/utils/actions" ;
14+
15+ const initialState : { message : string | null ; errors ?: Record < string , string [ ] | undefined > } = {
16+ message : null ,
17+ errors : { } ,
18+ } ;
919
1020const Register = ( ) => {
11- const [ isChecked , setIsChecked ] = useState < boolean > ( false ) ;
1221 const [ togglePassword , setTogglePassword ] = useState < boolean > ( false ) ;
1322 const [ toggleConfirmPassword , setToggleConfirmPasword ] = useState < boolean > ( false ) ;
23+ const [ loading , setLoading ] = useState < boolean > ( false ) ;
24+ const [ state , formAction ] = useFormState ( createUser , initialState )
1425
26+ const handleSubmit = async ( e :React . FormEvent < HTMLElement > ) => {
27+ e . preventDefault ( ) ;
28+ setLoading ( true ) ;
29+ const formData = new FormData ( e . currentTarget as HTMLFormElement )
30+ startTransition ( ( ) => {
31+ formAction ( formData ) ;
32+ setLoading ( false ) ;
33+ } ) ;
1534
16- const handleCheckboxToggle = ( ) => {
17- setIsChecked ( ( prev ) => ! prev ) ;
18- } ;
35+ }
1936
2037 return (
2138 < div className = "grid grid-cols-5 gap-8 mx-5 md:gap-12 max-w-screen" style = { { height : 'calc(100vh - 4rem)' } } >
22- < form action = "" method = 'POST' className = "col-span-5 max-w-lg sm:max-w-4xl mt-8 sm:mt-16 sm:col-span-3 md:col-span-2" >
39+ < form onSubmit = { handleSubmit } action = { formAction } method = 'POST' className = "col-span-5 max-w-lg sm:max-w-4xl mt-8 sm:mt-16 sm:col-span-3 md:col-span-2" >
2340 < h1 className = "heading text-2xl font-bold" > Register!</ h1 >
2441 < p className = "para mb-5 mt-2" > Create a new account.</ p >
42+
43+ { ( state ?. message ) && < >
44+ < div className = "flex gap-2" >
45+ < p className = "success-message text-green-500 mb-4 font-bold" >
46+ { state ?. message }
47+ </ p >
48+ < Link href = { "/login" } className = "heading underline cursor-pointer font-bold text-xs" > Login here</ Link >
49+ </ div >
50+ </ > }
51+ { ( state ?. errors ?. root ) && < >
52+ < div className = "flex gap-2" >
53+ < p className = "error-message font-bold mb-4 text-sm" >
54+ { state ?. errors ?. root }
55+ </ p >
56+ </ div >
57+ </ > }
2558 < div className = "flex flex-col mb-5" >
2659 < label className = "label" htmlFor = "firstName" > First Name < span className = "asterik" > *</ span > </ label >
27- < input type = "text" className = "input value w-full mt-2" id = "firstName" placeholder = "First Name" required />
60+ < input type = "text" name = "firstName" className = "input value w-full mt-2" id = "firstName" placeholder = "First Name" required />
61+ { state . errors && state . errors . firstName && (
62+ < p className = "error-message" > { state . errors . firstName } </ p >
63+ ) }
2864 </ div >
2965 < div className = "flex flex-col mb-5" >
3066 < label className = "label" htmlFor = "lastName" > Last Name < span className = "asterik" > *</ span > </ label >
31- < input type = "text" className = "input value w-full mt-2" id = "lastName" placeholder = "Last Name" required />
67+ < input type = "text" name = "lastName" className = "input value w-full mt-2" id = "lastName" placeholder = "Last Name" required />
68+ { state . errors && state . errors . lastName && (
69+ < p className = "error-message" > { state . errors . lastName } </ p >
70+ ) }
3271 </ div >
3372 < div className = "flex flex-col mb-5" >
3473 < label className = "label" htmlFor = "email" > Email < span className = "asterik" > *</ span > </ label >
35- < input type = "email" className = "input value w-full mt-2" id = "email" placeholder = "Your Email" required />
74+ < input type = "email" name = "email" className = "input value w-full mt-2" id = "email" placeholder = "Your Email" required />
75+ { state . errors && state . errors . email && (
76+ < p className = "error-message" > { state . errors . email } </ p >
77+ ) }
3678 </ div >
37- < div className = "flex flex-col mb-5 relative" >
79+ < div className = "flex flex-col mb-5 relative z-0 " >
3880 < label className = "label" htmlFor = "password" > Password < span className = "asterik" > *</ span > </ label >
3981 < div className = "flex mt-2 relative" >
40- < input type = { togglePassword ?"text" :"password" } className = "input value w-full pr-12" id = "password" placeholder = "Password" required />
82+ < input type = { togglePassword ?"text" :"password" } name = "password" className = "input value w-full pr-12" id = "password" placeholder = "Password" required />
4183 < div className = "flex justify-center items-center py-1 px-4 rounded-lg box-border cursor-pointer absolute top-0 right-0 bottom-0" onClick = { ( ) => setTogglePassword ( ! togglePassword ) } >
4284 < FaEye className = "value" />
4385 </ div >
4486 </ div >
87+ { state . errors && state . errors . password && (
88+ < p className = "error-message" > { state . errors . password } </ p >
89+ ) }
4590
4691 </ div >
4792 < div className = "flex flex-col mb-5 relative w-full" >
4893 < label className = "label" htmlFor = "confirmPassword" > Confirm Password < span className = "asterik" > *</ span > </ label >
4994 < div className = "flex mt-2 relative" >
50- < input type = { toggleConfirmPassword ?"text" :"password" } className = "input value w-full pr-12" id = "confirmPassword" placeholder = "Confirm Password" required />
95+ < input type = { toggleConfirmPassword ?"text" :"password" } name = "confirmPassword" className = "input value w-full pr-12" id = "confirmPassword" placeholder = "Confirm Password" required />
5196 < div className = "flex justify-center items-center py-1 px-4 rounded-lg box-border cursor-pointer absolute top-0 right-0 bottom-0" onClick = { ( ) => setToggleConfirmPasword ( ! toggleConfirmPassword ) } >
5297 < FaEye className = "value" />
5398 </ div >
5499 </ div >
100+ { state . errors && state . errors . confirmPassword && (
101+ < p className = "error-message" > { state . errors . confirmPassword } </ p >
102+ ) }
55103 </ div >
56- < div >
104+ { /* <div>
57105 <label className="label flex items-center gap-2">
58106 {isChecked ? (
59107 <IoCheckbox
@@ -69,8 +117,9 @@ const Register = () => {
69117 <input type="checkbox" hidden />
70118 Remember me
71119 </label>
72- </ div >
73- < button className = "primaryBtn w-full mt-6" > Register</ button >
120+ </div> */ }
121+ < button className = "primaryBtn w-full mt-6" disabled = { loading } > { loading ? "Processing..." : "Register" } </ button >
122+
74123 < p className = "para text-sm mt-4 text-center" > Do you have an account? < Link href = { '/login' } className = "heading font-bold" > SignIn</ Link > </ p >
75124 </ form >
76125 < div className = "relative hidden sm:block col-span-1 sm:col-span-2 md:col-span-3 h-full" >
0 commit comments