kandimat/redaktions-app/src/components/SignIn.tsx
Christoph Lienhard 9944f8a38b
#20 add drawer menu
Also:
* Extract User Menu into own Component
2021-02-07 23:06:58 +01:00

168 lines
4.9 KiB
TypeScript

import React, { useState } from "react";
import Avatar from "@material-ui/core/Avatar";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Checkbox from "@material-ui/core/Checkbox";
import Grid from "@material-ui/core/Grid";
import Box from "@material-ui/core/Box";
import { Alert } from "@material-ui/lab";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import { Link, useHistory, useLocation } from "react-router-dom";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import Container from "@material-ui/core/Container";
import { useMutation } from "@apollo/client";
import ButtonWithSpinner from "./ButtonWithSpinner";
import { Copyright } from "./Copyright";
import {
LOGIN,
LoginResponse,
LoginVariables,
} from "../backend/mutations/login";
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center",
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main,
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
},
alert: {
margin: theme.spacing(1),
},
}));
export default function SignIn(): React.ReactElement {
const history = useHistory();
const queryParams = new URLSearchParams(useLocation().search);
const classes = useStyles();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [login, { loading }] = useMutation<LoginResponse, LoginVariables>(
LOGIN,
{
onCompleted(data) {
if (data.authenticate.jwtToken) {
localStorage.setItem("token", data.authenticate.jwtToken);
window.location.reload();
} else {
setError("Wrong username or password.");
}
},
onError(e) {
setError(`Error while trying to log in: ${e.message}`);
},
}
);
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form
className={classes.form}
noValidate
onSubmit={(event) => {
event.preventDefault();
login({
variables: { email: email, password: password },
}).catch((error) => setError(error));
}}
>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
value={email}
onChange={(e) => {
setEmail(e.target.value);
setError("");
}}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
value={password}
autoComplete="current-password"
onChange={(e) => {
setPassword(e.target.value);
setError("");
}}
/>
<FormControlLabel
disabled={true}
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<ButtonWithSpinner loading={loading} type="submit" fullWidth>
Sign In
</ButtonWithSpinner>
<Grid container>
<Grid item xs>
{/* todo: see issue #17*/}
{/*<Link to="/restore-password" aria-disabled={true}>*/}
{/* Forgot password?*/}
{/*</Link>*/}
</Grid>
<Grid item>
<Link to="/signup">{"Don't have an account? Sign Up"}</Link>
</Grid>
</Grid>
{queryParams.get("recent-sign-up-success") ? (
<Alert
className={classes.alert}
severity="success"
onClose={() => history.push("/login")}
>
Sign-Up was successful. Log in to continue
</Alert>
) : null}
{error ? (
<Alert
className={classes.alert}
severity="error"
onClose={() => setError("")}
>
{error}
</Alert>
) : null}
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
);
}