149 lines
4.0 KiB
TypeScript
149 lines
4.0 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import {
|
|
IconButton,
|
|
Dialog,
|
|
DialogActions,
|
|
DialogContent,
|
|
DialogContentText,
|
|
DialogTitle,
|
|
Button,
|
|
useMediaQuery,
|
|
Tooltip,
|
|
SxProps,
|
|
} from '@mui/material';
|
|
import { useTheme } from '@mui/material/styles';
|
|
import ResetIcon from '@mui/icons-material/History';
|
|
|
|
interface DeleteConfirmationProps {
|
|
// Legacy props for backward compatibility (uncontrolled mode)
|
|
onDelete?: () => void;
|
|
disabled?: boolean;
|
|
label?: string;
|
|
action?: "delete" | "reset";
|
|
color?: "inherit" | "default" | "primary" | "secondary" | "error" | "info" | "success" | "warning" | undefined;
|
|
sx?: SxProps;
|
|
// New props for controlled mode
|
|
open?: boolean;
|
|
onClose?: () => void;
|
|
onConfirm?: () => void;
|
|
title?: string;
|
|
message?: string;
|
|
|
|
// Optional props for button customization in controlled mode
|
|
hideButton?: boolean;
|
|
confirmButtonText?: string;
|
|
cancelButtonText?: string;
|
|
}
|
|
|
|
function capitalizeFirstLetter(str: string) {
|
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
}
|
|
|
|
const DeleteConfirmation = (props: DeleteConfirmationProps) => {
|
|
const {
|
|
// Legacy props
|
|
onDelete,
|
|
disabled,
|
|
label,
|
|
color,
|
|
action = "delete",
|
|
// New props
|
|
open: controlledOpen,
|
|
onClose: controlledOnClose,
|
|
onConfirm,
|
|
title,
|
|
message,
|
|
hideButton = false,
|
|
confirmButtonText,
|
|
cancelButtonText = "Cancel",
|
|
sx
|
|
} = props;
|
|
|
|
// Internal state for uncontrolled mode
|
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
const theme = useTheme();
|
|
const fullScreen = useMediaQuery(theme.breakpoints.down('md'));
|
|
|
|
// Determine if we're in controlled or uncontrolled mode
|
|
const isControlled = controlledOpen !== undefined;
|
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
|
|
const handleClickOpen = () => {
|
|
if (!isControlled) {
|
|
setInternalOpen(true);
|
|
}
|
|
};
|
|
|
|
const handleClose = () => {
|
|
if (isControlled) {
|
|
controlledOnClose?.();
|
|
} else {
|
|
setInternalOpen(false);
|
|
}
|
|
};
|
|
|
|
const handleConfirm = () => {
|
|
if (isControlled) {
|
|
onConfirm?.();
|
|
} else {
|
|
onDelete?.();
|
|
setInternalOpen(false);
|
|
}
|
|
};
|
|
|
|
// Determine dialog content based on mode
|
|
const dialogTitle = title || "Confirm Reset";
|
|
const dialogMessage = message || `This action will permanently ${capitalizeFirstLetter(action)} ${label ? label.toLowerCase() : "all data"} without the ability to recover it. Are you sure you want to continue?`;
|
|
const confirmText = confirmButtonText || `${capitalizeFirstLetter(action)} ${label || "Everything"}`;
|
|
|
|
return (
|
|
<>
|
|
{/* Only show button if not hidden (for controlled mode) */}
|
|
{!hideButton && (
|
|
<Tooltip title={label ? `${capitalizeFirstLetter(action)} ${label}` : "Reset"}>
|
|
<span style={{ display: "flex" }}> {/* This span is used to wrap the IconButton to ensure Tooltip works even when disabled */}
|
|
<IconButton
|
|
aria-label={action}
|
|
onClick={handleClickOpen}
|
|
color={color || "inherit"}
|
|
sx={{ display: "flex", margin: 'auto 0px', ...sx }}
|
|
size="large"
|
|
edge="start"
|
|
disabled={disabled}
|
|
>
|
|
<ResetIcon />
|
|
</IconButton>
|
|
</span>
|
|
</Tooltip>
|
|
)}
|
|
|
|
<Dialog
|
|
fullScreen={fullScreen}
|
|
open={isOpen}
|
|
onClose={handleClose}
|
|
aria-labelledby="responsive-dialog-title"
|
|
>
|
|
<DialogTitle id="responsive-dialog-title">
|
|
{dialogTitle}
|
|
</DialogTitle>
|
|
<DialogContent>
|
|
<DialogContentText>
|
|
{dialogMessage}
|
|
</DialogContentText>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<Button autoFocus onClick={handleClose}>
|
|
{cancelButtonText}
|
|
</Button>
|
|
<Button onClick={handleConfirm} color="error" variant="contained">
|
|
{confirmText}
|
|
</Button>
|
|
</DialogActions>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export {
|
|
DeleteConfirmation
|
|
}; |