UNPKG

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.

436 lines (410 loc) 17.6 kB
// ** React Imports import { useState, Fragment } from 'react' // ** Next Imports import Link from 'next/link' // ** MUI Components import Button from '@mui/material/Button' import Divider from '@mui/material/Divider' import Checkbox from '@mui/material/Checkbox' import TextField from '@mui/material/TextField' import InputLabel from '@mui/material/InputLabel' import IconButton from '@mui/material/IconButton' import Box from '@mui/material/Box' import FormControl from '@mui/material/FormControl' import useMediaQuery from '@mui/material/useMediaQuery' import OutlinedInput from '@mui/material/OutlinedInput' import { styled, useTheme } from '@mui/material/styles' import FormHelperText from '@mui/material/FormHelperText' import InputAdornment from '@mui/material/InputAdornment' import FormControlLabel from '@mui/material/FormControlLabel' import Typography from '@mui/material/Typography' // ** Icons Imports import Google from 'mdi-material-ui/Google' import Github from 'mdi-material-ui/Github' import Twitter from 'mdi-material-ui/Twitter' import Facebook from 'mdi-material-ui/Facebook' import EyeOutline from 'mdi-material-ui/EyeOutline' import EyeOffOutline from 'mdi-material-ui/EyeOffOutline' // ** Third Party Imports import * as yup from 'yup' import { yupResolver } from '@hookform/resolvers/yup' import { useForm, Controller } from 'react-hook-form' // ** Configs import themeConfig from '~/configs/themeConfig' // ** Layout Import import BlankLayout from '~/@core/layouts/BlankLayout' // ** Hooks import { useAuth } from '~/hooks/useAuth' import { useSettings } from '~/@core/hooks/useSettings' // ** Demo Imports import FooterIllustrationsV2 from '~/views/pages/auth/FooterIllustrationsV2' const defaultValues = { email: '', username: '', password: '', terms: false } // ** Styled Components const RegisterIllustrationWrapper = styled(Box)(({ theme }) => ({ padding: theme.spacing(20), paddingRight: '0 !important', [theme.breakpoints.down('lg')]: { padding: theme.spacing(10) } })) const RegisterIllustration = styled('img')(({ theme }) => ({ maxWidth: '46rem', [theme.breakpoints.down('lg')]: { maxWidth: '35rem' } })) const TreeIllustration = styled('img')(({ theme }) => ({ bottom: 0, left: '1.875rem', position: 'absolute', [theme.breakpoints.down('lg')]: { left: 0 } })) const RightWrapper = styled(Box)(({ theme }) => ({ width: '100%', [theme.breakpoints.up('md')]: { maxWidth: 450 } })) const BoxWrapper = styled(Box)(({ theme }) => ({ [theme.breakpoints.down('xl')]: { width: '100%' }, [theme.breakpoints.down('md')]: { maxWidth: 400 } })) const TypographyStyled = styled(Typography)(({ theme }) => ({ fontWeight: 600, marginBottom: theme.spacing(1.5), [theme.breakpoints.down('md')]: { mt: theme.spacing(8) } })) const LinkStyled = styled('a')(({ theme }) => ({ textDecoration: 'none', color: theme.palette.primary.main })) const Register = () => { // ** States const [showPassword, setShowPassword] = useState(false) // ** Hooks const theme = useTheme() const { register } = useAuth() const { settings } = useSettings() const hidden = useMediaQuery(theme.breakpoints.down('md')) // ** Vars const { skin } = settings const schema = yup.object().shape({ password: yup.string().min(5).required(), username: yup.string().min(3).required(), email: yup.string().email().required(), terms: yup.bool().oneOf([true], 'You must accept the privacy policy & terms') }) const { control, setError, handleSubmit, formState: { errors } } = useForm({ defaultValues, mode: 'onBlur', resolver: yupResolver(schema) }) const onSubmit = data => { const { email, username, password } = data register({ email, username, password }, err => { if (err.email) { setError('email', { type: 'manual', message: err.email }) } if (err.username) { setError('username', { type: 'manual', message: err.username }) } }) } const imageSource = skin === 'bordered' ? 'auth-v2-register-illustration-bordered' : 'auth-v2-register-illustration' return ( <Box className='content-right'> {!hidden ? ( <Box sx={{ flex: 1, display: 'flex', position: 'relative', alignItems: 'center', justifyContent: 'center' }}> <RegisterIllustrationWrapper> <RegisterIllustration alt='register-illustration' src={`/images/pages/${imageSource}-${theme.palette.mode}.png`} /> </RegisterIllustrationWrapper> <FooterIllustrationsV2 image={<TreeIllustration alt='tree' src='/images/pages/tree-2.png' />} /> </Box> ) : null} <RightWrapper sx={skin === 'bordered' && !hidden ? { borderLeft: `1px solid ${theme.palette.divider}` } : {}}> <Box sx={{ p: 12, height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'background.paper' }} > <BoxWrapper> <Box sx={{ top: 30, left: 40, display: 'flex', position: 'absolute', alignItems: 'center', justifyContent: 'center' }} > <svg width={35} height={29} version='1.1' viewBox='0 0 30 23' xmlns='http://www.w3.org/2000/svg' xmlnsXlink='http://www.w3.org/1999/xlink' > <g stroke='none' strokeWidth='1' fill='none' fillRule='evenodd'> <g id='Artboard' transform='translate(-95.000000, -51.000000)'> <g id='logo' transform='translate(95.000000, 50.000000)'> <path id='Combined-Shape' fill={theme.palette.primary.main} d='M30,21.3918362 C30,21.7535219 29.9019196,22.1084381 29.7162004,22.4188007 C29.1490236,23.366632 27.9208668,23.6752135 26.9730355,23.1080366 L26.9730355,23.1080366 L23.714971,21.1584295 C23.1114106,20.7972624 22.7419355,20.1455972 22.7419355,19.4422291 L22.7419355,19.4422291 L22.741,12.7425689 L15,17.1774194 L7.258,12.7425689 L7.25806452,19.4422291 C7.25806452,20.1455972 6.88858935,20.7972624 6.28502902,21.1584295 L3.0269645,23.1080366 C2.07913318,23.6752135 0.850976404,23.366632 0.283799571,22.4188007 C0.0980803893,22.1084381 2.0190442e-15,21.7535219 0,21.3918362 L0,3.58469444 L0.00548573643,3.43543209 L0.00548573643,3.43543209 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 L15,9.19354839 L26.9548759,1.86636639 C27.2693965,1.67359571 27.6311047,1.5715689 28,1.5715689 C29.1045695,1.5715689 30,2.4669994 30,3.5715689 L30,3.5715689 Z' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='0 8.58870968 7.25806452 12.7505183 7.25806452 16.8305646' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='0 8.58870968 7.25806452 12.6445567 7.25806452 15.1370162' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='22.7419355 8.58870968 30 12.7417372 30 16.9537453' transform='translate(26.370968, 12.771227) scale(-1, 1) translate(-26.370968, -12.771227) ' /> <polygon id='Rectangle' opacity='0.077704' fill={theme.palette.common.black} points='22.7419355 8.58870968 30 12.6409734 30 15.2601969' transform='translate(26.370968, 11.924453) scale(-1, 1) translate(-26.370968, -11.924453) ' /> <path id='Rectangle' fillOpacity='0.15' fill={theme.palette.common.white} d='M3.04512412,1.86636639 L15,9.19354839 L15,9.19354839 L15,17.1774194 L0,8.58649679 L0,3.5715689 C3.0881846e-16,2.4669994 0.8954305,1.5715689 2,1.5715689 C2.36889529,1.5715689 2.73060353,1.67359571 3.04512412,1.86636639 Z' /> <path id='Rectangle' fillOpacity='0.35' fill={theme.palette.common.white} transform='translate(22.500000, 8.588710) scale(-1, 1) translate(-22.500000, -8.588710) ' d='M18.0451241,1.86636639 L30,9.19354839 L30,9.19354839 L30,17.1774194 L15,8.58649679 L15,3.5715689 C15,2.4669994 15.8954305,1.5715689 17,1.5715689 C17.3688953,1.5715689 17.7306035,1.67359571 18.0451241,1.86636639 Z' /> </g> </g> </g> </svg> <Typography variant='h6' sx={{ ml: 3, lineHeight: 1, fontWeight: 600, textTransform: 'uppercase', fontSize: '1.5rem !important' }} > {themeConfig.templateName} </Typography> </Box> <Box sx={{ mb: 6 }}> <TypographyStyled variant='h5'>Adventure starts here 🚀</TypographyStyled> <Typography variant='body2'>Make your app management easy and fun!</Typography> </Box> <form noValidate autoComplete='off' onSubmit={handleSubmit(onSubmit)}> <FormControl fullWidth sx={{ mb: 4 }}> <Controller name='username' control={control} rules={{ required: true }} render={({ field: { value, onChange, onBlur } }) => ( <TextField autoFocus value={value} onBlur={onBlur} label='Username' onChange={onChange} placeholder='johndoe' error={Boolean(errors.username)} /> )} /> {errors.username && ( <FormHelperText sx={{ color: 'error.main' }}>{errors.username.message}</FormHelperText> )} </FormControl> <FormControl fullWidth sx={{ mb: 4 }}> <Controller name='email' control={control} rules={{ required: true }} render={({ field: { value, onChange, onBlur } }) => ( <TextField value={value} label='Email' onBlur={onBlur} onChange={onChange} error={Boolean(errors.email)} placeholder='user@email.com' /> )} /> {errors.email && <FormHelperText sx={{ color: 'error.main' }}>{errors.email.message}</FormHelperText>} </FormControl> <FormControl fullWidth> <InputLabel htmlFor='auth-login-v2-password' error={Boolean(errors.password)}> Password </InputLabel> <Controller name='password' control={control} rules={{ required: true }} render={({ field: { value, onChange, onBlur } }) => ( <OutlinedInput value={value} label='Password' onBlur={onBlur} onChange={onChange} id='auth-login-v2-password' error={Boolean(errors.password)} type={showPassword ? 'text' : 'password'} endAdornment={ <InputAdornment position='end'> <IconButton edge='end' onMouseDown={e => e.preventDefault()} onClick={() => setShowPassword(!showPassword)} > {showPassword ? <EyeOutline /> : <EyeOffOutline />} </IconButton> </InputAdornment> } /> )} /> {errors.password && ( <FormHelperText sx={{ color: 'error.main' }}>{errors.password.message}</FormHelperText> )} </FormControl> <FormControl sx={{ mt: 1.5, mb: 4 }} error={Boolean(errors.terms)}> <Controller name='terms' control={control} rules={{ required: true }} render={({ field: { value, onChange } }) => { return ( <FormControlLabel sx={{ ...(errors.terms ? { color: 'error.main' } : null), '& .MuiFormControlLabel-label': { fontSize: '0.875rem' } }} control={ <Checkbox checked={value} onChange={onChange} sx={errors.terms ? { color: 'error.main' } : null} /> } label={ <> <Typography variant='body2' component='span' sx={{ color: errors.terms ? 'error.main' : '' }} > I agree to{' '} </Typography> <Link href='/' passHref> <LinkStyled onClick={e => e.preventDefault()}>privacy policy & terms</LinkStyled> </Link> </> } /> ) }} /> {errors.terms && ( <FormHelperText sx={{ mt: 0, color: 'error.main' }}>{errors.terms.message}</FormHelperText> )} </FormControl> <Button fullWidth size='large' type='submit' variant='contained' sx={{ mb: 7 }}> Sign up </Button> <Box sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', justifyContent: 'center' }}> <Typography variant='body2' sx={{ mr: 2 }}> Already have an account? </Typography> <Typography variant='body2'> <Link href='/login' passHref> <LinkStyled>Sign in instead</LinkStyled> </Link> </Typography> </Box> <Divider sx={{ my: 5 }}>or</Divider> <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}> <Link href='/' passHref> <IconButton component='a' onClick={e => e.preventDefault()}> <Facebook sx={{ color: '#497ce2' }} /> </IconButton> </Link> <Link href='/' passHref> <IconButton component='a' onClick={e => e.preventDefault()}> <Twitter sx={{ color: '#1da1f2' }} /> </IconButton> </Link> <Link href='/' passHref> <IconButton component='a' onClick={e => e.preventDefault()}> <Github sx={{ color: theme => (theme.palette.mode === 'light' ? '#272727' : theme.palette.grey[300]) }} /> </IconButton> </Link> <Link href='/' passHref> <IconButton component='a' onClick={e => e.preventDefault()}> <Google sx={{ color: '#db4437' }} /> </IconButton> </Link> </Box> </form> </BoxWrapper> </Box> </RightWrapper> </Box> ) } Register.getLayout = page => <BlankLayout>{page}</BlankLayout> Register.guestGuard = true export default Register