Replace immediate server action calls with ConfirmDialog modals for activate/deactivate on all 6 admin tables (users, vendors, vessels, sites, accounts, products). Delete already used DeleteConfirmDialog; this adds the same pattern for reversible toggle actions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useTransition } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
import { AdminDialog } from "@/components/ui/admin-dialog";
|
|
|
|
type ActionResult = { ok: true } | { error: string };
|
|
|
|
interface Props {
|
|
open: boolean;
|
|
onOpenChange: (v: boolean) => void;
|
|
title: string;
|
|
description: string;
|
|
confirmLabel: string;
|
|
onConfirm: () => Promise<ActionResult>;
|
|
}
|
|
|
|
export function ConfirmDialog({ open, onOpenChange, title, description, confirmLabel, onConfirm }: Props) {
|
|
const router = useRouter();
|
|
const [error, setError] = useState("");
|
|
const [isPending, startTransition] = useTransition();
|
|
|
|
function handleClose() {
|
|
if (isPending) return;
|
|
setError("");
|
|
onOpenChange(false);
|
|
}
|
|
|
|
function handleConfirm() {
|
|
setError("");
|
|
startTransition(async () => {
|
|
const result = await onConfirm();
|
|
if ("error" in result) {
|
|
setError(result.error);
|
|
} else {
|
|
onOpenChange(false);
|
|
router.refresh();
|
|
}
|
|
});
|
|
}
|
|
|
|
return (
|
|
<AdminDialog title={title} open={open} onClose={handleClose}>
|
|
<div className="space-y-4">
|
|
<p className="text-sm text-neutral-600">{description}</p>
|
|
{error && (
|
|
<p className="text-sm text-danger-700 bg-danger-50 rounded-lg px-3 py-2">{error}</p>
|
|
)}
|
|
<div className="flex justify-end gap-3 pt-1">
|
|
<button
|
|
type="button"
|
|
onClick={handleClose}
|
|
disabled={isPending}
|
|
className="rounded-lg border border-neutral-300 px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-50 disabled:opacity-60"
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onClick={handleConfirm}
|
|
disabled={isPending}
|
|
className="rounded-lg bg-primary-600 px-4 py-2 text-sm font-semibold text-white hover:bg-primary-700 disabled:opacity-60 transition-colors"
|
|
>
|
|
{isPending ? `${confirmLabel}…` : confirmLabel}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</AdminDialog>
|
|
);
|
|
}
|