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 | 2x 7x 7x 7x 7x 7x 7x 7x 1x 1x 7x | /**
* DeleteSubscriberDialog — Destructive confirmation dialog
*
* Mirrors DeleteUserDialog.tsx pattern.
*
* Story 10.28: Newsletter Subscriber Management Page
*/
import React from 'react';
import {
Alert,
Box,
Button,
CircularProgress,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Typography,
} from '@mui/material';
import { Close, ErrorOutline } from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import type { components } from '@/types/generated/event-newsletter-api.types';
import { useBreakpoints } from '@/hooks/useBreakpoints';
import { useDeleteSubscriber } from '@/hooks/useNewsletterSubscribers';
type SubscriberResponse = components['schemas']['SubscriberResponse'];
interface DeleteSubscriberDialogProps {
open: boolean;
subscriber: SubscriberResponse | null;
onClose: () => void;
onSuccess: () => void;
}
const DeleteSubscriberDialog: React.FC<DeleteSubscriberDialogProps> = ({
open,
subscriber,
onClose,
onSuccess,
}) => {
const { t } = useTranslation('newsletterSubscribers');
const { t: tCommon } = useTranslation('common');
const { isMobile } = useBreakpoints();
const mutation = useDeleteSubscriber();
React.useEffect(() => {
if (open) mutation.reset();
}, [open, mutation]);
const handleConfirm = () => {
Iif (!subscriber?.id) return;
mutation.mutate(subscriber.id, {
onSuccess: () => {
onSuccess();
onClose();
},
});
};
return (
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth fullScreen={isMobile}>
<DialogTitle>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Box display="flex" alignItems="center" gap={1}>
<ErrorOutline color="error" />
<Typography variant="h6">{t('dialogs.delete.title')}</Typography>
</Box>
<IconButton onClick={onClose} aria-label={tCommon('actions.close')}>
<Close />
</IconButton>
</Box>
</DialogTitle>
<DialogContent dividers>
<Typography>{t('dialogs.delete.message', { email: subscriber?.email })}</Typography>
{mutation.isError && (
<Alert severity="error" sx={{ mt: 2 }}>
{tCommon('errors.unexpected')}
</Alert>
)}
</DialogContent>
<DialogActions>
<Button onClick={onClose} variant="outlined">
{tCommon('actions.cancel')}
</Button>
<Button
onClick={handleConfirm}
variant="contained"
color="error"
disabled={mutation.isPending}
>
{mutation.isPending ? <CircularProgress size={20} /> : t('actions.delete')}
</Button>
</DialogActions>
</Dialog>
);
};
export default DeleteSubscriberDialog;
|