Files
Jyotisha/frontend/src/components/admin/reason-action-modal.tsx
T
Jesse_Chen 4f6cf5782d
Independent Staging Quality Gate / validate (push) Successful in 12m37s
Independent Staging Quality Gate / publish (push) Successful in 10m0s
fix(admin): remove operation-level email reauthentication
2026-08-16 14:07:57 +08:00

77 lines
2.0 KiB
TypeScript

"use client";
import { Alert, Form, Input, Modal } from "antd";
import { useState } from "react";
type ReasonActionModalProps = {
open: boolean;
title: string;
okText: string;
danger?: boolean;
confirmLoading?: boolean;
onCancel: () => void;
onSubmit: (reason: string) => Promise<void> | void;
};
type ReasonFormValues = {
reason: string;
};
export function ReasonActionModal({
open,
title,
okText,
danger = false,
confirmLoading = false,
onCancel,
onSubmit,
}: ReasonActionModalProps) {
const [form] = Form.useForm<ReasonFormValues>();
const [actionLoading, setActionLoading] = useState(false);
const [actionError, setActionError] = useState<string>();
async function submit(values: ReasonFormValues) {
setActionError(undefined);
setActionLoading(true);
try {
await onSubmit(values.reason.trim());
} 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={() => form.submit()}
afterOpenChange={(visible) => {
if (visible) form.resetFields();
setActionError(undefined);
}}
destroyOnHidden
>
<Form form={form} layout="vertical" preserve={false} onFinish={submit}>
<Form.Item
label="操作原因"
name="reason"
rules={[
{ required: true, whitespace: true, message: "请输入操作原因" },
{ max: 500, message: "操作原因最多 500 字" },
]}
>
<Input.TextArea rows={3} maxLength={500} showCount autoFocus />
</Form.Item>
{actionError ? <Alert type="error" showIcon message={actionError} /> : null}
</Form>
</Modal>
);
}