Skip to content

Instantly share code, notes, and snippets.

@MohammedALREAI
Created December 2, 2021 07:09
Show Gist options
  • Save MohammedALREAI/f7c8ff9bde7f8833e01fd43f6e26560b to your computer and use it in GitHub Desktop.
Save MohammedALREAI/f7c8ff9bde7f8833e01fd43f6e26560b to your computer and use it in GitHub Desktop.
formik example
import React from 'react'
import { useSelector } from 'react-redux'
import { Link } from 'react-router-dom'
// material-ui
import { makeStyles } from '@material-ui/core/styles'
import {
Box,
Button,
Checkbox,
Divider,
FormControl,
FormControlLabel,
FormHelperText,
Grid,
IconButton,
InputAdornment,
InputLabel,
OutlinedInput,
Stack,
Typography,
} from '@material-ui/core'
// third party
import * as Yup from 'yup'
import { Formik } from 'formik'
// project imports
import useAuth from '../../../../hooks/useAuth'
import useScriptRef from '../../../../hooks/useScriptRef'
import AnimateButton from './../../../../ui-component/extended/AnimateButton'
// assets
import Visibility from '@material-ui/icons/Visibility'
import VisibilityOff from '@material-ui/icons/VisibilityOff'
import Google from './../../../../assets/images/icons/social-google.svg'
import { DefaultRootStateProps } from '../../../../types/index'
// style constant
const useStyles = makeStyles((theme) => ({
redButton: {
fontSize: '1rem',
fontWeight: 500,
backgroundColor: theme.palette.mode === 'dark' ? theme.palette.dark.main : theme.palette.grey[50],
border: '1px solid',
borderColor: theme.palette.mode === 'dark' ? theme.palette.dark.light + 20 : theme.palette.grey[100],
color: theme.palette.grey[700],
textTransform: 'none',
'&:hover': {
backgroundColor:
theme.palette.mode === 'dark' ? theme.palette.dark.light + 20 : theme.palette.primary.light,
},
[theme.breakpoints.down('sm')]: {
fontSize: '0.875rem',
},
},
signDivider: {
flexGrow: 1,
},
signText: {
cursor: 'unset',
margin: theme.spacing(2),
padding: '5px 56px',
borderColor:
theme.palette.mode === 'dark'
? theme.palette.dark.light + 20 + ' !important'
: theme.palette.grey[100] + ' !important',
color: theme.palette.grey[900] + '!important',
fontWeight: 500,
},
loginIcon: {
marginRight: '16px',
[theme.breakpoints.down('sm')]: {
marginRight: '8px',
},
},
loginInput: {
...theme.typography.customInput,
},
}))
//============================|| FIREBASE - LOGIN ||============================//
const FirebaseLogin = (props: { login?: number }, { ...others }) => {
const classes = useStyles()
const customization = useSelector((state: DefaultRootStateProps) => state.customization)
const scriptedRef = useScriptRef()
const [checked, setChecked] = React.useState(true)
const { firebaseEmailPasswordSignIn, firebaseGoogleSignIn } = useAuth()
const googleHandler = async () => {
try {
await firebaseGoogleSignIn()
} catch (err) {
console.error(err)
}
}
const [showPassword, setShowPassword] = React.useState(false)
const handleClickShowPassword = () => {
setShowPassword(!showPassword)
}
const handleMouseDownPassword = (event: React.SyntheticEvent) => {
event.preventDefault()
}
return (
<React.Fragment>
<Grid container direction="column" justifyContent="center" spacing={2}>
<Grid item xs={12}>
<AnimateButton>
<Button
disableElevation
fullWidth={true}
className={classes.redButton}
onClick={googleHandler}
size="large"
variant="contained"
>
<img src={Google} alt="google" width="20px" className={classes.loginIcon} /> Sign in with
Google
</Button>
</AnimateButton>
</Grid>
<Grid item xs={12}>
<Box alignItems="center" display="flex">
<Divider className={classes.signDivider} orientation="horizontal" />
<AnimateButton>
<Button
variant="outlined"
className={classes.signText}
sx={{ borderRadius: customization.borderRadius + 'px' }}
disableRipple
disabled
>
OR
</Button>
</AnimateButton>
<Divider className={classes.signDivider} orientation="horizontal" />
</Box>
</Grid>
<Grid item xs={12} container alignItems="center" justifyContent="center">
<Box mb={2}>
<Typography variant="subtitle1">Sign in with Email address</Typography>
</Box>
</Grid>
</Grid>
<Formik
initialValues={{
email: '[email protected]',
password: '123456',
submit: null,
}}
validationSchema={Yup.object().shape({
email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
password: Yup.string().max(255).required('Password is required'),
})}
onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => {
try {
await firebaseEmailPasswordSignIn(values.email, values.password)
if (scriptedRef.current) {
setStatus({ success: true })
setSubmitting(false)
}
} catch (err: any) {
console.error(err)
if (scriptedRef.current) {
setStatus({ success: false })
setErrors({ submit: err.message })
setSubmitting(false)
}
}
}}
>
{({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => (
<form noValidate onSubmit={handleSubmit} {...others}>
<FormControl
fullWidth
error={Boolean(touched.email && errors.email)}
className={classes.loginInput}
variant="outlined"
>
<InputLabel htmlFor="outlined-adornment-email-login">Email Address / Username</InputLabel>
<OutlinedInput
id="outlined-adornment-email-login"
type="email"
value={values.email}
name="email"
onBlur={handleBlur}
onChange={handleChange}
label="Email Address / Username"
inputProps={{}}
/>
{touched.email && errors.email && (
<FormHelperText error id="standard-weight-helper-text-email-login">
{' '}
{errors.email}{' '}
</FormHelperText>
)}
</FormControl>
<FormControl
fullWidth
error={Boolean(touched.password && errors.password)}
className={classes.loginInput}
variant="outlined"
>
<InputLabel htmlFor="outlined-adornment-password-login">Password</InputLabel>
<OutlinedInput
id="outlined-adornment-password-login"
type={showPassword ? 'text' : 'password'}
value={values.password}
name="password"
onBlur={handleBlur}
onChange={handleChange}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
edge="end"
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
}
label="Password"
inputProps={{}}
/>
{touched.password && errors.password && (
<FormHelperText error id="standard-weight-helper-text-password-login">
{' '}
{errors.password}{' '}
</FormHelperText>
)}
</FormControl>
<Stack direction="row" alignItems="center" justifyContent="space-between" spacing={1}>
<FormControlLabel
control={
<Checkbox
checked={checked}
onChange={(event) => setChecked(event.target.checked)}
name="checked"
color="primary"
/>
}
label="Remember me"
/>
<Typography
variant="subtitle1"
component={Link}
to={props.login ? '/pages/forgot-password/forgot-password' + props.login : '#'}
color="secondary"
sx={{ textDecoration: 'none' }}
>
Forgot Password?
</Typography>
</Stack>
{errors.submit && (
<Box mt={3}>
<FormHelperText error>{errors.submit}</FormHelperText>
</Box>
)}
<Box mt={2}>
<AnimateButton>
<Button
disableElevation
disabled={isSubmitting}
fullWidth
size="large"
type="submit"
variant="contained"
color="secondary"
>
Sign in
</Button>
</AnimateButton>
</Box>
</form>
)}
</Formik>
</React.Fragment>
)
}
export default FirebaseLogin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment