Skip to content

Commit f536319

Browse files
committed
Add formik and yup to login and signup forms
1 parent 77a7eb9 commit f536319

File tree

6 files changed

+288
-93
lines changed

6 files changed

+288
-93
lines changed

components/Landing/index.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { NextPage } from 'next';
2-
import React from 'react';
2+
import React, {useEffect} from 'react';
3+
import smoothscroll from 'smoothscroll-polyfill';
4+
35
import Image from 'next/image';
46
import { Box } from '@mui/material';
57
import LandingHero from './_heroes/LandingHero';
@@ -12,6 +14,7 @@ import WithBackgroundImageAndGradient from './_heroes/WithBackgroundImageAndGrad
1214
import SimpleThreeColumnGrid from './_heroes/SimpleThreeColumnGrid';
1315

1416
const Landing = () => {
17+
useEffect(() => smoothscroll.polyfill(), [])
1518
return (
1619
<Box>
1720
<CallToActionWithIllustration />

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@mui/icons-material": "^5.8.4",
2222
"@mui/material": "^5.8.4",
2323
"@reduxjs/toolkit": "^1.8.4",
24+
"formik": "^2.2.9",
2425
"framer-motion": "^5.6.0",
2526
"jsonwebtoken": "^8.5.1",
2627
"next": "12.0.8",
@@ -29,7 +30,9 @@
2930
"react-icons": "^4.4.0",
3031
"react-lottie": "^1.2.3",
3132
"react-redux": "^8.0.2",
32-
"redux-saga": "^1.2.0"
33+
"redux-saga": "^1.2.0",
34+
"smoothscroll-polyfill": "^0.4.4",
35+
"yup": "^0.32.11"
3336
},
3437
"devDependencies": {
3538
"@babel/core": "^7.16.7",
@@ -44,6 +47,7 @@
4447
"@types/react": "17.0.30",
4548
"@types/react-dom": "^18.0.6",
4649
"@types/react-lottie": "^1.2.6",
50+
"@types/smoothscroll-polyfill": "^0.3.1",
4751
"babel-loader": "^8.2.3",
4852
"eslint": "8.6.0",
4953
"eslint-config-next": "12.0.8",

pages/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { Button } from 'components/button';
21
import type { NextPage } from 'next';
32
import Head from 'next/head';
43
import { Container } from '@chakra-ui/react';

pages/login.tsx

+84-33
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,27 @@ import {
1313
useColorModeValue,
1414
} from '@chakra-ui/react';
1515

16+
import { Formik, Form, Field } from 'formik';
17+
import * as Yup from 'yup';
18+
19+
const LoginSchema = Yup.object().shape({
20+
email: Yup.string()
21+
.email('Invalid email')
22+
.required('Please enter e-mail address'),
23+
password: Yup.string()
24+
.required('No password provided.')
25+
.min(8, 'Password is too short - should be 8 chars minimum.')
26+
.matches(/[a-zA-Z]/, 'Password can only contain Latin letters.'),
27+
});
28+
1629
export default function SimpleCard() {
1730
return (
1831
<Flex
1932
minH={'90vh'}
2033
align={'center'}
2134
justify={'center'}
22-
bg={useColorModeValue('gray.50', 'gray.800')}>
35+
bg={useColorModeValue('gray.50', 'gray.800')}
36+
>
2337
<Stack spacing={8} mx={'auto'} maxW={'lg'} py={12} px={6}>
2438
<Stack align={'center'}>
2539
<Heading fontSize={'4xl'}>Sign in to your account</Heading>
@@ -31,39 +45,76 @@ export default function SimpleCard() {
3145
rounded={'lg'}
3246
bg={useColorModeValue('white', 'gray.700')}
3347
boxShadow={'lg'}
34-
p={8}>
35-
<Stack spacing={4}>
36-
<FormControl id="email">
37-
<FormLabel>Email address</FormLabel>
38-
<Input type="email" />
39-
</FormControl>
40-
<FormControl id="password">
41-
<FormLabel>Password</FormLabel>
42-
<Input type="password" />
43-
</FormControl>
44-
<Stack spacing={10}>
45-
<Stack
46-
direction={{ base: 'column', sm: 'row' }}
47-
align={'start'}
48-
justify={'space-between'}>
49-
<Checkbox>Remember me</Checkbox>
50-
<Link color={'blue.400'} href='/forgot-password'>Forgot password?</Link>
51-
</Stack>
52-
<Button
53-
bg={'blue.400'}
54-
color={'white'}
55-
_hover={{
56-
bg: 'blue.500',
57-
}}>
58-
Sign in
59-
</Button>
60-
<Text align={'center'}>
61-
I don't have an account yet. <Link color={'blue.400'} href='/signup'>Sign up</Link>
62-
</Text>
63-
</Stack>
64-
</Stack>
48+
p={8}
49+
>
50+
<Formik
51+
initialValues={{
52+
email: '',
53+
password: '',
54+
}}
55+
validationSchema={LoginSchema}
56+
onSubmit={(values) => {
57+
// same shape as initial values
58+
console.log(values);
59+
}}
60+
>
61+
{({ errors, touched }) => (
62+
<Form>
63+
<Stack spacing={4}>
64+
<FormControl id="email">
65+
<FormLabel>Email address</FormLabel>
66+
{/* <Input type="email" name="email" /> */}
67+
<Field name="email" type="email" as={Input} />
68+
{errors.email && touched.email ? (
69+
<Text color={'red'} backgroundColor={'white'}>
70+
{errors.email}
71+
</Text>
72+
) : null}
73+
</FormControl>
74+
<FormControl id="password">
75+
<FormLabel>Password</FormLabel>
76+
<Field name="password" type="password" as={Input} />
77+
{errors.password && touched.password ? (
78+
<Text color={'red'} backgroundColor={'white'}>
79+
{errors.password}
80+
</Text>
81+
) : null}
82+
</FormControl>
83+
<Stack spacing={10}>
84+
<Stack
85+
direction={{ base: 'column', sm: 'row' }}
86+
align={'start'}
87+
justify={'space-between'}
88+
>
89+
<Checkbox>Remember me</Checkbox>
90+
<Link color={'blue.400'} href="/forgot-password">
91+
Forgot password?
92+
</Link>
93+
</Stack>
94+
<Button
95+
// as={'button'}
96+
bg={'blue.400'}
97+
color={'white'}
98+
_hover={{
99+
bg: 'blue.500',
100+
}}
101+
type="submit"
102+
>
103+
Sign in
104+
</Button>
105+
<Text align={'center'}>
106+
I don't have an account yet.{' '}
107+
<Link color={'blue.400'} href="/signup">
108+
Sign up
109+
</Link>
110+
</Text>
111+
</Stack>
112+
</Stack>
113+
</Form>
114+
)}
115+
</Formik>
65116
</Box>
66117
</Stack>
67118
</Flex>
68119
);
69-
}
120+
}

pages/signup.tsx

+117-55
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@ import {
1616
} from '@chakra-ui/react';
1717
import { useState } from 'react';
1818
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+
});
1936

2037
export default function SignupCard() {
2138
const [showPassword, setShowPassword] = useState(false);
@@ -25,7 +42,8 @@ export default function SignupCard() {
2542
minH={'90vh'}
2643
align={'center'}
2744
justify={'center'}
28-
bg={useColorModeValue('gray.50', 'gray.800')}>
45+
bg={useColorModeValue('gray.50', 'gray.800')}
46+
>
2947
<Stack spacing={8} mx={'auto'} maxW={'lg'} py={12} px={6}>
3048
<Stack align={'center'}>
3149
<Heading fontSize={'4xl'} textAlign={'center'}>
@@ -39,61 +57,105 @@ export default function SignupCard() {
3957
rounded={'lg'}
4058
bg={useColorModeValue('white', 'gray.700')}
4159
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>
95157
</Box>
96158
</Stack>
97159
</Flex>
98160
);
99-
}
161+
}

0 commit comments

Comments
 (0)