Skip to content

Instantly share code, notes, and snippets.

@alfonmga
Created February 24, 2020 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alfonmga/014a11ba9793927dffeb847d896c607c to your computer and use it in GitHub Desktop.
Save alfonmga/014a11ba9793927dffeb847d896c607c to your computer and use it in GitHub Desktop.
@ValidateInput(RegisterUserInput)
@UseMiddleware(RecaptchaGqlMiddleware)
@Mutation(() => RegisterWithCredentialsUnion)
async registerWithCredentials(
@Session() session: Express.Session,
@Arg('input') input: RegisterUserInput,
): Promise<typeof RegisterWithCredentialsUnion> {
const user = await this.userService.getUserByEmailAddress(input.email)
if (user) {
if (user.accessStatus === USER_ACCESS_STATUS.PENDING_JOIN) {
return new RegisterWithCredentialsErrorType(RegisterWithCredentialsErrorCodes.USER_PENDING_JOIN_ACCOUNT)
}
return new RegisterWithCredentialsErrorType(RegisterWithCredentialsErrorCodes.USER_EMAIL_ALREADY_REGISTRED)
}
const registredUserId = await this.userService.registerWithCredentials(input.email, input.password, input.locale)
session.user = {
id: registredUserId,
}
return new SuccessfulOperationType()
}
const RegisterWithCredentialsForm: FC<{
disableGoogleRegistration: () => void
enableGoogleRegistration: () => void
}> = ({ disableGoogleRegistration, enableGoogleRegistration }) => {
const [errMsg, setErrMsg] = React.useState("")
const [isRecaptchaRendered, setIsRecaptchaRendered] = React.useState(false)
const { i18n, t } = useTranslation()
const [registerUser] = useRegisterWithCredentialsMutation()
const recaptchaRef = React.useRef<Reaptcha>(null)
const { closeSnackbar } = useSnackbar()
const { login: loginUser } = useStoreActions(actions => actions.auth)
React.useEffect(() => {
if (isRecaptchaRendered) {
recaptchaRef.current!.renderExplicitly()
}
}, [isRecaptchaRendered])
return (
<Formik
initialValues={{
email: "",
password: "",
}}
validationSchema={Yup.object().shape({
email: Yup.string()
.email(t("inputValidation.invalidEmail"))
.required(`Email ${t("common.required").toLocaleLowerCase()}`),
password: Yup.string()
.min(5, t("inputValidation.minPasswordLength", { length: "5" }))
.required(
lodashCapitalize(t("inputValidation.passwordRequired").toString())
),
})}
onSubmit={async (
values,
{ setSubmitting, setErrors: setFormikErrors }
) => {
setSubmitting(true)
setErrMsg("")
disableGoogleRegistration()
closeSnackbar()
const recaptchaToken = await recaptchaRef.current!.getResponse()
if (!recaptchaToken) {
return recaptchaRef.current!.execute()
}
try {
const { data } = await registerUser({
variables: {
input: {
email: values.email,
locale: i18n.language as LOCALES,
password: values.password,
recaptchaInput: recaptchaToken,
},
},
})
const registerWithCredentialsData = data!.registerWithCredentials
switch (registerWithCredentialsData.__typename) {
case "InvalidInputErrorType":
formikUtils.handleGqlServerInputErrors(
setFormikErrors,
registerWithCredentialsData.fieldErrors
)
break
case "InvalidRecaptchaErrorType":
setErrMsg(t("errors.RECAPTCHA_INPUT_ERROR"))
break
case "RegisterWithCredentialsErrorType":
switch (registerWithCredentialsData.errorCode) {
case RegisterWithCredentialsErrorCodes.USER_EMAIL_ALREADY_REGISTRED: {
setFormikErrors({
email: t(
"errors.RegisterWithCredentialsErrorCodes.USER_EMAIL_ALREADY_REGISTRED"
),
})
break
}
case RegisterWithCredentialsErrorCodes.USER_PENDING_JOIN_ACCOUNT:
setErrMsg(t("errors.USER_PENDING_JOIN_ACCOUNT"))
break
}
break
case "SuccessfulOperationType":
return loginUser()
}
} catch (_) {}
recaptchaRef.current!.reset()
setSubmitting(false)
enableGoogleRegistration()
}}
>
{({ isSubmitting, submitForm }) => (
<Form>
<Reaptcha
ref={recaptchaRef}
sitekey={config.GOOGLE_RECAPTCHA_SITE_KEY}
size="invisible"
explicit
onLoad={() => setIsRecaptchaRendered(true)}
onVerify={async () => {
await submitForm()
}}
onExpire={() => recaptchaRef.current!.reset()}
badge="bottomleft"
/>
{errMsg && (
<Box mb={2}>
<ErrorBox message={errMsg} />
</Box>
)}
<Box mb={1.25}>
<Field
component={TextField}
name="email"
type="email"
autoComplete="username"
label="Email"
variant="outlined"
fullWidth
size="small"
/>
</Box>
<Box mb={1.25}>
<Field
component={TextField}
type="password"
label={t("common.password")}
name="password"
variant="outlined"
fullWidth
size="small"
autoComplete="new-password"
/>
</Box>
{isSubmitting && (
<Box mb={2}>
<LinearProgress />
</Box>
)}
<Button
type="submit"
variant="contained"
color="primary"
disabled={isSubmitting}
style={{ textTransform: "none" }}
size="large"
fullWidth
>
<Box px={1} py={0.05}>
<Typography style={{ fontWeight: 700, fontSize: "16px" }}>
{t("getStartedPage.signupBtn")}
</Typography>
</Box>
</Button>
</Form>
)}
</Formik>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment