all repos — caroster @ 2b810d8047851a8ab095f96c9547adadc104ff3e

[Octree] Group carpool to your event https://caroster.io

frontend/containers/LostPassword/index.js (view raw)

  1import {useCallback, useState, useEffect} from 'react';
  2import { styled } from '@mui/material/styles';
  3import {useTranslation} from 'react-i18next';
  4import router from 'next/router';
  5import TextField from '@mui/material/TextField';
  6import Button from '@mui/material/Button';
  7import CardContent from '@mui/material/CardContent';
  8import Card from '@mui/material/Card';
  9import CircularProgress from '@mui/material/CircularProgress';
 10import CardActions from '@mui/material/CardActions';
 11import Link from '@mui/material/Link';
 12import LostPasswordSuccess from './Success';
 13import useToastStore from '../../stores/useToastStore';
 14import useProfile from '../../hooks/useProfile';
 15import {useForgotPasswordMutation} from '../../generated/graphql';
 16
 17const PREFIX = 'LostPassword';
 18
 19const classes = {
 20  loader: `${PREFIX}-loader`,
 21  actions: `${PREFIX}-actions`
 22};
 23
 24const Root = styled('form')((
 25  {
 26    theme
 27  }
 28) => ({
 29  [`& .${classes.loader}`]: {
 30    marginLeft: theme.spacing(4),
 31  },
 32
 33  [`& .${classes.actions}`]: {
 34    marginTop: theme.spacing(2),
 35    justifyContent: 'flex-end',
 36  }
 37}));
 38
 39const LostPassword = () => {
 40  const {t} = useTranslation();
 41
 42  const addToast = useToastStore(s => s.addToast);
 43  const {profile} = useProfile();
 44  const [sendForgotPassword, {loading}] = useForgotPasswordMutation();
 45  const [isSent, setIsSent] = useState(false);
 46  const [error, setError] = useState('');
 47  const [email, setEmail] = useState('');
 48  const canSubmit = email.length > 4;
 49
 50  useEffect(() => {
 51    if (profile?.confirmed) router.replace('/confirm');
 52    else if (profile) router.replace('/dashboard');
 53  }, [profile]);
 54
 55  const onSubmit = useCallback(
 56    async e => {
 57      if (e.preventDefault) e.preventDefault();
 58
 59      try {
 60        await sendForgotPassword({variables: {email}});
 61        setIsSent(true);
 62      } catch (error) {
 63        if (error.message === 'Bad Request') {
 64          addToast(t('lost_password.error'));
 65          setError(t('lost_password.error'));
 66        } else {
 67          addToast(t('generic.errors.unknown'));
 68        }
 69      }
 70      return false;
 71    },
 72    [sendForgotPassword, email, addToast, t]
 73  );
 74
 75  if (!loading && isSent) return <LostPasswordSuccess email={email} />;
 76
 77  return (
 78    <Root onSubmit={onSubmit}>
 79      <Card>
 80        <CardContent>
 81          <TextField
 82            label={t('lost_password.email')}
 83            fullWidth
 84            required={true}
 85            margin="dense"
 86            value={email}
 87            onChange={({target: {value = ''}}) => setEmail(value)}
 88            id="LostPasswordEmail"
 89            name="email"
 90            type="email"
 91            error={!!error}
 92            helperText={
 93              error && (
 94                <>
 95                  {error}&nbsp;
 96                  <Link href="/auth/register">
 97                    {t('lost_password.actions.register')}
 98                  </Link>
 99                </>
100              )
101            }
102          />
103        </CardContent>
104        <CardActions className={classes.actions}>
105          <Button id="LostPasswordRegister" href="/auth/login">
106            {t('lost_password.actions.cancel')}
107          </Button>
108
109          <Button
110            color="primary"
111            variant="contained"
112            type="submit"
113            disabled={!canSubmit}
114            aria-disabled={!canSubmit}
115            id="LostPasswordSubmit"
116          >
117            {t('lost_password.actions.send')}
118            {loading && (
119              <CircularProgress
120                className={classes.loader}
121                color="primary"
122                size={20}
123              />
124            )}
125          </Button>
126        </CardActions>
127      </Card>
128    </Root>
129  );
130};
131
132export default LostPassword;