import { AlertCircle, CheckCircle } from "lucide-react"; import { useTranslate } from "ra-core"; import * as React from "react"; import { type ComponentType, type MouseEventHandler, useCallback } from "react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; /** * Generic confirmation dialog component for destructive actions. * * Displays a dialog with customizable title, content, and action buttons. * Used internally for delete operations and other confirmations. * Supports custom icons, button labels, and loading states. * * @see {@link https://marmelab.com/shadcn-admin-kit/docs/confirm Confirm documentation} * * @example * import { useState } from "react"; * import { useDelete, useRecordContext, useResourceContext, useRedirect } from "ra-core"; * import { Button } from "@/components/ui/button"; * import { Confirm } from "@/components/admin/confirm"; * * const DeleteButton = () => { * const resource = useResourceContext(); * const record = useRecordContext(); * const [isOpen, setIsOpen] = useState(false); * const [deleteOne, { isPending }] = useDelete(); * const redirect = useRedirect(); * * const handleDelete = () => { * deleteOne( * resource, * { id: record?.id, previousData: record }, * { * onSuccess: () => { * setIsOpen(false); * redirect("list", resource); * }, * }, * ); * }; * * return ( * <> * * setIsOpen(false)} * loading={isPending} * /> * * ); * }; */ export const Confirm = (props: ConfirmProps) => { const { className, isOpen = false, loading, title, content, cancel = "ra.action.cancel", confirm = "ra.action.confirm", confirmColor = "primary", ConfirmIcon = CheckCircle, CancelIcon = AlertCircle, onClose, onConfirm, translateOptions = {}, titleTranslateOptions = translateOptions, contentTranslateOptions = translateOptions, ...rest } = props; const translate = useTranslate(); const handleConfirm = useCallback( (e: React.MouseEvent) => { e.stopPropagation(); onConfirm(e); }, [onConfirm], ); const handleClick = useCallback((e: React.MouseEvent) => { e.stopPropagation(); }, []); return ( onClose()}> {typeof title === "string" ? translate(title, { _: title, ...titleTranslateOptions }) : title} {typeof content === "string" ? ( {translate(content, { _: content, ...contentTranslateOptions, })} ) : ( content )} ); }; export interface ConfirmProps { cancel?: string; className?: string; confirm?: string; confirmColor?: "primary" | "warning"; ConfirmIcon?: ComponentType; CancelIcon?: ComponentType; content?: React.ReactNode; isOpen?: boolean; loading?: boolean; onClose: () => void; onConfirm: MouseEventHandler; title: React.ReactNode; /** * @deprecated use `titleTranslateOptions` and `contentTranslateOptions` instead */ translateOptions?: object; titleTranslateOptions?: object; contentTranslateOptions?: object; }