OrganizationPage hinzugefügt, UsersPage fix
This commit is contained in:
@@ -2,12 +2,13 @@ import { useEffect, useState } from 'react';
|
||||
import {
|
||||
Box, Typography, Alert, IconButton, Tooltip,
|
||||
Dialog, DialogTitle, DialogContent, DialogActions,
|
||||
TextField, Button, CircularProgress, Stack, Divider,
|
||||
Snackbar,
|
||||
TextField, Button, CircularProgress, Stack,
|
||||
Snackbar, Select, MenuItem, FormControl, InputLabel,
|
||||
} from '@mui/material';
|
||||
import { DataGrid } from '@mui/x-data-grid';
|
||||
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
|
||||
import LockResetIcon from '@mui/icons-material/LockReset';
|
||||
import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
|
||||
import axiosInstance from '../api/axiosInstance';
|
||||
|
||||
export default function UsersPage() {
|
||||
@@ -20,8 +21,11 @@ export default function UsersPage() {
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [saveError, setSaveError] = useState('');
|
||||
|
||||
const [resetting, setResetting] = useState(null); // user id der gerade resettet wird
|
||||
const [snackbar, setSnackbar] = useState(''); // Erfolgsmeldung
|
||||
const [resetting, setResetting] = useState(null);
|
||||
const [snackbar, setSnackbar] = useState('');
|
||||
|
||||
const [deleteUser, setDeleteUser] = useState(null);
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
axiosInstance.get('/api/users')
|
||||
@@ -35,7 +39,7 @@ export default function UsersPage() {
|
||||
setEditForm({
|
||||
email: user.email ?? '',
|
||||
nickname: user.nickname ?? '',
|
||||
role: user.role ?? '',
|
||||
role: user.role?.replace('ROLE_', '') ?? '',
|
||||
});
|
||||
setSaveError('');
|
||||
};
|
||||
@@ -77,6 +81,20 @@ export default function UsersPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteConfirm = async () => {
|
||||
setDeleting(true);
|
||||
try {
|
||||
await axiosInstance.delete(`/api/users/${deleteUser.id}`);
|
||||
setRows((prev) => prev.filter((r) => r.id !== deleteUser.id));
|
||||
setSnackbar(`Nutzer ${deleteUser.nickname} wurde gelöscht.`);
|
||||
setDeleteUser(null);
|
||||
} catch (err) {
|
||||
setSnackbar(err.response?.data?.message ?? 'Löschen fehlgeschlagen');
|
||||
} finally {
|
||||
setDeleting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ field: 'id', headerName: 'ID', width: 80 },
|
||||
{ field: 'nickname', headerName: 'Anzeigename', flex: 1 },
|
||||
@@ -91,7 +109,7 @@ export default function UsersPage() {
|
||||
{
|
||||
field: 'actions',
|
||||
headerName: '',
|
||||
width: 100,
|
||||
width: 130,
|
||||
sortable: false,
|
||||
renderCell: ({ row }) => (
|
||||
<Box sx={{ display: 'flex', gap: 0.5 }}>
|
||||
@@ -115,6 +133,11 @@ export default function UsersPage() {
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title="Nutzer löschen">
|
||||
<IconButton size="small" color="error" onClick={() => setDeleteUser(row)}>
|
||||
<DeleteOutlineIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
),
|
||||
},
|
||||
@@ -159,19 +182,19 @@ export default function UsersPage() {
|
||||
onChange={handleFormChange}
|
||||
fullWidth
|
||||
/>
|
||||
<TextField
|
||||
label="Berechtigung"
|
||||
name="role"
|
||||
select
|
||||
value={editForm.role ?? ''}
|
||||
onChange={handleFormChange}
|
||||
fullWidth
|
||||
SelectProps={{ native: true }}
|
||||
>
|
||||
<option value="ADMIN">ADMIN</option>
|
||||
<option value="REPORTER">REPORTER</option>
|
||||
<option value="USER">USER</option>
|
||||
</TextField>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Berechtigung</InputLabel>
|
||||
<Select
|
||||
name="role"
|
||||
value={editForm.role ?? ''}
|
||||
label="Berechtigung"
|
||||
onChange={handleFormChange}
|
||||
>
|
||||
<MenuItem value="ADMIN">ADMIN</MenuItem>
|
||||
<MenuItem value="REPORTER">REPORTER</MenuItem>
|
||||
<MenuItem value="USER">USER</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Stack>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ px: 3, pb: 2.5 }}>
|
||||
@@ -187,7 +210,29 @@ export default function UsersPage() {
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
{/* Snackbar für Reset-Feedback */}
|
||||
{/* Delete Bestätigungs-Dialog */}
|
||||
<Dialog open={!!deleteUser} onClose={() => setDeleteUser(null)} maxWidth="xs" fullWidth>
|
||||
<DialogTitle sx={{ fontWeight: 600 }}>Nutzer löschen</DialogTitle>
|
||||
<DialogContent>
|
||||
<Typography variant="body2">
|
||||
Soll <strong>{deleteUser?.nickname}</strong> ({deleteUser?.email}) wirklich gelöscht werden? Diese Aktion kann nicht rückgängig gemacht werden.
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions sx={{ px: 3, pb: 2.5 }}>
|
||||
<Button onClick={() => setDeleteUser(null)} disabled={deleting}>Abbrechen</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={handleDeleteConfirm}
|
||||
disabled={deleting}
|
||||
startIcon={deleting ? <CircularProgress size={16} color="inherit" /> : null}
|
||||
>
|
||||
Löschen
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
{/* Snackbar */}
|
||||
<Snackbar
|
||||
open={!!snackbar}
|
||||
autoHideDuration={5000}
|
||||
|
||||
Reference in New Issue
Block a user