aboutsummaryrefslogtreecommitdiff
path: root/modern
diff options
context:
space:
mode:
authorditoaugusta <dt_ap@ymail.com>2020-03-27 17:39:49 +0700
committerditoaugusta <dt_ap@ymail.com>2020-03-27 17:39:49 +0700
commit8bef4f04c2b0b203450fe5753b6109a0b0d04e82 (patch)
treea7bed472e98fa52f1887d060a841d87bd3f0fd6a /modern
parentb10607f96ad72f5f971fbd867eeeeb86380f79cb (diff)
downloadtrackermap-web-8bef4f04c2b0b203450fe5753b6109a0b0d04e82.tar.gz
trackermap-web-8bef4f04c2b0b203450fe5753b6109a0b0d04e82.tar.bz2
trackermap-web-8bef4f04c2b0b203450fe5753b6109a0b0d04e82.zip
exp: hooks (1)
Diffstat (limited to 'modern')
-rw-r--r--modern/src/DeviceList.js46
-rw-r--r--modern/src/LoginPage.js166
-rw-r--r--modern/src/MainPage.js82
-rw-r--r--modern/src/MainToolbar.js147
4 files changed, 191 insertions, 250 deletions
diff --git a/modern/src/DeviceList.js b/modern/src/DeviceList.js
index 235ba229..8d855a76 100644
--- a/modern/src/DeviceList.js
+++ b/modern/src/DeviceList.js
@@ -1,30 +1,26 @@
-import React, { Component, Fragment } from 'react';
-import { connect } from 'react-redux';
+import React, { Fragment } from 'react';
+import Avatar from '@material-ui/core/Avatar';
+import Divider from '@material-ui/core/Divider';
+import IconButton from '@material-ui/core/IconButton';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
+import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
-import Avatar from '@material-ui/core/Avatar';
import LocationOnIcon from '@material-ui/icons/LocationOn';
-import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
-import IconButton from '@material-ui/core/IconButton';
import MoreVertIcon from '@material-ui/icons/MoreVert';
-import Divider from '@material-ui/core/Divider';
-import { devicesActions } from './store';
-const mapStateToProps = state => ({
- devices: Object.values(state.devices.items)
-});
+import { useDispatch, useSelector } from 'react-redux';
+import { devicesActions } from './store';
-class DeviceList extends Component {
- handleClick(device) {
- this.props.dispatch(devicesActions.select(device));
- }
+const DeviceList = () => {
+ const devices = useSelector(state => Object.values(state.devices.items));
+ const dispatch = useDispatch();
- render() {
- const devices = this.props.devices.map((device, index, list) =>
- <Fragment key={device.id.toString()}>
- <ListItem button onClick={(e) => this.handleClick(device)}>
+ return (<List>
+ {devices.map((device, index, list) => (
+ <Fragment key={device.id}>
+ <ListItem button key={device.id} onClick={() => dispatch(devicesActions.select(device))}>
<ListItemAvatar>
<Avatar>
<LocationOnIcon />
@@ -39,14 +35,10 @@ class DeviceList extends Component {
</ListItem>
{index < list.length - 1 ? <Divider /> : null}
</Fragment>
- );
-
- return (
- <List>
- {devices}
- </List>
- );
- }
+ ))
+ }
+ </List>);
}
-export default connect(mapStateToProps)(DeviceList);
+export default DeviceList;
+
diff --git a/modern/src/LoginPage.js b/modern/src/LoginPage.js
index c094fa3b..1f0b950b 100644
--- a/modern/src/LoginPage.js
+++ b/modern/src/LoginPage.js
@@ -1,13 +1,14 @@
-import React, { Component } from 'react';
+import React, { useState } from 'react';
+import { useHistory } from 'react-router-dom';
import Button from '@material-ui/core/Button';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import Paper from '@material-ui/core/Paper';
-import withStyles from '@material-ui/core/styles/withStyles';
+import { makeStyles } from '@material-ui/core';
-const styles = theme => ({
+const useStyles = makeStyles(theme => ({
root: {
width: 'auto',
display: 'block', // Fix IE11 issue.
@@ -38,111 +39,94 @@ const styles = theme => ({
flex: '1 1 0',
margin: `${theme.spacing(3)}px ${theme.spacing(1)}px 0`
},
-});
+}));
-class LoginPage extends Component {
- constructor(props) {
- super(props);
- this.state = {
- filled: false,
- loading: false,
- failed: false,
- email: "",
- password: ""
- };
- this.handleChange = this.handleChange.bind(this);
- this.handleRegister = this.handleRegister.bind(this);
- this.handleLogin = this.handleLogin.bind(this);
+const LoginPage = () => {
+ const [filled, setFilled] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [failed, setFailed] = useState(false);
+ const [email, setEmail] = useState('');
+ const [password, setPassword] = useState('');
+
+ const classes = useStyles();
+ const history = useHistory();
+
+ const handleEmailChange = (event) => {
+ setEmail(event.target.value);
}
- handleChange(event) {
- this.setState({
- [event.target.id]: event.target.value
- });
+ const handlePasswordChange = (event) => {
+ setPassword(event.target.value);
}
- handleRegister() {
- // TODO implement registration
+ const handleRegister = () => {
+ // TODO: Implement registration
}
- handleLogin(event) {
+ const handleLogin = (event) => {
event.preventDefault();
- const { email, password } = this.state;
- fetch("/api/session", {
- method: "POST",
- body: new URLSearchParams(`email=${email}&password=${password}`)
- }).then(response => {
+ fetch('/api/session', { method: 'POST', body: new URLSearchParams(`email=${email}&password=${password}`) }).then(response => {
if (response.ok) {
- this.props.history.push('/'); // TODO avoid calling sessions twice
+ history.push('/'); // TODO: Avoid calling sessions twice
} else {
- this.setState({
- failed: true,
- password: ""
- });
+ setFailed(true);
+ setPassword('');
}
});
}
- render() {
- const { classes } = this.props;
- const { failed, email, password } = this.state;
- return (
- <main className={classes.root}>
- <Paper className={classes.paper}>
-
- <img className={classes.logo} src="/logo.svg" alt="Traccar" />
-
- <form onSubmit={this.handleLogin}>
-
- <FormControl margin="normal" required fullWidth error={failed}>
- <InputLabel htmlFor="email">Email</InputLabel>
- <Input
- id="email"
- value={email}
- autoComplete="email"
- autoFocus
- onChange={this.handleChange} />
- { failed && <FormHelperText>Invalid username or password</FormHelperText> }
- </FormControl>
-
- <FormControl margin="normal" required fullWidth>
- <InputLabel htmlFor="password">Password</InputLabel>
- <Input
- id="password"
- type="password"
- value={password}
- autoComplete="current-password"
- onChange={this.handleChange} />
- </FormControl>
-
- <div className={classes.buttons}>
-
- <Button
- type="button"
- variant="contained"
- disabled
- className={classes.button}
- onClick={this.handleRegister}>
- Register
+ return (
+ <main className={classes.root}>
+ <Paper className={classes.paper}>
+ <img className={classes.logo} src="/logo.svg" alt="Traccar" />
+ <form onSubmit={handleLogin}>
+ <FormControl margin="normal" required fullWidth error={failed}>
+ <InputLabel htmlFor="email">Email</InputLabel>
+ <Input
+ id="email"
+ name="email"
+ value={email}
+ autoComplete="email"
+ autoFocus
+ onChange={handleEmailChange} />
+ {failed && <FormHelperText>Invalid username or password</FormHelperText>}
+ </FormControl>
+
+ <FormControl margin="normal" required fullWidth>
+ <InputLabel htmlFor="password">Password</InputLabel>
+ <Input
+ id="password"
+ name="password"
+ type="password"
+ value={password}
+ autoComplete="current-password"
+ onChange={handlePasswordChange} />
+ </FormControl>
+
+ <div className={classes.buttons}>
+ <Button
+ type="button"
+ variant="contained"
+ disabled
+ className={classes.button}
+ onClick={handleRegister}>
+ Register
</Button>
- <Button
- type="submit"
- variant="contained"
- color="primary"
- disabled={!email || !password}
- className={classes.button}>
- Login
+ <Button
+ type="submit"
+ variant="contained"
+ color="primary"
+ disabled={!email || !password}
+ className={classes.button}>
+ Login
</Button>
- </div>
-
- </form>
-
- </Paper>
- </main>
- );
- }
+ </div>
+ </form>
+ </Paper>
+ </main>
+ );
}
-export default withStyles(styles)(LoginPage);
+export default LoginPage;
diff --git a/modern/src/MainPage.js b/modern/src/MainPage.js
index 450a5e00..8e9b695f 100644
--- a/modern/src/MainPage.js
+++ b/modern/src/MainPage.js
@@ -1,14 +1,14 @@
-import React, { Component } from 'react';
+import React, { useState, useEffect } from 'react';
import ContainerDimensions from 'react-container-dimensions';
import MainToobar from './MainToolbar';
import MainMap from './MainMap';
import Drawer from '@material-ui/core/Drawer';
-import withStyles from '@material-ui/core/styles/withStyles';
import SocketController from './SocketController';
-import withWidth, { isWidthUp } from '@material-ui/core/withWidth';
import DeviceList from './DeviceList';
+import { makeStyles } from '@material-ui/core';
+import { useHistory } from 'react-router-dom';
-const styles = theme => ({
+const useStyles = makeStyles(theme => ({
root: {
height: "100vh",
display: "flex",
@@ -35,57 +35,43 @@ const styles = theme => ({
mapContainer: {
flexGrow: 1
}
-});
+}));
-class MainPage extends Component {
- constructor(props) {
- super(props);
- this.state = {
- loading: true
- };
- }
+const MainPage = () => {
+ const [loading, setLoading] = useState(true);
+ const classes = useStyles();
+ const history = useHistory();
- componentDidMount() {
+ useEffect(() => {
fetch('/api/session').then(response => {
if (response.ok) {
- this.setState({
- loading: false
- });
+ setLoading(false);
} else {
- this.props.history.push('/login');
+ history.push('/login');
}
});
- }
+ }, [history]);
- render() {
- const { classes } = this.props;
- const { loading } = this.state;
- if (loading) {
- return (
- <div>Loading...</div>
- );
- } else {
- return (
- <div className={classes.root}>
- <SocketController />
- <MainToobar history={this.props.history} />
- <div className={classes.content}>
- <Drawer
- anchor={isWidthUp('sm', this.props.width) ? "left" : "bottom"}
- variant="permanent"
- classes={{ paper: classes.drawerPaper }}>
- <DeviceList />
- </Drawer>
- <div className={classes.mapContainer}>
- <ContainerDimensions>
- <MainMap/>
- </ContainerDimensions>
- </div>
- </div>
- </div>
- );
- }
- }
+ return (loading ? (<div>Loading...</div>) : (<div className={classes.root}>
+ <SocketController />
+ <MainToobar history={history} />
+ <div className={classes.content}>
+ { /* <Drawer
+ anchor={isWidthUp('sm', this.props.width) ? "left" : "bottom"} NOTE: What's this do?
+ variant="permanent"
+ classes={{ paper: classes.drawerPaper }}> */}
+ <Drawer
+ variant="permanent"
+ classes={{ paper: classes.drawerPaper }}>
+ <DeviceList />
+ </Drawer>
+ <div className={classes.mapContainer}>
+ <ContainerDimensions>
+ <MainMap />
+ </ContainerDimensions>
+ </div>
+ </div>
+ </div>));
}
-export default withWidth()(withStyles(styles)(MainPage));
+export default MainPage;
diff --git a/modern/src/MainToolbar.js b/modern/src/MainToolbar.js
index 6e2e4d6d..9ec89a2f 100644
--- a/modern/src/MainToolbar.js
+++ b/modern/src/MainToolbar.js
@@ -1,5 +1,6 @@
-import React, { Component, Fragment } from 'react';
-import { withStyles } from '@material-ui/core/styles';
+import React, { useState } from 'react';
+import { useHistory } from 'react-router-dom';
+import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
@@ -16,7 +17,7 @@ import DashboardIcon from '@material-ui/icons/Dashboard';
import BarChartIcon from '@material-ui/icons/BarChart';
import SettingsIcon from '@material-ui/icons/Settings';
-const styles = theme => ({
+const useStyles = makeStyles(theme => ({
flex: {
flexGrow: 1
},
@@ -30,94 +31,72 @@ const styles = theme => ({
marginLeft: -12,
marginRight: 20,
}
-});
+}));
-class MainToobar extends Component {
- constructor(props) {
- super(props);
- this.state = {
- drawer: false
- };
- this.openDrawer = this.openDrawer.bind(this);
- this.closeDrawer = this.closeDrawer.bind(this);
- this.handleLogout = this.handleLogout.bind(this);
- }
-
- openDrawer() {
- this.setState({
- drawer: true
- });
- };
+const MainToolbar = () => {
+ const [drawer, setDrawer] = useState(false);
+ const classes = useStyles();
+ const history = useHistory();
- closeDrawer() {
- this.setState({
- drawer: false
- });
- };
+ const openDrawer = () => { setDrawer(true) }
+ const closeDrawer = () => { setDrawer(false) }
- handleLogout() {
- fetch("/api/session", {
- method: "DELETE"
- }).then(response => {
+ const handleLogout = () => {
+ fetch('/api/session', { method: 'DELETE' }).then(response => {
if (response.ok) {
- this.props.history.push('/login');
+ history.push('/login');
}
- });
+ })
}
- render() {
- const { classes } = this.props;
- return (
- <Fragment>
- <AppBar position="static" className={classes.appBar}>
- <Toolbar>
- <IconButton
- className={classes.menuButton}
- color="inherit"
- onClick={this.openDrawer}>
- <MenuIcon />
- </IconButton>
- <Typography variant="h6" color="inherit" className={classes.flex}>
- Traccar
+ return (<>
+ <AppBar position="static" className={classes.appBar}>
+ <Toolbar>
+ <IconButton
+ className={classes.menuButton}
+ color="inherit"
+ onClick={openDrawer}>
+ <MenuIcon />
+ </IconButton>
+ <Typography variant="h6" color="inherit" className={classes.flex}>
+ Traccar
</Typography>
- <Button color="inherit" onClick={this.handleLogout}>Logout</Button>
- </Toolbar>
- </AppBar>
- <Drawer open={this.state.drawer} onClose={this.closeDrawer}>
- <div
- tabIndex={0}
- className={classes.list}
- role="button"
- onClick={this.closeDrawer}
- onKeyDown={this.closeDrawer}>
- <List>
- <ListItem button>
- <ListItemIcon>
- <DashboardIcon />
- </ListItemIcon>
- <ListItemText primary="Dashboard" />
- </ListItem>
- <ListItem button disabled>
- <ListItemIcon>
- <BarChartIcon />
- </ListItemIcon>
- <ListItemText primary="Reports" />
- </ListItem>
- </List>
- <Divider />
- <List>
- <ListItem button disabled>
- <ListItemIcon>
- <SettingsIcon />
- </ListItemIcon>
- <ListItemText primary="Settings" />
- </ListItem>
- </List>
- </div>
- </Drawer>
- </Fragment>
- );
- }
+ <Button color="inherit" onClick={handleLogout}>Logout</Button>
+ </Toolbar>
+ </AppBar>
+ <Drawer open={drawer} onClose={closeDrawer}>
+ <div
+ tabIndex={0}
+ className={classes.list}
+ role="button"
+ onClick={closeDrawer}
+ onKeyDown={closeDrawer}>
+ <List>
+ <ListItem button>
+ <ListItemIcon>
+ <DashboardIcon />
+ </ListItemIcon>
+ <ListItemText primary="Dashboard" />
+ </ListItem>
+ <ListItem button disabled>
+ <ListItemIcon>
+ <BarChartIcon />
+ </ListItemIcon>
+ <ListItemText primary="Reports" />
+ </ListItem>
+ </List>
+ <Divider />
+ <List>
+ <ListItem button disabled>
+ <ListItemIcon>
+ <SettingsIcon />
+ </ListItemIcon>
+ <ListItemText primary="Settings" />
+ </ListItem>
+ </List>
+ </div>
+ </Drawer>
+ </>);
}
-export default withStyles(styles)(MainToobar);
+export default MainToolbar;