73 lines
1.6 KiB
TypeScript
73 lines
1.6 KiB
TypeScript
|
|
import { Button } from "@repo/shadcn-ui/components/button";
|
||
|
|
import { useState } from "react";
|
||
|
|
|
||
|
|
import { FormActions, FormBody, FormDialog } from "./form-dialog";
|
||
|
|
|
||
|
|
export function ConfirmDeleteDialog({
|
||
|
|
open,
|
||
|
|
onOpenChange,
|
||
|
|
title,
|
||
|
|
description,
|
||
|
|
cancelLabel,
|
||
|
|
confirmLabel,
|
||
|
|
pendingLabel,
|
||
|
|
errorLabel,
|
||
|
|
onConfirm,
|
||
|
|
}: {
|
||
|
|
open: boolean;
|
||
|
|
onOpenChange: (open: boolean) => void;
|
||
|
|
title: string;
|
||
|
|
description: string;
|
||
|
|
cancelLabel: string;
|
||
|
|
confirmLabel: string;
|
||
|
|
pendingLabel: string;
|
||
|
|
errorLabel: string;
|
||
|
|
onConfirm: () => Promise<unknown>;
|
||
|
|
}) {
|
||
|
|
const [pending, setPending] = useState(false);
|
||
|
|
const [failed, setFailed] = useState(false);
|
||
|
|
return (
|
||
|
|
<FormDialog
|
||
|
|
cancelLabel={cancelLabel}
|
||
|
|
formActions
|
||
|
|
onOpenChange={(value) => {
|
||
|
|
if (!pending) {
|
||
|
|
setFailed(false);
|
||
|
|
onOpenChange(value);
|
||
|
|
}
|
||
|
|
}}
|
||
|
|
open={open}
|
||
|
|
title={title}
|
||
|
|
>
|
||
|
|
<FormBody>
|
||
|
|
<p>{description}</p>
|
||
|
|
{failed && (
|
||
|
|
<p className="text-destructive" role="alert">
|
||
|
|
{errorLabel}
|
||
|
|
</p>
|
||
|
|
)}
|
||
|
|
</FormBody>
|
||
|
|
<FormActions>
|
||
|
|
<Button
|
||
|
|
disabled={pending}
|
||
|
|
onClick={async () => {
|
||
|
|
setPending(true);
|
||
|
|
setFailed(false);
|
||
|
|
try {
|
||
|
|
await onConfirm();
|
||
|
|
onOpenChange(false);
|
||
|
|
} catch {
|
||
|
|
setFailed(true);
|
||
|
|
} finally {
|
||
|
|
setPending(false);
|
||
|
|
}
|
||
|
|
}}
|
||
|
|
variant="destructive"
|
||
|
|
>
|
||
|
|
{pending ? pendingLabel : confirmLabel}
|
||
|
|
</Button>
|
||
|
|
</FormActions>
|
||
|
|
</FormDialog>
|
||
|
|
);
|
||
|
|
}
|