@@ -16,6 +16,23 @@ import {
16
16
} from '@chakra-ui/react' ;
17
17
import { useState } from 'react' ;
18
18
import { ViewIcon , ViewOffIcon } from '@chakra-ui/icons' ;
19
+ import { Formik , Form , Field } from 'formik' ;
20
+ import * as Yup from 'yup' ;
21
+
22
+ const SignupSchema = Yup . object ( ) . shape ( {
23
+ firstName : Yup . string ( )
24
+ . required ( 'Please enter your first name' )
25
+ . min ( 2 , 'First name is too short' ) ,
26
+ lastName : Yup . string ( )
27
+ . required ( 'Please enter your last name' )
28
+ . min ( 2 , 'Last name is too short' ) ,
29
+ email : Yup . string ( )
30
+ . email ( 'Invalid email' )
31
+ . required ( 'Please enter e-mail address' ) ,
32
+ password : Yup . string ( )
33
+ . required ( 'No password provided.' )
34
+ . min ( 8 , 'Password is too short - should be 8 chars minimum.' ) ,
35
+ } ) ;
19
36
20
37
export default function SignupCard ( ) {
21
38
const [ showPassword , setShowPassword ] = useState ( false ) ;
@@ -25,7 +42,8 @@ export default function SignupCard() {
25
42
minH = { '90vh' }
26
43
align = { 'center' }
27
44
justify = { 'center' }
28
- bg = { useColorModeValue ( 'gray.50' , 'gray.800' ) } >
45
+ bg = { useColorModeValue ( 'gray.50' , 'gray.800' ) }
46
+ >
29
47
< Stack spacing = { 8 } mx = { 'auto' } maxW = { 'lg' } py = { 12 } px = { 6 } >
30
48
< Stack align = { 'center' } >
31
49
< Heading fontSize = { '4xl' } textAlign = { 'center' } >
@@ -39,61 +57,105 @@ export default function SignupCard() {
39
57
rounded = { 'lg' }
40
58
bg = { useColorModeValue ( 'white' , 'gray.700' ) }
41
59
boxShadow = { 'lg' }
42
- p = { 8 } >
43
- < Stack spacing = { 4 } >
44
- < HStack >
45
- < Box >
46
- < FormControl id = "firstName" isRequired >
47
- < FormLabel > First Name</ FormLabel >
48
- < Input type = "text" />
49
- </ FormControl >
50
- </ Box >
51
- < Box >
52
- < FormControl id = "lastName" >
53
- < FormLabel > Last Name</ FormLabel >
54
- < Input type = "text" />
55
- </ FormControl >
56
- </ Box >
57
- </ HStack >
58
- < FormControl id = "email" isRequired >
59
- < FormLabel > Email address</ FormLabel >
60
- < Input type = "email" />
61
- </ FormControl >
62
- < FormControl id = "password" isRequired >
63
- < FormLabel > Password</ FormLabel >
64
- < InputGroup >
65
- < Input type = { showPassword ? 'text' : 'password' } />
66
- < InputRightElement h = { 'full' } >
67
- < Button
68
- variant = { 'ghost' }
69
- onClick = { ( ) =>
70
- setShowPassword ( ( showPassword ) => ! showPassword )
71
- } >
72
- { showPassword ? < ViewIcon /> : < ViewOffIcon /> }
73
- </ Button >
74
- </ InputRightElement >
75
- </ InputGroup >
76
- </ FormControl >
77
- < Stack spacing = { 10 } pt = { 2 } >
78
- < Button
79
- loadingText = "Submitting"
80
- size = "lg"
81
- bg = { 'blue.400' }
82
- color = { 'white' }
83
- _hover = { {
84
- bg : 'blue.500' ,
85
- } } >
86
- Sign up
87
- </ Button >
88
- </ Stack >
89
- < Stack pt = { 6 } >
90
- < Text align = { 'center' } >
91
- Already a user? < Link color = { 'blue.400' } href = '/login' > Login</ Link >
92
- </ Text >
93
- </ Stack >
94
- </ Stack >
60
+ p = { 8 }
61
+ >
62
+ < Formik
63
+ initialValues = { {
64
+ firstName : '' ,
65
+ lastName : '' ,
66
+ email : '' ,
67
+ password : '' ,
68
+ } }
69
+ validationSchema = { SignupSchema }
70
+ onSubmit = { ( values ) => {
71
+ // same shape as initial values
72
+ console . log ( values ) ;
73
+ } }
74
+ >
75
+ { ( { errors, touched } ) => (
76
+ < Form >
77
+ < Stack spacing = { 4 } >
78
+ < HStack >
79
+ < Box >
80
+ < FormControl id = "firstName" isRequired >
81
+ < FormLabel > First Name</ FormLabel >
82
+ < Field name = "firstName" type = "text" as = { Input } />
83
+ { errors . firstName && touched . firstName ? (
84
+ < Text color = "red.500" > { errors . firstName } </ Text >
85
+ ) : null }
86
+ </ FormControl >
87
+ </ Box >
88
+ < Box >
89
+ < FormControl id = "lastName" >
90
+ < FormLabel > Last Name</ FormLabel >
91
+ < Field name = "lastName" type = "text" as = { Input } />
92
+ { errors . lastName && touched . lastName ? (
93
+ < Text color = "red.500" > { errors . lastName } </ Text >
94
+ ) : null }
95
+ </ FormControl >
96
+ </ Box >
97
+ </ HStack >
98
+ < FormControl id = "email" isRequired >
99
+ < FormLabel > Email address</ FormLabel >
100
+ < Field name = "email" type = "email" as = { Input } />
101
+ { errors . email && touched . email ? (
102
+ < Text color = "red.500" > { errors . email } </ Text >
103
+ ) : null }
104
+ </ FormControl >
105
+ < FormControl id = "password" isRequired >
106
+ < FormLabel > Password</ FormLabel >
107
+ < InputGroup flex = { 1 } align = { 'center' } justify = { 'center' } >
108
+ < Box w = { '100%' } >
109
+ < Field
110
+ name = "password"
111
+ type = { showPassword ? 'text' : 'password' }
112
+ as = { Input }
113
+ />
114
+ { errors . password && touched . password ? (
115
+ < Text color = "red.500" > { errors . password } </ Text >
116
+ ) : null }
117
+ </ Box >
118
+ < InputRightElement >
119
+ < Button
120
+ variant = { 'ghost' }
121
+ onClick = { ( ) =>
122
+ setShowPassword ( ( showPassword ) => ! showPassword )
123
+ }
124
+ >
125
+ { showPassword ? < ViewIcon /> : < ViewOffIcon /> }
126
+ </ Button >
127
+ </ InputRightElement >
128
+ </ InputGroup >
129
+ </ FormControl >
130
+ < Stack spacing = { 10 } pt = { 2 } >
131
+ < Button
132
+ loadingText = "Submitting"
133
+ size = "lg"
134
+ bg = { 'blue.400' }
135
+ color = { 'white' }
136
+ _hover = { {
137
+ bg : 'blue.500' ,
138
+ } }
139
+ as = { 'button' }
140
+ type = "submit"
141
+ >
142
+ Sign up
143
+ </ Button >
144
+ </ Stack >
145
+ < Stack pt = { 6 } >
146
+ < Text align = { 'center' } >
147
+ Already a user?{ ' ' }
148
+ < Link color = { 'blue.400' } href = "/login" >
149
+ Login
150
+ </ Link >
151
+ </ Text >
152
+ </ Stack >
153
+ </ Stack >
154
+ </ Form >
155
+ ) }
156
+ </ Formik >
95
157
</ Box >
96
158
</ Stack >
97
159
</ Flex >
98
160
) ;
99
- }
161
+ }
0 commit comments