Path: blob/1.0-develop/resources/scripts/components/auth/LoginContainer.tsx
10266 views
import React, { useEffect, useRef, useState } from 'react';1import { Link, RouteComponentProps } from 'react-router-dom';2import login from '@/api/auth/login';3import LoginFormContainer from '@/components/auth/LoginFormContainer';4import { useStoreState } from 'easy-peasy';5import { Formik, FormikHelpers } from 'formik';6import { object, string } from 'yup';7import Field from '@/components/elements/Field';8import tw from 'twin.macro';9import Button from '@/components/elements/Button';10import Reaptcha from 'reaptcha';11import useFlash from '@/plugins/useFlash';1213interface Values {14username: string;15password: string;16}1718const LoginContainer = ({ history }: RouteComponentProps) => {19const ref = useRef<Reaptcha>(null);20const [token, setToken] = useState('');2122const { clearFlashes, clearAndAddHttpError } = useFlash();23const { enabled: recaptchaEnabled, siteKey } = useStoreState((state) => state.settings.data!.recaptcha);2425useEffect(() => {26clearFlashes();27}, []);2829const onSubmit = (values: Values, { setSubmitting }: FormikHelpers<Values>) => {30clearFlashes();3132// If there is no token in the state yet, request the token and then abort this submit request33// since it will be re-submitted when the recaptcha data is returned by the component.34if (recaptchaEnabled && !token) {35ref.current!.execute().catch((error) => {36console.error(error);3738setSubmitting(false);39clearAndAddHttpError({ error });40});4142return;43}4445login({ ...values, recaptchaData: token })46.then((response) => {47if (response.complete) {48// @ts-expect-error this is valid49window.location = response.intended || '/';50return;51}5253history.replace('/auth/login/checkpoint', { token: response.confirmationToken });54})55.catch((error) => {56console.error(error);5758setToken('');59if (ref.current) ref.current.reset();6061setSubmitting(false);62clearAndAddHttpError({ error });63});64};6566return (67<Formik68onSubmit={onSubmit}69initialValues={{ username: '', password: '' }}70validationSchema={object().shape({71username: string().required('A username or email must be provided.'),72password: string().required('Please enter your account password.'),73})}74>75{({ isSubmitting, setSubmitting, submitForm }) => (76<LoginFormContainer title={'Login to Continue'} css={tw`w-full flex`}>77<Field light type={'text'} label={'Username or Email'} name={'username'} disabled={isSubmitting} />78<div css={tw`mt-6`}>79<Field light type={'password'} label={'Password'} name={'password'} disabled={isSubmitting} />80</div>81<div css={tw`mt-6`}>82<Button type={'submit'} size={'xlarge'} isLoading={isSubmitting} disabled={isSubmitting}>83Login84</Button>85</div>86{recaptchaEnabled && (87<Reaptcha88ref={ref}89size={'invisible'}90sitekey={siteKey || '_invalid_key'}91onVerify={(response) => {92setToken(response);93submitForm();94}}95onExpire={() => {96setSubmitting(false);97setToken('');98}}99/>100)}101<div css={tw`mt-6 text-center`}>102<Link103to={'/auth/password'}104css={tw`text-xs text-neutral-500 tracking-wide no-underline uppercase hover:text-neutral-600`}105>106Forgot password?107</Link>108</div>109</LoginFormContainer>110)}111</Formik>112);113};114115export default LoginContainer;116117118