diff options
author | ditoaugusta <dt_ap@ymail.com> | 2020-03-27 17:39:49 +0700 |
---|---|---|
committer | ditoaugusta <dt_ap@ymail.com> | 2020-03-27 17:39:49 +0700 |
commit | 8bef4f04c2b0b203450fe5753b6109a0b0d04e82 (patch) | |
tree | a7bed472e98fa52f1887d060a841d87bd3f0fd6a | |
parent | b10607f96ad72f5f971fbd867eeeeb86380f79cb (diff) | |
download | etbsa-traccar-web-8bef4f04c2b0b203450fe5753b6109a0b0d04e82.tar.gz etbsa-traccar-web-8bef4f04c2b0b203450fe5753b6109a0b0d04e82.tar.bz2 etbsa-traccar-web-8bef4f04c2b0b203450fe5753b6109a0b0d04e82.zip |
exp: hooks (1)
-rw-r--r-- | modern/src/DeviceList.js | 46 | ||||
-rw-r--r-- | modern/src/LoginPage.js | 166 | ||||
-rw-r--r-- | modern/src/MainPage.js | 82 | ||||
-rw-r--r-- | modern/src/MainToolbar.js | 147 |
4 files changed, 191 insertions, 250 deletions
diff --git a/modern/src/DeviceList.js b/modern/src/DeviceList.js index 235ba22..8d855a7 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 c094fa3..1f0b950 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 450a5e0..8e9b695 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 6e2e4d6..9ec89a2 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; |