diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2020-09-20 21:28:52 -0700 |
---|---|---|
committer | Anton Tananaev <anton.tananaev@gmail.com> | 2020-09-20 21:28:52 -0700 |
commit | 787c9dc0ec684d3524ec060b6422ffbaea5012ac (patch) | |
tree | d8e125759f8e54de2921127365f90016013c3c2c /modern/src | |
parent | 9801338e03965ec28af9369b850f339ba534003f (diff) | |
download | etbsa-traccar-web-787c9dc0ec684d3524ec060b6422ffbaea5012ac.tar.gz etbsa-traccar-web-787c9dc0ec684d3524ec060b6422ffbaea5012ac.tar.bz2 etbsa-traccar-web-787c9dc0ec684d3524ec060b6422ffbaea5012ac.zip |
Add user edit page
Diffstat (limited to 'modern/src')
-rw-r--r-- | modern/src/App.js | 2 | ||||
-rw-r--r-- | modern/src/DevicePage.js | 123 | ||||
-rw-r--r-- | modern/src/EditPage.js | 80 | ||||
-rw-r--r-- | modern/src/UserPage.js | 53 |
4 files changed, 165 insertions, 93 deletions
diff --git a/modern/src/App.js b/modern/src/App.js index 0f2a69b..a4c00e2 100644 --- a/modern/src/App.js +++ b/modern/src/App.js @@ -6,6 +6,7 @@ import LoginPage from './LoginPage'; import RouteReportPage from './reports/RouteReportPage'; import UsersPage from './admin/UsersPage'; import DevicePage from './DevicePage'; +import UserPage from './UserPage'; import SocketController from './SocketController'; const App = () => { @@ -16,6 +17,7 @@ const App = () => { <Switch> <Route exact path='/' component={MainPage} /> <Route exact path='/login' component={LoginPage} /> + <Route exact path='/user/:id?' component={UserPage} /> <Route exact path='/device/:id?' component={DevicePage} /> <Route exact path='/reports/route' component={RouteReportPage} /> <Route exact path='/admin/users' component={UsersPage} /> diff --git a/modern/src/DevicePage.js b/modern/src/DevicePage.js index ee52549..14e978e 100644 --- a/modern/src/DevicePage.js +++ b/modern/src/DevicePage.js @@ -1,106 +1,43 @@ -import React, { useEffect, useState } from 'react'; -import MainToobar from './MainToolbar'; -import { useHistory, useParams } from 'react-router-dom'; -import { makeStyles } from '@material-ui/core/styles'; +import React, { useState } from 'react'; import TextField from '@material-ui/core/TextField'; -import Container from '@material-ui/core/Container'; -import Button from '@material-ui/core/Button'; -import FormControl from '@material-ui/core/FormControl'; import t from './common/localization'; - -const useStyles = makeStyles(theme => ({ - container: { - marginTop: theme.spacing(2), - }, - buttons: { - display: 'flex', - justifyContent: 'space-evenly', - '& > *': { - flexBasis: '33%', - }, - }, -})); +import EditPage from './EditPage'; const DevicePage = () => { - const history = useHistory(); - const classes = useStyles(); - const { id } = useParams(); - const [device, setDevice] = useState(); + const [item, setItem] = useState(); + const [name, setName] = useState(''); const [uniqueId, setUniqueId] = useState(''); - useEffect(() => { - fetch(`/api/devices/${id}`).then(response => { - if (response.ok) { - response.json().then(setDevice); - } - }); - }, [id]); - - const handleSave = () => { - const updatedDevice = id ? device : {}; - updatedDevice.name = name || updatedDevice.name; - updatedDevice.uniqueId = uniqueId || updatedDevice.uniqueId; - - let request; - if (id) { - request = fetch(`/api/devices/${id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(updatedDevice), - }); - } else { - request = fetch('/api/devices', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(updatedDevice), - }); - } - - request.then(response => { - if (response.ok) { - history.goBack(); - } - }); - } + const getItem = () => { + const updatedItem = item; + updatedItem.name = name; + updatedItem.uniqueId = uniqueId; + return updatedItem; + }; return ( - <> - <MainToobar history={history} /> - <Container maxWidth='xs' className={classes.container}> - <form> - {(!id || device) && - <TextField - margin='normal' - fullWidth - defaultValue={device && device.name} - onChange={(event) => setName(event.target.value)} - label={t('sharedName')} - variant='filled' /> - } - {(!id || device) && - <TextField - margin='normal' - fullWidth - defaultValue={device && device.uniqueId} - onChange={(event) => setUniqueId(event.target.value)} - label={t('deviceIdentifier')} - variant='filled' /> - } - <FormControl fullWidth margin='normal'> - <div className={classes.buttons}> - <Button type='button' color='primary' variant='outlined' onClick={() => history.goBack()}> - {t('sharedCancel')} - </Button> - <Button type='button' color='primary' variant='contained' onClick={handleSave}> - {t('sharedSave')} - </Button> - </div> - </FormControl> - </form> - </Container> - </> + <EditPage endpoint="devices" setItem={setItem} getItem={getItem}> + {item && + <> + <TextField + margin="normal" + fullWidth + defaultValue={item.name} + onChange={(event) => setName(event.target.value)} + label={t('sharedName')} + variant="filled" /> + <TextField + margin="normal" + fullWidth + defaultValue={item.uniqueId} + onChange={(event) => setUniqueId(event.target.value)} + label={t('deviceIdentifier')} + variant="filled" /> + </> + } + </EditPage> ); } diff --git a/modern/src/EditPage.js b/modern/src/EditPage.js new file mode 100644 index 0000000..23e8c07 --- /dev/null +++ b/modern/src/EditPage.js @@ -0,0 +1,80 @@ +import React from 'react'; +import MainToobar from './MainToolbar'; +import { useHistory, useParams } from 'react-router-dom'; +import { makeStyles } from '@material-ui/core/styles'; +import Container from '@material-ui/core/Container'; +import Button from '@material-ui/core/Button'; +import FormControl from '@material-ui/core/FormControl'; + +import t from './common/localization'; +import { useEffectAsync } from './reactHelper'; + +const useStyles = makeStyles(theme => ({ + container: { + marginTop: theme.spacing(2), + }, + buttons: { + display: 'flex', + justifyContent: 'space-evenly', + '& > *': { + flexBasis: '33%', + }, + }, +})); + +const EditPage = ({ children, endpoint, setItem, getItem }) => { + const history = useHistory(); + const classes = useStyles(); + const { id } = useParams(); + + useEffectAsync(async () => { + if (id) { + const response = await fetch(`/api/${endpoint}/${id}`); + if (response.ok) { + setItem(await response.json()); + } + } else { + setItem({}); + } + }, [id]); + + const handleSave = async () => { + let url = `/api/${endpoint}`; + if (id) { + url += `/${id}`; + } + + const response = await fetch(url, { + method: !id ? 'POST' : 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(getItem()), + }); + + if (response.ok) { + history.goBack(); + } + }; + + return ( + <> + <MainToobar history={history} /> + <Container maxWidth='xs' className={classes.container}> + <form> + {children} + <FormControl fullWidth margin='normal'> + <div className={classes.buttons}> + <Button type='button' color='primary' variant='outlined' onClick={() => history.goBack()}> + {t('sharedCancel')} + </Button> + <Button type='button' color='primary' variant='contained' onClick={handleSave}> + {t('sharedSave')} + </Button> + </div> + </FormControl> + </form> + </Container> + </> + ); +} + +export default EditPage; diff --git a/modern/src/UserPage.js b/modern/src/UserPage.js new file mode 100644 index 0000000..da8ba1b --- /dev/null +++ b/modern/src/UserPage.js @@ -0,0 +1,53 @@ +import React, { useState } from 'react'; +import TextField from '@material-ui/core/TextField'; + +import t from './common/localization'; +import EditPage from './EditPage'; + +const UserPage = () => { + const [item, setItem] = useState(); + + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + + const getItem = () => { + const updatedItem = item; + updatedItem.name = name; + updatedItem.email = email; + updatedItem.password = password; + return updatedItem; + }; + + return ( + <EditPage endpoint="users" setItem={setItem} getItem={getItem}> + {item && + <> + <TextField + margin="normal" + fullWidth + defaultValue={item.name} + onChange={(event) => setName(event.target.value)} + label={t('sharedName')} + variant="filled" /> + <TextField + margin="normal" + fullWidth + defaultValue={item.email} + onChange={(event) => setEmail(event.target.value)} + label={t('userEmail')} + variant="filled" /> + <TextField + margin="normal" + fullWidth + type="password" + onChange={(event) => setPassword(event.target.value)} + label={t('userPassword')} + variant="filled" /> + </> + } + </EditPage> + ); +} + +export default UserPage; |