43
loading...
This website collects cookies to deliver better user experience
npx create-next-app app &&
cd app
npm i formik && npm i yup
npm install -D tailwindcss postcss autoprefixer &&
npx tailwindcss init -p
tailwind.config.js
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
@tailwind
directives to your ./styles/globals.css
file to include tailwind styles in our project.@tailwind base;
@tailwind components;
@tailwind utilities;
mkdir components && cd components && touch LoginForm.js && touch RegisterForm.js
<Form/> <Field/> <ErrorMessage/>
we can directly hook up form elements to <Formik/>
it will look at name attribute to match form elements. This will mean onSubmit and onChange methods don't need to be linked form/input manually. We pass predefined tailwind styles
from the parent component to avoid repetition and keep our form file tidy.LoginForm.js
import { Formik, Field, Form, ErrorMessage } from 'formik'
//import { loginSchema } from './validation/loginSchema'
export const LoginForm = ({styles}) => (
<>
<Formik
initialValues={{
email: '',
password: '',
}}
// validationSchema={loginSchema}
onSubmit={(values) => {
alert(JSON.stringify(values, null, 2))
}}
>
<Form>
<label className={styles.label} htmlFor='Email'>
Email
</label>
<Field className={styles.field} id='email' name='email' />
<ErrorMessage component='a' className={styles.errorMsg} name='email' />
<label className={styles.label} htmlFor='Email'>
Password
</label>
<Field className={styles.field} id='password' name='password' />
<ErrorMessage
component='a'
className={styles.errorMsg}
name='password'
/>
<div className='mt-8'>
<button type='submit' className={styles.button}>
Login
</button>
</div>
</Form>
</Formik>
</>
)
RegisterForm.js
import { Formik, Field, Form } from 'formik'
export const RegisterForm = ({styles}) => (
<>
<Formik
initialValues={{
name: '',
email: '',
password: '',
}}
onSubmit={(values) => {
alert(JSON.stringify(values, null, 2))
}}
>
<Form>
<label className={styles.label} htmlFor='Name'>
Full Name
</label>
<Field className={styles.field} id='name' name='name' />
<label className={styles.label} htmlFor='Email'>
Email
</label>
<Field className={styles.field} id='email' name='email' />
<label className={styles.label} htmlFor='Password'>
Password
</label>
<Field className={styles.field} id='Password' name='Password' />
<div class='mt-8'>
<button type='submit' className={styles.button}>
Register
</button>
</div>
</Form>
</Formik>
</>
)
Become member
registration form will be render and when Back to login clicked
we will render back login form.import { useState } from 'react'
import { LoginForm } from '../components/LoginForm'
import { RegisterForm } from '../components/RegisterForm'
export const MemberPage = ({ brand, logoUrl }) => {
const [isLogin, setIsLogin] = useState(true)
return (
<div className='flex flex-row w-full'>
<div className='py-12 flex-1'>
<div className='flex bg-white rounded-lg shadow-2xl overflow-hidden mx-auto max-w-sm lg:max-w-4xl'>
<div
className='hidden lg:block lg:w-1/2 bg-auto bg-no-repeat '
style={{ backgroundImage: `url(${logoUrl})` }}
></div>
<div className='w-full p-8 lg:w-1/2'>
<h2 className='text-2xl font-semibold text-gray-600 text-center'>
{brand}
</h2>
<a
onClick={() => {
setIsLogin(!isLogin)
}}
className='flex items-center justify-center mt-4 text-white rounded-lg shadow-md hover:bg-gray-100'
>
<h1 className='px-4 py-3 w-5/6 text-center text-gray-600 font-bold'>
{isLogin ? 'Become Member' : 'Back to Login'}
</h1>
</a>
<div className='mt-4 flex items-center justify-between'>
<span className='border-b border-red-700 w-1/5 lg:w-1/4'></span>
<a
href='#'
className='text-xs text-center text-gray-500 uppercase'
>
{isLogin ? 'Login' : 'Register'}
</a>
<span className='border-b w-1/5 border-red-700 lg:w-1/4'></span>
</div>
{isLogin ? (
<LoginForm styles={styles} />
) : (
<RegisterForm styles={styles} />
)}
</div>
</div>
</div>
</div>
)
}
import { MemberPage } from './memberPage'
export default function Home() {
return (
<main className='flex justify-center items-center w-screen h-screen'>
<MemberPage
brand={'Brand Name'}
logoUrl='https://i.imgur.com/l1kG0LQ.png'
/>
</main>
)
}
cd components && mkdir validation && touch loginSchema.js
loginSchema.js
import * as Yup from 'yup'
export const loginSchema = Yup.object().shape({
email: Yup.string().email().required('Required'),
password: Yup.string().required('Required').min(3, 'Too Short!'),
})
LoginForm.js
//import { loginSchema } from './validation/loginSchema'
// validationSchema={loginSchema}