Skip to content

Instantly share code, notes, and snippets.

@juddey
Created September 7, 2019 22:45
Show Gist options
  • Save juddey/81a6f4a7d8ffb9e6832a0f372985ed40 to your computer and use it in GitHub Desktop.
Save juddey/81a6f4a7d8ffb9e6832a0f372985ed40 to your computer and use it in GitHub Desktop.
EmailValidationAsync Field
import React, { useState } from 'react'
import { InputAdornment, Typography } from '@material-ui/core'
import Fade from '@material-ui/core/Fade'
import CircularProgress from '@material-ui/core/CircularProgress'
import { MdCheckCircle } from 'react-icons/md'
import { ErrorMessage } from 'formik'
import TextField from 'Components/TextField'
import { string } from 'yup'
import { useAsyncFn } from 'react-use'
import { useApolloClient } from '@apollo/react-hooks'
import { FIND_BY_IDENTIFIER } from 'Queries/FindByIdentifier.query'
import { not } from 'ramda'
const schema = string()
.ensure()
.required('Oops, email is required')
.email('Oops, check your email format')
const LoginInstead = () => { return (<div>Would you like to login instead?</div>) }
function FormEmailAsync ({
name,
email,
handleChange,
label,
setFieldError,
setFieldTouched,
onBlurred,
...rest
}) {
const [emailValid, setValidEmail] = useState('')
const client = useApolloClient()
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
const [emailPresent, setEmailPresent] = useState(false)
//eslint-disable-next-line no-unused-vars
const [theState, asyncFunc] = useAsyncFn(async value => {
const returnedSchema = await schema.validate(value)
if (returnedSchema !== value) { return returnedSchema }
setLoading(true)
const { data } = await client.query({
query: FIND_BY_IDENTIFIER,
variables: { identifier: value },
context: { uri: process.env.REACT_APP_GRAPHQL_PUBLIC_API }
})
setValidEmail(not(data.findByIdentifier.present))
setEmailPresent(data.findByIdentifier.present)
setLoading(false)
return value
}, [])
const onBlurFunc = async (name, email) => {
setFieldTouched(name)
let returnFromAsync = await asyncFunc(email)
if (returnFromAsync === email) {
onBlurred(returnFromAsync)
} else {
setError(true)
setFieldError(name, returnFromAsync.message)
}
}
const onChangeFunc = (evt) => {
setValidEmail(null)
setEmailPresent(false)
setError(false)
handleChange(evt)
}
return (
<div>
<TextField
error={error}
name={name}
variant='outlined'
value={email}
placeholder={'email@example.com'}
onChange={evt => onChangeFunc(evt)}
label={label}
onBlur={event => onBlurFunc(name, event.target.value)}
InputProps={{
endAdornment: (
<InputAdornment position='end'>
<Fade
in={loading}
style={{
transitionDelay: loading ? '800ms' : '0ms'
}}
unmountOnExit
>
<CircularProgress size={16} />
</Fade>
{ emailValid === true &&
<Fade
in={emailValid}
>
<MdCheckCircle
color='green'
data-testid={'success'}
size={16}
/>
</Fade> }
</InputAdornment>
)
}}
{...rest}
/>
{ emailPresent ? LoginInstead() :
<ErrorMessage
name='email'
render={msg => <Typography color='error'>{msg}</Typography> }
/>}
</div>
)
}
export default FormEmailAsync
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment