import React, { useEffect, useRef } from 'react'; import { AlertTriangle } from 'lucide-react'; /** * ConfirmModal — themed replacement for window.confirm(). * * Props: * open {boolean} Whether the modal is visible * title {string} Heading text (e.g. "Delete Document") * message {string|ReactNode} Body text / description * confirmText {string} Label for the confirm button (default "Confirm") * cancelText {string} Label for the cancel button (default "Cancel") * variant {"danger"|"warning"|"default"} Controls accent color (default "danger") * onConfirm {function} Called when user confirms * onCancel {function} Called when user cancels or presses Escape */ export default function ConfirmModal({ open, title = 'Confirm', message = 'Are you sure?', confirmText = 'Confirm', cancelText = 'Cancel', variant = 'danger', onConfirm, onCancel, }) { const confirmRef = useRef(null); // Focus the confirm button when the modal opens and handle Escape key useEffect(() => { if (!open) return; // Small delay so the DOM is painted before we focus const timer = setTimeout(() => confirmRef.current?.focus(), 50); const handleKey = (e) => { if (e.key === 'Escape') onCancel?.(); }; document.addEventListener('keydown', handleKey); return () => { clearTimeout(timer); document.removeEventListener('keydown', handleKey); }; }, [open, onCancel]); if (!open) return null; const accentMap = { danger: { color: '#EF4444', bg: 'rgba(239,68,68,0.10)', bgHover: 'rgba(239,68,68,0.18)', border: 'rgba(239,68,68,0.3)' }, warning: { color: '#F59E0B', bg: 'rgba(245,158,11,0.10)', bgHover: 'rgba(245,158,11,0.18)', border: 'rgba(245,158,11,0.3)' }, default: { color: '#0EA5E9', bg: 'rgba(14,165,233,0.10)', bgHover: 'rgba(14,165,233,0.18)', border: 'rgba(14,165,233,0.3)' }, }; const accent = accentMap[variant] || accentMap.danger; return (
{ if (e.target === e.currentTarget) onCancel?.(); }} >
{/* Header */}
{title}
{/* Body */}
{message}
{/* Actions */}
); }