/** * Reusable confirmation dialog component */ import React, { useEffect, useId, useRef } from 'react'; import { Dialog, DialogContent, DialogTitle } from './ui/dialog'; export interface ConfirmDialogProps { isOpen: boolean; onClose: () => void; onConfirm?: () => void; title: string; message: React.ReactNode; subMessage?: React.ReactNode; confirmText?: string; cancelText?: string; variant?: 'info' | 'warning'; showCancel?: boolean; wide?: boolean; } export const ConfirmDialog: React.FC = ({ isOpen, onClose, onConfirm, title, message, subMessage, confirmText = 'Got it', cancelText = 'Cancel', variant = 'info', showCancel = false, wide = false, }) => { const descriptionId = useId(); const cancelButtonRef = useRef(null); const confirmButtonRef = useRef(null); useEffect(() => { if (!isOpen) return; const handleKey = (event: KeyboardEvent) => { if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) { event.preventDefault(); event.stopPropagation(); if (onConfirm) onConfirm(); else onClose(); } }; window.addEventListener('keydown', handleKey); return () => window.removeEventListener('keydown', handleKey); }, [isOpen, onConfirm, onClose]); if (!isOpen) return null; const iconColors = { info: 'bg-accent/20 text-accent', warning: 'bg-warning/20 text-warning', }; const buttonColors = { info: 'bg-primary text-primary-foreground [@media(hover:hover)_and_(pointer:fine)]:hover:opacity-90', warning: 'bg-warning text-warning-foreground [@media(hover:hover)_and_(pointer:fine)]:hover:opacity-90', }; const icons = { info: ( ), warning: ( ), }; return ( { if (!open) onClose(); }} > (showCancel ? cancelButtonRef.current : confirmButtonRef.current)} backdropClassName="bg-background/80 backdrop-blur-sm" className={`bg-card text-foreground rounded-xl shadow-2xl p-6 transition-none ${wide ? 'max-w-md' : 'max-w-sm'}`} data-plannotator-confirm-dialog="true" >
{icons[variant]}
{title}
{message}
{subMessage && (
{subMessage}
)} {!subMessage &&
}
{showCancel && ( )}
); };