pelagia-portal/App/components/ui/confirm-delete-button.tsx
2026-05-18 23:18:58 +05:30

60 lines
1.9 KiB
TypeScript

"use client";
import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
type ActionResult = { ok: true } | { error: string };
export function ConfirmDeleteButton({
onDelete,
label,
}: {
onDelete: () => Promise<ActionResult>;
label: string;
}) {
const router = useRouter();
const [confirming, setConfirming] = useState(false);
const [error, setError] = useState("");
const [isPending, startTransition] = useTransition();
if (confirming) {
return (
<span className="inline-flex items-center gap-1.5 flex-wrap">
<span className="text-xs text-neutral-500 whitespace-nowrap">Delete {label}?</span>
<button
onClick={() =>
startTransition(async () => {
const result = await onDelete();
if ("error" in result) {
setError(result.error);
setConfirming(false);
} else {
router.refresh();
}
})
}
disabled={isPending}
className="rounded border border-danger-400 bg-danger-600 px-2 py-0.5 text-xs font-semibold text-white hover:bg-danger-700 disabled:opacity-50 whitespace-nowrap transition-colors"
>
{isPending ? "Deleting…" : "Confirm"}
</button>
<button
onClick={() => { setConfirming(false); setError(""); }}
className="rounded border border-neutral-300 bg-white px-2 py-0.5 text-xs text-neutral-600 hover:bg-neutral-50 whitespace-nowrap transition-colors"
>
Cancel
</button>
{error && <span className="text-xs text-danger-600 block w-full">{error}</span>}
</span>
);
}
return (
<button
onClick={() => setConfirming(true)}
className="rounded border border-danger-200 bg-white px-2.5 py-1 text-xs font-medium text-danger-600 hover:bg-danger-50 hover:border-danger-300 transition-colors"
>
Delete
</button>
);
}