3
3
import Image from "next/image"
4
4
import Link from "next/link" ;
5
5
import { useState } from "react" ;
6
+ import { useFormState } from "react-dom" ;
6
7
import { 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
+ } ;
9
19
10
20
const Register = ( ) => {
11
- const [ isChecked , setIsChecked ] = useState < boolean > ( false ) ;
12
21
const [ togglePassword , setTogglePassword ] = useState < boolean > ( false ) ;
13
22
const [ toggleConfirmPassword , setToggleConfirmPasword ] = useState < boolean > ( false ) ;
23
+ const [ loading , setLoading ] = useState < boolean > ( false ) ;
24
+ const [ state , formAction ] = useFormState ( createUser , initialState )
14
25
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
+ } ) ;
15
34
16
- const handleCheckboxToggle = ( ) => {
17
- setIsChecked ( ( prev ) => ! prev ) ;
18
- } ;
35
+ }
19
36
20
37
return (
21
38
< 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" >
23
40
< h1 className = "heading text-2xl font-bold" > Register!</ h1 >
24
41
< 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
+ </ > }
25
58
< div className = "flex flex-col mb-5" >
26
59
< 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
+ ) }
28
64
</ div >
29
65
< div className = "flex flex-col mb-5" >
30
66
< 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
+ ) }
32
71
</ div >
33
72
< div className = "flex flex-col mb-5" >
34
73
< 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
+ ) }
36
78
</ div >
37
- < div className = "flex flex-col mb-5 relative" >
79
+ < div className = "flex flex-col mb-5 relative z-0 " >
38
80
< label className = "label" htmlFor = "password" > Password < span className = "asterik" > *</ span > </ label >
39
81
< 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 />
41
83
< 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 ) } >
42
84
< FaEye className = "value" />
43
85
</ div >
44
86
</ div >
87
+ { state . errors && state . errors . password && (
88
+ < p className = "error-message" > { state . errors . password } </ p >
89
+ ) }
45
90
46
91
</ div >
47
92
< div className = "flex flex-col mb-5 relative w-full" >
48
93
< label className = "label" htmlFor = "confirmPassword" > Confirm Password < span className = "asterik" > *</ span > </ label >
49
94
< 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 />
51
96
< 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 ) } >
52
97
< FaEye className = "value" />
53
98
</ div >
54
99
</ div >
100
+ { state . errors && state . errors . confirmPassword && (
101
+ < p className = "error-message" > { state . errors . confirmPassword } </ p >
102
+ ) }
55
103
</ div >
56
- < div >
104
+ { /* <div>
57
105
<label className="label flex items-center gap-2">
58
106
{isChecked ? (
59
107
<IoCheckbox
@@ -69,8 +117,9 @@ const Register = () => {
69
117
<input type="checkbox" hidden />
70
118
Remember me
71
119
</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
+
74
123
< p className = "para text-sm mt-4 text-center" > Do you have an account? < Link href = { '/login' } className = "heading font-bold" > SignIn</ Link > </ p >
75
124
</ form >
76
125
< div className = "relative hidden sm:block col-span-1 sm:col-span-2 md:col-span-3 h-full" >
0 commit comments