all repos — caroster @ 406456e1af7399c4bf12340f443334a004070db9

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