Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 1x 7x 7x 7x 7x 1x 1x 1x 1x 1x 7x 7x | import React from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
Box,
Typography,
IconButton,
Alert,
} from '@mui/material';
import { Close as CloseIcon, Warning as WarningIcon } from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import { useBreakpoints } from '@/hooks/useBreakpoints';
import { useDeleteUser } from '../../../hooks/useUserManagement';
import type { User } from '../../../types/user.types';
interface DeleteUserDialogProps {
user: User | null;
open: boolean;
onClose: () => void;
onSuccess?: () => void;
}
const DeleteUserDialog: React.FC<DeleteUserDialogProps> = ({ user, open, onClose, onSuccess }) => {
const { t } = useTranslation('userManagement');
const { isMobile } = useBreakpoints();
const deleteUserMutation = useDeleteUser();
const handleDelete = async () => {
Iif (!user) return;
try {
await deleteUserMutation.mutateAsync(user.id);
onSuccess?.();
onClose();
} catch (error) {
console.error('Failed to delete user:', error);
// Error is handled by React Query mutation error state
}
};
Iif (!user) return null;
return (
<Dialog
open={open}
onClose={onClose}
maxWidth="sm"
fullWidth
fullScreen={isMobile}
aria-labelledby="delete-user-dialog-title"
data-testid="delete-user-dialog"
>
<DialogTitle id="delete-user-dialog-title">
<Box display="flex" justifyContent="space-between" alignItems="center">
<Box display="flex" alignItems="center" gap={1}>
<WarningIcon color="error" />
<Typography variant="h6">{t('modal.deleteConfirm.title')}</Typography>
</Box>
<IconButton
edge="end"
color="inherit"
onClick={onClose}
aria-label={t('common:actions.close')}
>
<CloseIcon />
</IconButton>
</Box>
</DialogTitle>
<DialogContent dividers>
{/* User Information */}
<Box sx={{ mb: 3 }}>
<Typography variant="body1" gutterBottom>
{t('modal.deleteConfirm.message')}
</Typography>
<Typography variant="body1" sx={{ mt: 2 }}>
<strong>
{user.firstName} {user.lastName}
</strong>
</Typography>
<Typography variant="body2" color="text.secondary" data-testid="delete-user-email">
{user.email}
</Typography>
</Box>
{/* GDPR Warning */}
<Alert severity="error" sx={{ mb: 2 }} data-testid="delete-user-gdpr-warning">
<Typography variant="body2" fontWeight="bold">
{t('modal.deleteConfirm.gdprWarning')}
</Typography>
</Alert>
{/* Cascade Warning */}
<Alert severity="warning" data-testid="delete-user-cascade-warning">
<Typography variant="body2">{t('modal.deleteConfirm.cascadeWarning')}</Typography>
</Alert>
{/* Mutation Error */}
{deleteUserMutation.isError && (
<Alert severity="error" sx={{ mt: 2 }}>
{t('error.deleteFailed')}
</Alert>
)}
</DialogContent>
<DialogActions>
<Button onClick={onClose} variant="outlined" data-testid="delete-user-cancel">
{t('common:actions.cancel')}
</Button>
<Button
onClick={handleDelete}
variant="contained"
color="error"
disabled={deleteUserMutation.isPending}
data-testid="delete-user-confirm"
>
{deleteUserMutation.isPending ? t('common:actions.deleting') : t('common:actions.delete')}
</Button>
</DialogActions>
</Dialog>
);
};
export default DeleteUserDialog;
|