2022-06-09 12:22:19 -07:00
|
|
|
import { AxiosError } from 'axios';
|
|
|
|
import React from 'react';
|
2022-11-11 15:07:02 -08:00
|
|
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
2022-03-21 11:09:01 -07:00
|
|
|
|
|
|
|
import snackbar from 'soapbox/actions/snackbar';
|
2022-06-07 13:21:18 -07:00
|
|
|
import { checkEmailVerification, postEmailVerification, requestEmailVerification } from 'soapbox/actions/verification';
|
2022-03-21 11:09:01 -07:00
|
|
|
import Icon from 'soapbox/components/icon';
|
|
|
|
import { Button, Form, FormGroup, Input, Text } from 'soapbox/components/ui';
|
2022-06-09 12:22:19 -07:00
|
|
|
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
2022-03-21 11:09:01 -07:00
|
|
|
|
2022-11-11 15:07:02 -08:00
|
|
|
const messages = defineMessages({
|
|
|
|
verificationSuccess: { id: 'email_verification.success', defaultMessage: 'Verification email sent successfully.' },
|
|
|
|
verificationFail: { id: 'email_verification.fail', defaultMessage: 'Failed to request email verification.' },
|
2022-11-16 14:52:12 -08:00
|
|
|
verificationFailTakenAlert: { id: 'email_verifilcation.exists', defaultMessage: 'This email has already been taken.' },
|
2022-11-11 15:07:02 -08:00
|
|
|
verificationFailTaken: { id: 'email_verification.taken', defaultMessage: 'is taken' },
|
2022-11-26 05:09:28 -08:00
|
|
|
emailLabel: { id: 'email_verification.email.label', defaultMessage: 'E-mail address' },
|
2022-11-11 15:07:02 -08:00
|
|
|
});
|
|
|
|
|
2022-03-21 11:09:01 -07:00
|
|
|
const Statuses = {
|
|
|
|
IDLE: 'IDLE',
|
|
|
|
REQUESTED: 'REQUESTED',
|
|
|
|
FAIL: 'FAIL',
|
|
|
|
};
|
|
|
|
|
|
|
|
const EMAIL_REGEX = /^[^@\s]+@[^@\s]+$/;
|
|
|
|
|
2022-06-09 12:22:19 -07:00
|
|
|
interface IEmailSent {
|
|
|
|
handleSubmit: React.FormEventHandler,
|
|
|
|
}
|
|
|
|
|
|
|
|
const EmailSent: React.FC<IEmailSent> = ({ handleSubmit }) => {
|
|
|
|
const dispatch = useAppDispatch();
|
2022-03-21 11:09:01 -07:00
|
|
|
|
|
|
|
const checkEmailConfirmation = () => {
|
|
|
|
dispatch(checkEmailVerification())
|
|
|
|
.then(() => dispatch(postEmailVerification()))
|
|
|
|
.catch(() => null);
|
|
|
|
};
|
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
const intervalId = setInterval(() => checkEmailConfirmation(), 2500);
|
|
|
|
|
|
|
|
return () => clearInterval(intervalId);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className='sm:pt-10 mx-auto flex flex-col items-center justify-center'>
|
2022-07-09 09:20:02 -07:00
|
|
|
<Icon src={require('@tabler/icons/send.svg')} className='text-primary-600 dark:text-primary-400 h-12 w-12 mb-5' />
|
2022-03-21 11:09:01 -07:00
|
|
|
|
2022-07-22 10:30:16 -07:00
|
|
|
<div className='space-y-2 text-center mb-4'>
|
2022-03-21 11:09:01 -07:00
|
|
|
<Text weight='bold' size='3xl'>We sent you an email</Text>
|
|
|
|
<Text theme='muted'>Click on the link in the email to validate your email.</Text>
|
|
|
|
</div>
|
|
|
|
|
2022-07-22 10:30:16 -07:00
|
|
|
<Button theme='tertiary' onClick={handleSubmit}>Resend verification email</Button>
|
2022-03-21 11:09:01 -07:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const EmailVerification = () => {
|
|
|
|
const intl = useIntl();
|
2022-06-09 12:22:19 -07:00
|
|
|
const dispatch = useAppDispatch();
|
2022-03-21 11:09:01 -07:00
|
|
|
|
2022-06-20 06:46:43 -07:00
|
|
|
const isLoading = useAppSelector((state) => state.verification.isLoading) as boolean;
|
2022-03-21 11:09:01 -07:00
|
|
|
|
|
|
|
const [email, setEmail] = React.useState('');
|
|
|
|
const [status, setStatus] = React.useState(Statuses.IDLE);
|
2022-06-09 12:22:19 -07:00
|
|
|
const [errors, setErrors] = React.useState<Array<string>>([]);
|
2022-03-21 11:09:01 -07:00
|
|
|
|
|
|
|
const isValid = email.length > 0 && EMAIL_REGEX.test(email);
|
|
|
|
|
|
|
|
const onChange = React.useCallback((event) => setEmail(event.target.value), []);
|
|
|
|
|
2022-06-09 12:22:19 -07:00
|
|
|
const handleSubmit: React.FormEventHandler = React.useCallback((event) => {
|
2022-03-21 11:09:01 -07:00
|
|
|
event.preventDefault();
|
|
|
|
setErrors([]);
|
|
|
|
|
|
|
|
submitEmailForVerification();
|
|
|
|
}, [email]);
|
|
|
|
|
|
|
|
const submitEmailForVerification = () => {
|
|
|
|
return dispatch(requestEmailVerification((email)))
|
|
|
|
.then(() => {
|
|
|
|
setStatus(Statuses.REQUESTED);
|
|
|
|
|
|
|
|
dispatch(
|
|
|
|
snackbar.success(
|
2022-11-11 15:07:02 -08:00
|
|
|
intl.formatMessage(messages.verificationSuccess),
|
2022-03-21 11:09:01 -07:00
|
|
|
),
|
|
|
|
);
|
|
|
|
})
|
2022-06-09 12:22:19 -07:00
|
|
|
.catch((error: AxiosError) => {
|
2022-08-16 06:48:58 -07:00
|
|
|
const errorMessage = (error.response?.data as any)?.error;
|
|
|
|
const isEmailTaken = errorMessage === 'email_taken';
|
2022-11-11 15:07:02 -08:00
|
|
|
let message = intl.formatMessage(messages.verificationFail);
|
2022-03-21 11:09:01 -07:00
|
|
|
|
2022-08-16 06:48:58 -07:00
|
|
|
if (isEmailTaken) {
|
2022-11-11 15:07:02 -08:00
|
|
|
message = intl.formatMessage(messages.verificationFailTakenAlert);
|
2022-08-16 06:48:58 -07:00
|
|
|
} else if (errorMessage) {
|
|
|
|
message = errorMessage;
|
|
|
|
}
|
2022-03-21 11:09:01 -07:00
|
|
|
|
|
|
|
if (isEmailTaken) {
|
2022-11-11 15:07:02 -08:00
|
|
|
setErrors([intl.formatMessage(messages.verificationFailTaken)]);
|
2022-03-21 11:09:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
dispatch(snackbar.error(message));
|
|
|
|
setStatus(Statuses.FAIL);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
if (status === Statuses.REQUESTED) {
|
|
|
|
return <EmailSent handleSubmit={handleSubmit} />;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
2022-07-22 10:30:16 -07:00
|
|
|
<div className='pb-4 sm:pb-10 mb-4 border-b border-gray-200 dark:border-gray-800 border-solid -mx-4 sm:-mx-10'>
|
2022-11-11 15:07:02 -08:00
|
|
|
<h1 className='text-center font-bold text-2xl'>
|
|
|
|
<FormattedMessage id='email_verification.header' defaultMessage='Enter your email address' />
|
|
|
|
</h1>
|
2022-03-21 11:09:01 -07:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className='sm:pt-10 sm:w-2/3 md:w-1/2 mx-auto'>
|
2022-04-04 08:54:00 -07:00
|
|
|
<Form onSubmit={handleSubmit}>
|
2022-11-26 05:09:28 -08:00
|
|
|
<FormGroup labelText={intl.formatMessage(messages.emailLabel)} errors={errors}>
|
2022-03-21 11:09:01 -07:00
|
|
|
<Input
|
|
|
|
type='email'
|
|
|
|
value={email}
|
|
|
|
name='email'
|
|
|
|
onChange={onChange}
|
|
|
|
placeholder='you@email.com'
|
|
|
|
required
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
|
|
|
|
<div className='text-center'>
|
2022-11-26 05:09:28 -08:00
|
|
|
<Button block theme='primary' type='submit' disabled={isLoading || !isValid}>
|
|
|
|
<FormattedMessage id='onboarding.next' defaultMessage='Next' />
|
|
|
|
</Button>
|
2022-03-21 11:09:01 -07:00
|
|
|
</div>
|
|
|
|
</Form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default EmailVerification;
|