Finished login component

Did the following:
 - Extract front-end from component;
 - Added localStorage for remembering API details and access key;
 - Added routing to login component;

Todo:
 - Remove getApi*FromDTO;
 - Create ProtectedRoute to prevent unauthorized entry to /dashboard;
This commit is contained in:
2020-02-19 00:48:30 +01:00
parent 60079a1417
commit ae7d63db35
9 changed files with 254 additions and 62 deletions
+4 -8
View File
@@ -6,18 +6,14 @@ import Login from '../LoginComponent/Login';
import Dashboard from '../DashboardComponent/Dashboard';
export default class App extends React.Component {
componentDidMount() {
if((localStorage.getItem("APILink") !== undefined || localStorage.getItem("APILink") !== '') &&
(localStorage.getItem("AccessToken") !== undefined || localStorage.getItem("AccessToken") !== '')) {
return <Redirect to="/dashboard" />
};
}
render() {
return (
<Switch>
<Route exact path="/" component={Login} />
<Route path="/dashboard" component={Dashboard} />
<Route exact path="/"
component={Login} />
<Route path="/dashboard"
component={Dashboard} />
<Redirect to="/" />
</Switch>
);
+52 -35
View File
@@ -1,44 +1,61 @@
import React from 'react';
import { Card, Button, InputGroup, FormControl } from 'react-bootstrap';
import LoginView from '../../Views/LoginView';
import API_DTO from '../../DTOs/api.dto';
export default class Login extends React.Component<{
history: any
}, {
dto: any
}> {
export default class Login extends React.Component {
// eslint-disable-next-line
constructor(props: any) {
super(props);
this.persistApiLink = this.persistApiLink.bind(this);
this.persistAccessToken = this.persistAccessToken.bind(this);
this.verifyLogin = this.verifyLogin.bind(this);
this.getApiLinkFromDTO = this.getApiLinkFromDTO.bind(this);
this.getApiTokenFromDTO = this.getApiTokenFromDTO.bind(this);
}
render () {
return (
<div className="LoginComponent">
<Card className="text-center">
<Card.Body>
<Card.Title>Please login to see the dashboard.</Card.Title>
<Card.Text>
Please fill in the following items: <br /><br />
<InputGroup className="mb-3">
<InputGroup.Prepend>
<InputGroup.Text id="inputGroup-sizing-default">API url</InputGroup.Text>
</InputGroup.Prepend>
<FormControl
aria-label="Default"
aria-describedby="inputGroup-sizing-default"
/>
</InputGroup>
<InputGroup className="mb-3">
<InputGroup.Prepend>
<InputGroup.Text id="inputGroup-sizing-default">API token</InputGroup.Text>
</InputGroup.Prepend>
<FormControl
aria-label="Default"
aria-describedby="inputGroup-sizing-default"
/>
</InputGroup>
</Card.Text>
<Button variant="primary">Login</Button>
</Card.Body>
<Card.Footer className="text-muted">Your last login was X-X-X @ XX:XX</Card.Footer>
</Card>
</div>
);
componentDidMount() {
const DTO = new API_DTO();
DTO.setApiLink(localStorage.getItem("APILink"));
DTO.setApiToken(localStorage.getItem("AccessToken"));
this.setState({ dto: DTO });
}
verifyLogin() {
console.log("API Link: " + this.state.dto.getApiLink());
console.log("API Token: " + this.state.dto.getApiToken());
localStorage.setItem("lastLoggedIn", new Date().toUTCString());
// eslint-disable-next-line
this.props.history.push('/dashboard');
};
getApiLinkFromDTO(): string {
return this.state.dto.getApiLink();
}
getApiTokenFromDTO(): string {
return this.state.dto.getApiToken();
}
persistApiLink(e: any): void {
this.state.dto.setApiLink(e.target.value);
}
persistAccessToken(e: any): void {
this.state.dto.setApiToken(e.target.value);
}
render() {
return (<LoginView
persistApiLink={this.persistApiLink}
persistAccessToken={this.persistAccessToken}
verifyLogin={this.verifyLogin}
getApiLinkFromDTO={this.getApiLinkFromDTO}
getApiTokenFromDTO={this.getApiTokenFromDTO}
/>);
}
}
+29
View File
@@ -0,0 +1,29 @@
export default class API_DTO {
API_Link: string;
API_Token: string;
constructor() {
this.API_Link = "";
this.API_Token = "";
}
setApiLink(_api_link: string | null): void {
if (_api_link === null) _api_link = "";
this.API_Link = _api_link;
localStorage.setItem("APILink", this.API_Link);
}
setApiToken(_api_token: string | null): void {
if (_api_token === null) _api_token = "";
this.API_Token = _api_token;
localStorage.setItem("AccessToken", this.API_Token);
}
getApiLink() {
return this.API_Link;
}
getApiToken() {
return this.API_Token;
}
}
+44
View File
@@ -0,0 +1,44 @@
import React from 'react';
import { Card, Button, FormControl } from 'react-bootstrap';
export default class LoginView extends React.Component<{
persistApiLink: any,
persistAccessToken: any,
verifyLogin: any,
getApiLinkFromDTO: any,
getApiTokenFromDTO: any
}> {
render () {
return (
<div className="LoginComponent">
<Card className="text-center">
<Card.Body>
<Card.Title>Please login to see the dashboard.</Card.Title>
<Card.Text>
Please fill in the following items: <br /><br />
<FormControl aria-label="Default"
aria-describedby="inputGroup-sizing-default"
type="text"
placeholder="API Link"
defaultValue={localStorage.getItem("APILink") || ""}
onChange={(e: any) => this.props.persistApiLink(e)}
/>
<FormControl
aria-label="Default"
aria-describedby="inputGroup-sizing-default"
type="text"
placeholder="API Token"
defaultValue={localStorage.getItem("AccessToken") || ""}
onChange={(e: any) => this.props.persistAccessToken(e)}
/>
</Card.Text>
<Button variant="primary" onClick={this.props.verifyLogin}>Login </Button>
</Card.Body>
{ localStorage.getItem("lastLoggedIn") !== null &&
<Card.Footer className="text-muted">Your last login was { localStorage.getItem("lastLoggedIn") }</Card.Footer>
}
</Card>
</div>
);
}
}
+5 -1
View File
@@ -4,4 +4,8 @@ import './index.css';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './Components/AppComponent/App';
ReactDOM.render(<Router><App /></Router>, document.getElementById('App'));
ReactDOM.render(
<Router >
<App />
</Router>,
document.getElementById('App'));