frontend/app/LoginComponent.tsx (82 lines of code) (raw):
import React, {useState, useEffect} from "react";
import {Button, Grid, makeStyles, Paper, Typography} from "@material-ui/core";
import clsx from "clsx";
import {ChevronRight} from "@material-ui/icons";
const useStyles = makeStyles((theme)=>({
actionPanel: {
width: "40%",
maxWidth: "1000px",
},
panelContent: {
padding: "1em",
},
bannerText: {
textAlign: "center",
},
separated: {
marginBottom: "1em",
},
loginBox: {
marginLeft: "auto",
marginRight: "auto",
marginTop: "10em",
},
errorText: {
marginLeft: "1em",
marginRight: "1em",
},
}));
function generateCodeChallenge() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
const str = array.reduce<string>((acc:string, x) => acc + x.toString(16).padStart(2, '0'), "");
sessionStorage.setItem("cx", str);
return str;
}
const LoginComponent = ()=>{
const classes = useStyles();
const [lastError, setLastError] = useState<string|undefined>(undefined);
const doLogin = ()=>window.location.href = "/login?code_challenge=" + generateCodeChallenge();
useEffect(() => {
const dataToTest = new URLSearchParams(window.location.search).get("error");
if (dataToTest) {
setLastError(dataToTest)
}
}, []);
return (
<Paper className={clsx(classes.actionPanel, classes.loginBox)}>
<Grid container direction="column" alignItems="center" spacing={3}>
<Grid item>
<Typography variant="h6" className={classes.bannerText}>
You need to log in to access the Multimedia production system, using
your normal Mac login credentials.
</Typography>
</Grid>
<Grid item>
<Button
style={{ marginLeft: "auto", marginRight: "auto" }}
variant="contained"
endIcon={<ChevronRight />}
onClick={doLogin}
>
Log me in
</Button>
</Grid>
{lastError ?
<>
<Grid item>
<Typography>
An error occurred when attempting to log you in.
</Typography>
</Grid>
<Grid item className={classes.errorText}>
<Typography>
{lastError}
</Typography>
</Grid>
</> : null}
</Grid>
</Paper>
);
}
export default LoginComponent;