Files
lotteryAdmin/src/hooks/use-confirm-action.tsx

68 lines
1.7 KiB
TypeScript

"use client";
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { ConfirmActionDialog } from "@/components/admin/confirm-action-dialog";
export type ConfirmActionRequest = {
title: string;
description: string;
confirmLabel?: string;
cancelLabel?: string;
confirmVariant?: "default" | "destructive";
onConfirm: () => void | Promise<void>;
};
export function useConfirmAction() {
const { t } = useTranslation("common");
const [pending, setPending] = useState<ConfirmActionRequest | null>(null);
const [busy, setBusy] = useState(false);
const request = useCallback((req: ConfirmActionRequest) => {
setPending(req);
}, []);
const dismiss = useCallback(() => {
if (!busy) {
setPending(null);
}
}, [busy]);
const confirm = useCallback(async () => {
if (!pending || busy) {
return;
}
setBusy(true);
try {
await pending.onConfirm();
setPending(null);
} finally {
setBusy(false);
}
}, [pending, busy]);
const ConfirmDialog = useCallback(
() => (
<ConfirmActionDialog
open={pending !== null}
onOpenChange={(open) => {
if (!open) {
dismiss();
}
}}
title={pending?.title ?? ""}
description={pending?.description ?? ""}
confirmLabel={pending?.confirmLabel ?? t("confirm.confirm")}
cancelLabel={pending?.cancelLabel ?? t("confirm.cancel")}
confirmVariant={pending?.confirmVariant ?? "destructive"}
busy={busy}
onConfirm={() => void confirm()}
/>
),
[pending, busy, dismiss, confirm, t],
);
return { request, dismiss, busy, ConfirmDialog };
}