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.
211 lines (194 loc) • 7.15 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'
import CircularProgress from '@mui/material/CircularProgress'
// ** Third Party Imports
import toast from 'react-hot-toast'
import { useForm, Controller } from 'react-hook-form'
// ** Icons Imports
import EyeOutline from 'mdi-material-ui/EyeOutline'
import EyeOffOutline from 'mdi-material-ui/EyeOffOutline'
const defaultValues = {
email: '',
lastName: '',
password: '',
firstName: ''
}
const FormValidationAsync = () => {
// ** States
const [loading, setLoading] = useState(false)
const [state, setState] = useState({
password: '',
showPassword: false
})
// ** Hook
const {
control,
handleSubmit,
formState: { errors }
} = useForm({ defaultValues })
const handleClickShowPassword = () => {
setState({ ...state, showPassword: !state.showPassword })
}
const handleMouseDownPassword = event => {
event.preventDefault()
}
const onSubmit = async () => {
setLoading(true)
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
await sleep(2000)
setLoading(false)
toast.success('Form Submitted')
}
return (
<Card>
<CardHeader title='Async Submit' 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-async-first-name'
/>
)}
/>
{errors.firstName && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-async-first-name'>
This field is required
</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-async-last-name'
/>
)}
/>
{errors.lastName && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-async-last-name'>
This field is required
</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-async-email'
/>
)}
/>
{errors.email && (
<FormHelperText sx={{ color: 'error.main' }} id='validation-async-email'>
This field is required
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12}>
<FormControl fullWidth>
<InputLabel htmlFor='validation-async-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-async-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-async-password'>
This field is required
</FormHelperText>
)}
</FormControl>
</Grid>
<Grid item xs={12}>
<Button size='large' type='submit' variant='contained'>
{loading ? (
<CircularProgress
sx={{
color: 'common.white',
width: '20px !important',
height: '20px !important',
mr: theme => theme.spacing(2)
}}
/>
) : null}
Submit
</Button>
</Grid>
</Grid>
</form>
</CardContent>
</Card>
)
}
export default FormValidationAsync