all repos — caroster @ e2d2a77f78f52331a111b5e38389de808e95c571

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

frontend/containers/SignInForm/index.tsx (view raw)

  1import {useState, useMemo} from 'react';
  2import NextLink from 'next/link';
  3import TextField from '@mui/material/TextField';
  4import Button from '@mui/material/Button';
  5import Typography from '@mui/material/Typography';
  6import CardContent from '@mui/material/CardContent';
  7import FormHelperText from '@mui/material/FormHelperText';
  8import CardActions from '@mui/material/CardActions';
  9import Divider from '@mui/material/Divider';
 10import Box from '@mui/material/Box';
 11import {useTheme} from '@mui/material/styles';
 12import {useTranslation} from 'react-i18next';
 13import {signIn} from 'next-auth/react';
 14import useAddToEvents from '../../hooks/useAddToEvents';
 15import LoginGoogle from '../LoginGoogle';
 16import {useRouter} from 'next/router';
 17
 18interface Props {
 19  error?: string;
 20}
 21
 22const errorsMap = {
 23  CredentialsSignin: 'signin.errors.CredentialsSignin',
 24  EmailNotConfirmed: 'signin.errors.EmailNotConfirmed',
 25};
 26
 27const SignIn = (props: Props) => {
 28  const {error} = props;
 29  const {t} = useTranslation();
 30  const router = useRouter();
 31
 32  const theme = useTheme();
 33  const [email, setEmail] = useState('');
 34  const [password, setPassword] = useState('');
 35  const {saveStoredEvents} = useAddToEvents();
 36
 37  const canSubmit = useMemo(
 38    () => [email, password].filter(s => s.length < 4).length === 0,
 39    [email, password]
 40  );
 41
 42  const onSubmit = async e => {
 43    e.preventDefault?.();
 44    try {
 45      await signIn('credentials', {
 46        email,
 47        password,
 48        callbackUrl: (router.query?.redirectPath as string) || '/dashboard',
 49      });
 50      saveStoredEvents();
 51    } catch (error) {
 52      console.error(error);
 53    }
 54
 55    return false;
 56  };
 57
 58  const spaceAround = {
 59    width: '100%',
 60    textAlign: 'center',
 61    margin: theme.spacing(2, 0),
 62  };
 63
 64  return (
 65    <form onSubmit={onSubmit}>
 66      <CardContent
 67        sx={{
 68          display: 'flex',
 69          flexDirection: 'column',
 70          px: 2,
 71        }}
 72      >
 73        <Typography variant="h6" align="center">
 74          {t('signin.title')}
 75        </Typography>
 76        {error && (
 77          <FormHelperText error sx={{textAlign: 'center'}}>
 78            {t(errorsMap[error])}
 79          </FormHelperText>
 80        )}
 81        <Box
 82          sx={{
 83            display: 'flex',
 84            flexDirection: 'column',
 85          }}
 86        >
 87          <TextField
 88            label={t('signin.email')}
 89            fullWidth
 90            required={true}
 91            InputLabelProps={{required: false}}
 92            margin="dense"
 93            value={email}
 94            onChange={({target: {value = ''}}) => setEmail(value)}
 95            name="email"
 96            type="email"
 97            error={!!error}
 98          />
 99          <TextField
100            label={t('signin.password')}
101            fullWidth
102            InputLabelProps={{required: false}}
103            required={true}
104            margin="dense"
105            value={password}
106            onChange={({target: {value = ''}}) => setPassword(value)}
107            id="SignInEmail"
108            name="password"
109            type="password"
110            error={!!error}
111          />
112        </Box>
113
114        <Box sx={spaceAround}>
115          <NextLink href="/auth/lost-password" passHref>
116            <Typography
117              align="center"
118              variant="body2"
119              color="primary"
120              sx={{
121                textDecoration: 'underline',
122                textDecorationColor: 'primary',
123              }}
124            >
125              {t('lost_password.message')}
126            </Typography>
127          </NextLink>
128        </Box>
129        <Box
130          sx={{
131            display: 'flex',
132            flexDirection: 'column',
133            alignItems: 'center',
134            width: '100%',
135            pb: 1,
136          }}
137        >
138          <Button
139            color="primary"
140            variant="contained"
141            fullWidth
142            type="submit"
143            disabled={!canSubmit}
144            aria-disabled={!canSubmit}
145          >
146            {t('signin.login')}
147          </Button>
148          <Box sx={spaceAround}>
149            <Typography>{t('signin.or')}</Typography>
150          </Box>
151          <LoginGoogle />
152        </Box>
153      </CardContent>
154      <Divider />
155      <CardActions
156        sx={{
157          flexDirection: 'column',
158          justifyContent: 'center',
159          marginBottom: theme.spacing(2),
160          textAlign: 'center',
161          px: 2,
162        }}
163      >
164        <Typography align="center" variant="body2" sx={{pt: 2}}>
165          {t('signin.no_account')}
166        </Typography>
167        <NextLink href="/auth/register" passHref>
168          <Button size="small">{t('signin.register')}</Button>
169        </NextLink>
170      </CardActions>
171    </form>
172  );
173};
174
175export default SignIn;