pslockout/webclient/src/App.js

238 lines
6.0 KiB
JavaScript
Raw Normal View History

import React, { Component } from 'react';
import Categories from './Categories';
import Category from './Category';
2018-02-03 06:41:30 +00:00
import Tool from './Tool';
2018-11-13 09:45:16 +00:00
import { Button, Confirm, Container, Dimmer, Form, Header, Icon, Item, Label, Loader, Menu, Message, Segment, Input } from 'semantic-ui-react';
import { Link, Route } from 'react-router-dom';
2018-02-04 02:59:39 +00:00
import io from 'socket.io-client';
// Move to env var
2018-11-13 09:45:16 +00:00
const SOCKET_SERVER_URL = 'http://localhost:8080';
const AUTH_SERVER_URL = 'http://localhost:8000';
class App extends Component {
2018-02-03 08:48:49 +00:00
constructor() {
super();
2018-11-13 09:45:16 +00:00
this.socket = io(SOCKET_SERVER_URL);
this.storage = typeof localStorage !== 'undefined';
let token = this.storage ? localStorage.getItem('token') : null;
2018-02-04 02:59:39 +00:00
2018-02-03 08:48:49 +00:00
this.state = {
2018-11-13 09:45:16 +00:00
login: {token: token, error: null, username: '', password: '', confirmLogout: false},
2018-02-04 00:20:58 +00:00
user: null,
2018-02-03 08:48:49 +00:00
toolData: null,
2018-02-04 02:59:39 +00:00
toolStatus: null,
connected: false,
2018-11-13 09:45:16 +00:00
network: true,
2018-02-03 08:48:49 +00:00
};
}
2018-11-13 09:45:16 +00:00
getUser = () => {
fetch(AUTH_SERVER_URL + '/user/', {
headers: {'Authorization': 'Token ' + this.state.login.token},
})
.then(response => {
if (response.ok) {
response.json().then(data => this.setState({ user: data[0] }));
} else {
this.handleLogout();
}
})
.catch(error => {
console.log(error)
});
}
2018-02-03 08:48:49 +00:00
componentDidMount() {
2018-11-13 09:45:16 +00:00
fetch(AUTH_SERVER_URL + '/tooldata/')
2018-02-03 08:48:49 +00:00
.then(response => response.json())
2018-11-13 09:45:16 +00:00
.then(data => this.setState({ toolData: data }))
.catch(error => {
console.log(error)
this.setState({network: false});
});
if (this.state.login.token) this.getUser();
2018-02-04 02:59:39 +00:00
this.socket.on('toolStatus', toolStatus =>
this.setState({ toolStatus: toolStatus })
);
2018-11-13 09:45:16 +00:00
this.socket.on('connect', () =>
2018-02-04 02:59:39 +00:00
this.setState({ connected: true })
);
2018-11-13 09:45:16 +00:00
this.socket.on('disconnect', () => {
this.setState({ toolStatus: null, connected: false });
});
2018-02-04 02:59:39 +00:00
}
componentWillUnmount() {
this.socket.removeAllListeners();
}
requestInterlock = change => {
this.socket.emit('requestInterlock', {
2018-11-13 09:45:16 +00:00
token: this.state.login.token,
2018-02-04 02:59:39 +00:00
change: change,
});
2018-02-03 08:48:49 +00:00
}
2018-11-13 09:45:16 +00:00
handleChange = event => {
const name = event.target.name;
const value = event.target.value;
this.setState({
login: {...this.state.login, [name]: value}
});
}
handleSubmit = () => {
const login = this.state.login;
fetch(AUTH_SERVER_URL + '/login/', {
method: 'POST',
headers: {'Content-Type': 'application/json; charset=utf-8'},
body: JSON.stringify({'username': login.username, 'password': login.password})
})
.then(response => {
if (response.ok) {
response.json().then(data => {
this.setState({login: {...login, ...data, error: false}});
if (this.storage) localStorage.setItem('token', data.token);
this.getUser();
});
} else {
this.setState({login: {...login, error: true}});
}
})
.catch(error => {
console.log(error)
this.setState({network: false});
});
}
confirmLogout = () => {
if (this.state.login.token) {
this.setState({
login: {...this.state.login, confirmLogout: true}
});
}
}
cancelLogout = () => {
this.setState({
login: {...this.state.login, confirmLogout: false}
});
}
handleLogout = () => {
this.setState({
login: {...this.state.login, token: null, confirmLogout: false}
});
localStorage.removeItem('token');
}
handleRefresh = () => {
window.location.reload();
}
render() {
2018-11-13 09:45:16 +00:00
const login = this.state.login;
const user = this.state.user;
2018-02-03 08:48:49 +00:00
const toolData = this.state.toolData;
2018-02-04 02:59:39 +00:00
const toolStatus = this.state.toolStatus;
const connected = this.state.connected;
2018-11-13 09:45:16 +00:00
const network = this.state.network;
2018-02-03 08:48:49 +00:00
return (
2018-11-13 09:45:16 +00:00
network ?
<div>
<Menu fixed='top' borderless inverted>
<Menu.Item onClick={this.confirmLogout}>
<Icon name='user close' size='big' />
2018-02-03 06:41:30 +00:00
</Menu.Item>
2018-11-13 09:45:16 +00:00
<Menu.Item as={Link} to='/'>
<Icon name='home' size='big' />
</Menu.Item>
<Menu.Item>
<Icon name='circle' color={connected && toolStatus ? 'green' : 'red'} />
{connected && toolStatus ? 'Connected' : 'Disconnected'}
</Menu.Item>
</Menu>
<div style={{height: '70px', display: 'inline-block'}} />
<Confirm
open={login.confirmLogout}
header='Logout'
onCancel={this.cancelLogout}
onConfirm={this.handleLogout}
/>
{login.token ?
<div>
{toolData && user ?
<div>
<Route exact path='/' render={props =>
<Categories {...props} data={toolData} />
} />
<Route exact path='/:category' render={props =>
<Category {...props} data={toolData} user={user} />
} />
<Route exact path='/:category/:slug' render={props =>
<Tool {...props}
data={toolData}
user={user}
toolStatus={toolStatus}
requestInterlock={this.requestInterlock}
/>
} />
</div>
:
<Dimmer active>
<Loader>Loading</Loader>
</Dimmer>
}
</div>
:
<Container text>
<Form size='large' onSubmit={this.handleSubmit}>
{login.error ?
<Message visible error header='Invalid username / password!' />
:
<Message visible warning header='Please log in to access the tools!' />
}
<Form.Field>
<label>Protospace Username</label>
<input name='username' placeholder='Username' value={login.username} onChange={this.handleChange} />
</Form.Field>
<Form.Field>
<label>Password</label>
<input name='password' type='password' value={login.password} onChange={this.handleChange} />
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
</Container>
}
</div>
:
<Dimmer active>
<Header inverted icon>
<Icon color='red' name='wifi' />
Please connect to the "Protospace" wifi
</Header>
<br />
<Button size='big' inverted icon labelPosition='left' onClick={this.handleRefresh}>
<Icon name='refresh' />
Refresh
</Button>
</Dimmer>
);
}
}
export default App;