Merged PR 19: login step update

login step update
master
Tudor Stanciu 2020-12-24 14:48:43 +00:00
commit 4286b55d57
9 changed files with 159 additions and 22 deletions

View File

@ -21,6 +21,8 @@
"Username": "Username",
"Password": "Password",
"Label": "Login",
"ChangeUser": "Change user",
"Logout": "Logout",
"IncorrectCredentials": "Incorrect credentials."
}
}

View File

@ -12,6 +12,8 @@
"Username": "Utilizator",
"Password": "Parolă",
"Label": "Autentificare",
"ChangeUser": "Schimbă utilizatorul",
"Logout": "Deconectare",
"IncorrectCredentials": "Credențiale incorecte."
}
}

View File

@ -7,7 +7,6 @@ import LoginContainer from "../../features/login/components/LoginContainer";
const useStyles = makeStyles(() => ({
app: {
textAlign: "center",
backgroundColor: "#282c34",
minHeight: "100vh",
display: "flex",
@ -23,7 +22,6 @@ const useStyles = makeStyles(() => ({
color: "white"
},
appLoginOnly: {
textAlign: "center",
backgroundColor: "#282c34",
minHeight: "100vh",
display: "flex",
@ -34,12 +32,12 @@ const useStyles = makeStyles(() => ({
const Main = () => {
const classes = useStyles();
const { tokenIsValid } = useAuthorizationToken();
const _tokenIsValid = tokenIsValid();
const { validateToken } = useAuthorizationToken();
const tokenIsValid = validateToken();
return (
<div className={_tokenIsValid ? classes.app : classes.appLoginOnly}>
{_tokenIsValid ? (
<div className={tokenIsValid ? classes.app : classes.appLoginOnly}>
{tokenIsValid ? (
<>
<ApplicationStepper />
<div className={classes.content}>

View File

@ -0,0 +1,80 @@
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardHeader from "@material-ui/core/CardHeader";
import CardContent from "@material-ui/core/CardContent";
import CardActions from "@material-ui/core/CardActions";
import { Avatar, Collapse, Tooltip, Divider } from "@material-ui/core";
import IconButton from "@material-ui/core/IconButton";
import { AccountBox, RotateLeft, ExitToApp } from "@material-ui/icons";
import LoginComponent from "./LoginComponent";
import { useTranslation } from "react-i18next";
const useStyles = makeStyles(theme => ({
root: {
minWidth: 350
},
onRight: {
marginLeft: "auto"
},
avatar: {
backgroundColor: theme.palette.primary.main
}
}));
const LoggedInComponent = ({ credentials, onChange, onLogin, onLogout }) => {
const classes = useStyles();
const { t } = useTranslation();
const [expanded, setExpanded] = React.useState(false);
const handleExpandLogin = () => {
setExpanded(!expanded);
};
return (
<Card className={classes.root}>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
<AccountBox />
</Avatar>
}
title={<strong>{t("Server.ActiveSession")}</strong>}
subheader="September 14, 2016"
/>
<CardActions disableSpacing>
<Tooltip title={t("Login.ChangeUser")}>
<IconButton
size="small"
className={classes.onRight}
onClick={handleExpandLogin}
aria-expanded={expanded}
aria-label="show login component"
>
<RotateLeft />
</IconButton>
</Tooltip>
<Tooltip title={t("Login.Logout")}>
<IconButton size="small" onClick={onLogout}>
<ExitToApp />
</IconButton>
</Tooltip>
</CardActions>
<Divider />
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent>
<LoginComponent
credentials={credentials}
onChange={onChange}
onLogin={onLogin}
/>
</CardContent>
</Collapse>
</Card>
);
};
LoggedInComponent.propTypes = {};
export default LoggedInComponent;

View File

@ -0,0 +1,25 @@
import React from "react";
import PropTypes from "prop-types";
import { Card } from "@material-ui/core";
import LoginComponent from "./LoginComponent";
const LoginCard = ({ credentials, onChange, onLogin }) => {
return (
<Card variant="outlined">
<LoginComponent
credentials={credentials}
onChange={onChange}
onLogin={onLogin}
/>
</Card>
);
};
LoginCard.propTypes = {
credentials: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
onLogin: PropTypes.func.isRequired
};
export default LoginCard;

View File

@ -5,7 +5,6 @@ import {
TextField,
InputAdornment,
Button,
Card,
CardActions,
CardContent
} from "@material-ui/core";
@ -17,6 +16,9 @@ const useStyles = makeStyles(theme => ({
field: {
margin: theme.spacing(1),
width: "300px"
},
onRight: {
marginLeft: "auto"
}
}));
@ -25,7 +27,7 @@ const LoginComponent = ({ credentials, onChange, onLogin }) => {
const { t } = useTranslation();
return (
<Card variant="outlined">
<>
<CardContent>
<TextField
className={classes.field}
@ -51,11 +53,16 @@ const LoginComponent = ({ credentials, onChange, onLogin }) => {
/>
</CardContent>
<CardActions>
<Button variant="contained" color="primary" onClick={onLogin}>
<Button
className={classes.onRight}
variant="contained"
color="primary"
onClick={onLogin}
>
{t("Login.Label")}
</Button>
</CardActions>
</Card>
</>
);
};

View File

@ -1,18 +1,20 @@
import React, { useContext } from "react";
import LoginComponent from "./LoginComponent";
import { authenticate } from "../../../utils/identity";
import LoginCard from "./LoginCard";
import { authenticate, invalidate } from "../../../utils/identity";
import {
ApplicationStateContext,
ApplicationDispatchContext
} from "../../../state/ApplicationContexts";
import { useToast } from "../../../hooks";
import { useToast, useAuthorizationToken } from "../../../hooks";
import { useTranslation } from "react-i18next";
import LoggedInComponent from "./LoggedInComponent";
const LoginContainer = () => {
const state = useContext(ApplicationStateContext);
const dispatchActions = useContext(ApplicationDispatchContext);
const { error } = useToast();
const { t } = useTranslation();
const { tokenIsValid } = useAuthorizationToken();
const handleChange = prop => event => {
dispatchActions.onCredentialsChange(prop, event.target.value);
@ -33,13 +35,26 @@ const LoginContainer = () => {
}
};
const handleLogout = () => {
invalidate();
};
return (
<>
<LoginComponent
{tokenIsValid ? (
<LoggedInComponent
credentials={state.credentials}
onChange={handleChange}
onLogin={handleLogin}
onLogout={handleLogout}
/>
) : (
<LoginCard
credentials={state.credentials}
onChange={handleChange}
onLogin={handleLogin}
/>
)}
</>
);
};

View File

@ -5,7 +5,7 @@ export const useAuthorizationToken = () => {
const state = useContext(ApplicationStateContext);
const getToken = () => state.security.authorization.token;
const tokenIsValid = () => {
const validateToken = () => {
const token = getToken();
if (!token) {
return false;
@ -15,5 +15,6 @@ export const useAuthorizationToken = () => {
return valid;
};
return { getToken, tokenIsValid };
const tokenIsValid = validateToken();
return { getToken, validateToken, tokenIsValid };
};

View File

@ -1,5 +1,5 @@
import { request } from "./axios";
import { setItem } from "./localStorage";
import { setItem, getItem, removeItem } from "./localStorage";
const storageKeys = {
TOKEN: "AUTHORIZATION_TOKEN"
@ -22,4 +22,11 @@ const authenticate = async (username, password) => {
return response;
};
export { storageKeys, authenticate };
const invalidate = () => {
const token = getItem(storageKeys.TOKEN);
if (token) {
removeItem(storageKeys.TOKEN);
}
};
export { storageKeys, authenticate, invalidate };