60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { Alert, Modal, Typography } from "antd";
|
|
import { useState } from "react";
|
|
|
|
type ConfirmActionModalProps = {
|
|
open: boolean;
|
|
title: string;
|
|
okText: string;
|
|
danger?: boolean;
|
|
confirmLoading?: boolean;
|
|
onCancel: () => void;
|
|
onConfirm: () => Promise<void> | void;
|
|
};
|
|
|
|
export function ConfirmActionModal({
|
|
open,
|
|
title,
|
|
okText,
|
|
danger = false,
|
|
confirmLoading = false,
|
|
onCancel,
|
|
onConfirm,
|
|
}: ConfirmActionModalProps) {
|
|
const [actionLoading, setActionLoading] = useState(false);
|
|
const [actionError, setActionError] = useState<string>();
|
|
|
|
async function confirm() {
|
|
setActionError(undefined);
|
|
setActionLoading(true);
|
|
try {
|
|
await onConfirm();
|
|
} catch (error) {
|
|
setActionError(error instanceof Error ? error.message : "操作失败,请稍后再试");
|
|
} finally {
|
|
setActionLoading(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Modal
|
|
open={open}
|
|
title={title}
|
|
okText={okText}
|
|
cancelText="取消"
|
|
okButtonProps={{ danger }}
|
|
confirmLoading={confirmLoading || actionLoading}
|
|
onCancel={onCancel}
|
|
onOk={() => void confirm()}
|
|
afterOpenChange={() => setActionError(undefined)}
|
|
destroyOnHidden
|
|
>
|
|
<Typography.Paragraph type="secondary">
|
|
确认后将立即执行该操作,系统会自动记录管理员、动作和请求 ID。
|
|
</Typography.Paragraph>
|
|
{actionError ? <Alert type="error" showIcon message={actionError} /> : null}
|
|
</Modal>
|
|
);
|
|
}
|