import { useState, type ReactElement, type ReactNode } from "react" import { Loader2 } from "lucide-react" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "~/components/ui/alert-dialog" type Props = { /** The element that opens the dialog — a Button or bare button. */ trigger: ReactElement title: string description?: ReactNode confirmLabel?: string destructive?: boolean onConfirm: () => Promise | void } /** Branded confirm dialog. Replaces `window.confirm` — branded buttons, * keyboard-trapped, dismisses on Esc, awaits async confirm handlers * so we can show a spinner while the operation runs. */ export function ConfirmDialog({ trigger, title, description, confirmLabel = "Confirm", destructive, onConfirm, }: Props) { const [open, setOpen] = useState(false) const [busy, setBusy] = useState(false) const [error, setError] = useState(null) async function handleConfirm() { setBusy(true) setError(null) try { await onConfirm() setOpen(false) } catch (e) { setError(e instanceof Error ? e.message : String(e)) } finally { setBusy(false) } } return ( { if (!busy) setOpen(v) }} > {title} {description ? ( {description} ) : null} {error ?

{error}

: null} Cancel { e.preventDefault() void handleConfirm() }} disabled={busy} className={ destructive ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : undefined } > {busy ? ( <> Working… ) : ( confirmLabel )}
) }