66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
export function PairingCancelButton({
|
|
pairingId,
|
|
onCancelled,
|
|
}: {
|
|
pairingId: string;
|
|
onCancelled?: () => void;
|
|
}) {
|
|
const router = useRouter();
|
|
const [busy, setBusy] = useState(false);
|
|
const [error, setError] = useState("");
|
|
|
|
async function cancel() {
|
|
if (
|
|
!window.confirm(
|
|
"取消后这枚配对凭证立即失效并释放占位。若 daemon 正在认领,最终状态以主机列表为准。确定取消?",
|
|
)
|
|
) {
|
|
return;
|
|
}
|
|
setBusy(true);
|
|
setError("");
|
|
try {
|
|
const response = await fetch("/api/hosts/pairing/cancel", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ pairingId }),
|
|
});
|
|
const body = (await response.json()) as { message?: string };
|
|
if (!response.ok) {
|
|
throw new Error(body.message || "取消配对请求失败");
|
|
}
|
|
onCancelled?.();
|
|
router.refresh();
|
|
} catch (cancelError) {
|
|
setError(
|
|
cancelError instanceof Error ? cancelError.message : "取消配对请求失败",
|
|
);
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="pairing-cancel-action">
|
|
<button
|
|
className="button button-secondary"
|
|
type="button"
|
|
onClick={cancel}
|
|
disabled={busy}
|
|
>
|
|
{busy ? "正在取消…" : "取消配对"}
|
|
</button>
|
|
{error && (
|
|
<small className="form-error" role="alert">
|
|
{error}
|
|
</small>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|