diff options
author | Anton Tananaev <anton@traccar.org> | 2022-07-18 16:15:54 -0700 |
---|---|---|
committer | Anton Tananaev <anton@traccar.org> | 2022-07-18 16:15:54 -0700 |
commit | a86739114c754e70506c43dd1bbf78a7d1039207 (patch) | |
tree | 2a339ed71ca3ed579d2e2d37b6a48fa74f10de9f /modern | |
parent | 33f9da8e98763416d7f440e7ac4b8177c929eaff (diff) | |
download | trackermap-web-a86739114c754e70506c43dd1bbf78a7d1039207.tar.gz trackermap-web-a86739114c754e70506c43dd1bbf78a7d1039207.tar.bz2 trackermap-web-a86739114c754e70506c43dd1bbf78a7d1039207.zip |
Delete user account
Diffstat (limited to 'modern')
-rw-r--r-- | modern/src/settings/UserPage.js | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/modern/src/settings/UserPage.js b/modern/src/settings/UserPage.js index 5d29c0b4..863bb0b7 100644 --- a/modern/src/settings/UserPage.js +++ b/modern/src/settings/UserPage.js @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import { Accordion, AccordionSummary, @@ -16,10 +16,12 @@ import { OutlinedInput, FormGroup, TextField, + Button, } from '@mui/material'; import makeStyles from '@mui/styles/makeStyles'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import CachedIcon from '@mui/icons-material/Cached'; +import DeleteForeverIcon from '@mui/icons-material/DeleteForever'; import { useDispatch, useSelector } from 'react-redux'; import moment from 'moment'; import EditItemView from './components/EditItemView'; @@ -34,6 +36,7 @@ import useCommonUserAttributes from '../common/attributes/useCommonUserAttribute import { useAdministrator, useManager } from '../common/util/permissions'; import { prefixString } from '../common/util/stringUtils'; import useQuery from '../common/util/useQuery'; +import { useCatch } from '../reactHelper'; const useStyles = makeStyles((theme) => ({ details: { @@ -46,6 +49,7 @@ const useStyles = makeStyles((theme) => ({ const UserPage = () => { const classes = useStyles(); + const navigate = useNavigate(); const dispatch = useDispatch(); const t = useTranslation(); @@ -60,6 +64,24 @@ const UserPage = () => { const { id } = useParams(); const [item, setItem] = useState(id === currentUser.id.toString() ? currentUser : null); + const [deleteEmail, setDeleteEmail] = useState(); + const [deleteFailed, setDeleteFailed] = useState(false); + + const handleDelete = useCatch(async () => { + if (deleteEmail === currentUser.email) { + setDeleteFailed(false); + const response = await fetch(`/api/users/${currentUser.id}`, { method: 'DELETE' }); + if (response.ok) { + navigate('/login'); + dispatch(sessionActions.updateUser(null)); + } else { + throw Error(await response.text()); + } + } else { + setDeleteFailed(true); + } + }); + const query = useQuery(); const [queryHandled, setQueryHandled] = useState(false); const attribute = query.get('attribute'); @@ -320,7 +342,32 @@ const UserPage = () => { definitions={{ ...commonUserAttributes, ...userAttributes }} focusAttribute={attribute} /> - {item.id && manager && ( + {item.id === currentUser.id && ( + <Accordion> + <AccordionSummary expandIcon={<ExpandMoreIcon />}> + <Typography variant="subtitle1" color="error"> + {t('userDeleteAccount')} + </Typography> + </AccordionSummary> + <AccordionDetails className={classes.details}> + <TextField + value={deleteEmail} + onChange={(event) => setDeleteEmail(event.target.value)} + label={t('userEmail')} + error={deleteFailed} + /> + <Button + variant="outlined" + color="error" + onClick={handleDelete} + startIcon={<DeleteForeverIcon />} + > + {t('userDeleteAccount')} + </Button> + </AccordionDetails> + </Accordion> + )} + {item.id && item.id !== currentUser.id && manager && ( <Accordion> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography variant="subtitle1"> |