react-garden
Version:
React + TypeScript + ThreeJS app using Material UI on NextJS, Apollo Client, GraphQL + WordPress REST APIs, for ThreeD web development.. a part of the threed.ai code family.
223 lines (206 loc) • 7.4 kB
JavaScript
// ** React Imports
import { useState } from 'react'
// ** MUI Imports
import Card from '@mui/material/Card'
import Grid from '@mui/material/Grid'
import Button from '@mui/material/Button'
import TextField from '@mui/material/TextField'
import CardHeader from '@mui/material/CardHeader'
import InputLabel from '@mui/material/InputLabel'
import IconButton from '@mui/material/IconButton'
import CardContent from '@mui/material/CardContent'
import FormControl from '@mui/material/FormControl'
import OutlinedInput from '@mui/material/OutlinedInput'
import FormHelperText from '@mui/material/FormHelperText'
import InputAdornment from '@mui/material/InputAdornment'
// ** Third Party Imports
import * as yup from 'yup'
import toast from 'react-hot-toast'
import { useForm, Controller } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup/dist/yup'
// ** Icons Imports
import EyeOutline from 'mdi-material-ui/EyeOutline'
import EyeOffOutline from 'mdi-material-ui/EyeOffOutline'
const defaultValues = {
email: '',
lastName: '',
password: '',
firstName: ''
}
const showErrors = (field, valueLen, min) => {
if (valueLen === 0) {
return `${field} field is required`
} else if (valueLen > 0 && valueLen < min) {
return `${field} must be at least ${min} characters`
} else {
return ''
}
}
const schema = yup.object().shape({
email: yup.string().email().required(),
lastName: yup
.string()
.min(3, obj => showErrors('lastName', obj.value.length, obj.min))
.required(),
password: yup
.string()
.min(8, obj => showErrors('password', obj.value.length, obj.min))
.required(),
firstName: yup
.string()
.min(3, obj => showErrors('firstName', obj.value.length, obj.min))
.required()
})
const FormValidationSchema = () => {
// ** States
const [state, setState] = useState({
password: '',
showPassword: false
})
// ** Hook
const {
control,
handleSubmit,
formState: { errors }
} = useForm({
defaultValues,
mode: 'onChange',
resolver: yupResolver(schema)
})
const handleClickShowPassword = () => {
setState({ ...state, showPassword: !state.showPassword })
}
const handleMouseDownPassword = event => {
event.preventDefault()
}
const onSubmit = () => toast.success('Form Submitted')
return (
<Card>
<CardHeader title='Validation Schema With OnChange' titleTypographyProps={{ variant: 'h6' }} />
<CardContent>
<form onSubmit={handleSubmit(onSubmit)}>
<Grid container spacing={5}>
<Grid item xs={12}>
<FormControl fullWidth>
<Controller
name='firstName'
control={control}
rules={{ required: true }}
render={({ field: { value, onChange } }) => (
<TextField
value={value}
label='First Name'
onChange={onChange}
placeholder='Leonard'
error={Boolean(errors.firstName)}
aria-describedby='validation-schema-first-name'
/>
)}
/>
{errors.firstName && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-schema-first-name'>
{errors.firstName.message}
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12}>
<FormControl fullWidth>
<Controller
name='lastName'
control={control}
rules={{ required: true }}
render={({ field: { value, onChange } }) => (
<TextField
value={value}
label='Last Name'
onChange={onChange}
placeholder='Carter'
error={Boolean(errors.lastName)}
aria-describedby='validation-schema-last-name'
/>
)}
/>
{errors.lastName && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-schema-last-name'>
{errors.lastName.message}
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12}>
<FormControl fullWidth>
<Controller
name='email'
control={control}
rules={{ required: true }}
render={({ field: { value, onChange } }) => (
<TextField
type='email'
value={value}
label='Email'
onChange={onChange}
error={Boolean(errors.email)}
placeholder='carterleonard@gmail.com'
aria-describedby='validation-schema-email'
/>
)}
/>
{errors.email && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-schema-email'>
{errors.email.message}
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12}>
<FormControl fullWidth>
<InputLabel htmlFor='validation-schema-password' error={Boolean(errors.password)}>
Password
</InputLabel>
<Controller
name='password'
control={control}
rules={{ required: true }}
render={({ field: { value, onChange } }) => (
<OutlinedInput
value={value}
label='Password'
onChange={onChange}
id='validation-schema-password'
error={Boolean(errors.password)}
type={state.showPassword ? 'text' : 'password'}
endAdornment={
<InputAdornment position='end'>
<IconButton
edge='end'
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
aria-label='toggle password visibility'
>
{state.showPassword ? <EyeOutline /> : <EyeOffOutline />}
</IconButton>
</InputAdornment>
}
/>
)}
/>
{errors.password && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-schema-password'>
{errors.password.message}
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12}>
<Button size='large' type='submit' variant='contained'>
Submit
</Button>
</Grid>
</Grid>
</form>
</CardContent>
</Card>
)
}
export default FormValidationSchema