106 lines
2.9 KiB
TypeScript
106 lines
2.9 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
import Modal from "@/components/Modal";
|
||
import StaffDeleteFields from "@/components/StaffDeleteFields";
|
||
|
||
/**
|
||
* Staff 软删帖:必选删除类型;仅「其他」须填理由。
|
||
* 作者自删仍用 ConfirmDialog,不走此组件。
|
||
*/
|
||
export default function StaffDeletePostModal({
|
||
open,
|
||
title,
|
||
busy,
|
||
onClose,
|
||
onConfirm,
|
||
}: {
|
||
open: boolean;
|
||
/** 帖子标题,展示在说明里 */
|
||
title?: string;
|
||
busy?: boolean;
|
||
onClose: () => void;
|
||
onConfirm: (opts: { delete_type: string; delete_reason: string }) => void;
|
||
}) {
|
||
const [deleteType, setDeleteType] = useState("spam");
|
||
const [reason, setReason] = useState("");
|
||
const [err, setErr] = useState("");
|
||
|
||
useEffect(() => {
|
||
if (open) {
|
||
setDeleteType("spam");
|
||
setReason("");
|
||
setErr("");
|
||
}
|
||
}, [open]);
|
||
|
||
if (!open) return null;
|
||
|
||
const reasonRequired = deleteType === "other";
|
||
|
||
const submit = () => {
|
||
const r = reason.trim();
|
||
if (reasonRequired) {
|
||
if (!r) {
|
||
setErr("请填写删除理由");
|
||
return;
|
||
}
|
||
if ([...r].length > 200) {
|
||
setErr("删除理由不能超过 200 字");
|
||
return;
|
||
}
|
||
}
|
||
onConfirm({ delete_type: deleteType, delete_reason: reasonRequired ? r : "" });
|
||
};
|
||
|
||
return (
|
||
<Modal
|
||
open
|
||
title="删除帖子"
|
||
description={
|
||
title
|
||
? `将删除「${title}」。列表不再展示;原链接会显示删除类型,选「其他」时还会展示补充理由。`
|
||
: "列表不再展示;原链接会显示删除类型,选「其他」时还会展示补充理由。"
|
||
}
|
||
onClose={onClose}
|
||
busy={busy}
|
||
maxWidthClass="max-w-[440px]"
|
||
panelClassName="p-5"
|
||
ariaLabel="删除帖子"
|
||
footer={
|
||
<>
|
||
<button type="button" className="btn btn-line" onClick={onClose} disabled={busy}>
|
||
取消
|
||
</button>
|
||
<button type="button" className="btn btn-danger" onClick={submit} disabled={busy}>
|
||
{busy ? "删除中…" : "确认删除"}
|
||
</button>
|
||
</>
|
||
}
|
||
>
|
||
<StaffDeleteFields
|
||
deleteType={deleteType}
|
||
onTypeChange={(value) => {
|
||
setDeleteType(value);
|
||
setErr("");
|
||
if (value !== "other") setReason("");
|
||
}}
|
||
reason={reason}
|
||
onReasonChange={(value) => {
|
||
setReason(value);
|
||
setErr("");
|
||
}}
|
||
reasonId="post-delete-reason"
|
||
reasonPlaceholder="向读者说明删除原因(将展示在帖子页)"
|
||
typeHint="选「其他」时需补充理由;其余类型直接按标签展示给读者。"
|
||
reasonHint="将公开显示在帖子专用页与作者通知中。"
|
||
/>
|
||
{err ? (
|
||
<p className="mt-2 text-[12px]" style={{ color: "var(--danger)" }}>
|
||
{err}
|
||
</p>
|
||
) : null}
|
||
</Modal>
|
||
);
|
||
}
|