169 lines
4.9 KiB
TypeScript
169 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);
|
|
history.replace("/");
|
|
} 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();
|
|
// fixme: logging?????
|
|
login({
|
|
variables: { email: email, password: password },
|
|
}).catch((error) => console.log(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>
|
|
);
|
|
}
|