Files
TERES_web_frontend/src/components/Provider/DialogComponent.tsx

167 lines
4.0 KiB
TypeScript
Raw Normal View History

import React, { useState } from 'react';
import {
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
Typography,
Box,
IconButton,
} from '@mui/material';
import {
Close as CloseIcon,
Info as InfoIcon,
CheckCircle as SuccessIcon,
Warning as WarningIcon,
Error as ErrorIcon,
Help as ConfirmIcon,
} from '@mui/icons-material';
import { useTranslation } from 'react-i18next';
import { type IDialogInstance } from '../../interfaces/common';
interface DialogComponentProps {
dialog: IDialogInstance;
onClose: (result: boolean) => void;
}
const DialogComponent: React.FC<DialogComponentProps> = ({ dialog, onClose }) => {
const [loading, setLoading] = useState(false);
const { t } = useTranslation();
const { config } = dialog;
// 获取对话框图标
const getDialogIcon = () => {
const iconProps = { sx: { fontSize: 24, mr: 1 } };
switch (config.type) {
case 'info':
return <InfoIcon {...iconProps} color="info" />;
case 'success':
return <SuccessIcon {...iconProps} color="success" />;
case 'warning':
return <WarningIcon {...iconProps} color="warning" />;
case 'error':
return <ErrorIcon {...iconProps} color="error" />;
case 'confirm':
return <ConfirmIcon {...iconProps} color="warning" />;
default:
return null;
}
};
// 获取确认按钮颜色
const getConfirmButtonColor = () => {
switch (config.type) {
case 'error':
case 'warning':
return 'error';
case 'success':
return 'success';
case 'info':
return 'info';
default:
return 'primary';
}
};
// 处理确认操作
const handleConfirm = async () => {
try {
setLoading(true);
if (config.onConfirm) {
await config.onConfirm();
}
onClose(true);
} catch (error) {
console.error('Dialog confirm error:', error);
// 即使出错也关闭对话框但返回false
onClose(false);
} finally {
setLoading(false);
}
};
// 处理取消操作
const handleCancel = () => {
if (config.onCancel) {
config.onCancel();
}
onClose(false);
};
// 处理遮罩点击
const handleBackdropClick = () => {
if (config.maskClosable !== false) {
handleCancel();
}
};
return (
<Dialog
open={true}
onClose={handleBackdropClick}
maxWidth="sm"
fullWidth
slotProps={{
paper: {
sx: {
width: config.width || 'auto',
minWidth: config.width || '300px',
maxWidth: config.width || '500px',
}
}
}}
>
{/* 标题栏 */}
<DialogTitle sx={{ display: 'flex', alignItems: 'center', pr: 1 }}>
<Box sx={{ display: 'flex', alignItems: 'center', flex: 1 }}>
{getDialogIcon()}
<Typography variant="h6" component="span">
{config.title || t('dialog.confirm')}
</Typography>
</Box>
<IconButton
onClick={handleCancel}
size="small"
sx={{ ml: 1 }}
>
<CloseIcon />
</IconButton>
</DialogTitle>
{/* 内容区域 */}
<DialogContent>
<Typography variant="body1" sx={{ py: 1 }}>
{config.content}
</Typography>
</DialogContent>
{/* 操作按钮 */}
<DialogActions sx={{ px: 3, pb: 2 }}>
{config.showCancel !== false && (
<Button
onClick={handleCancel}
variant="outlined"
disabled={loading}
>
{config.cancelText || t('common.cancel')}
</Button>
)}
<Button
onClick={handleConfirm}
variant="contained"
color={getConfirmButtonColor() as any}
disabled={loading}
sx={{ ml: 1 }}
>
{loading ? t('dialog.processing') : (config.confirmText || t('common.confirm'))}
</Button>
</DialogActions>
</Dialog>
);
};
export default DialogComponent;