all repos — caroster @ dd61269df1312105abdf0be391ac513f9f0b27e5

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