import React, { useState } from 'react'; // Types for notification modal export interface NotificationModalProps { isOpen: boolean; title?: string; message: string; onConfirm?: () => void; onCancel?: () => void; type?: 'info' | 'success' | 'warning' | 'error'; confirmButtonText?: string; cancelButtonText?: string; } // Icon components for different types const Icons = { info: (props: React.SVGProps) => ( ), success: (props: React.SVGProps) => ( ), warning: (props: React.SVGProps) => ( ), error: (props: React.SVGProps) => ( ), }; // Default props const defaultProps: Partial = { title: 'Thông báo', type: 'info', confirmButtonText: 'OK', cancelButtonText: 'Hủy', }; export const NotificationModal: React.FC = ({ isOpen, title = defaultProps.title, message, onConfirm, onCancel, type = defaultProps.type, confirmButtonText = defaultProps.confirmButtonText, cancelButtonText = defaultProps.cancelButtonText, }) => { const [isAnimating, setIsAnimating] = useState(false); // Get colors based on type const getTypeStyles = () => { switch (type) { case 'success': return { bg: '#d4edda', border: '#c3e6cb', text: '#155724' }; case 'warning': return { bg: '#fff3cd', border: '#ffeeba', text: '#856404' }; case 'error': return { bg: '#f8d7da', border: '#f5c6cb', text: '#721c24' }; default: return { bg: '#e2e3e5', border: '#d6d8db', text: '#383d41' }; } }; const styles = getTypeStyles(); // Animation classes based on state const getAnimationClass = () => { if (!isOpen) return 'opacity-0 translate-y-4'; if (isAnimating && onCancel) return 'animate-fade-out'; return 'animate-fade-in'; }; // Handle confirm click const handleConfirm = () => { setIsAnimating(true); onConfirm?.(); setTimeout(() => setIsAnimating(false), 300); }; // Handle cancel click const handleCancel = () => { setIsAnimating(true); onCancel?.(); setTimeout(() => setIsAnimating(false), 300); }; if (!isOpen) return null; return (
{/* Header */}
{type === 'success' && } {type === 'warning' && } {type === 'error' && } {type === 'info' && }
{/* Body */}
{/* Footer */}
{onCancel && ( )} {onConfirm && ( )}
); }; // Hook for easy usage without props management export const useNotificationModal = () => { const [modalState, setModalState] = useState<{ isOpen: boolean; title?: string; message: string; type?: 'info' | 'success' | 'warning' | 'error'; onConfirm?: () => void; onCancel?: () => void; } | null>(null); const openModal = ( title: string, message: string, type: 'info' | 'success' | 'warning' | 'error' = 'info', onConfirm?: () => void, onCancel?: () => void, ) => { setModalState({ isOpen: true, title, message, type, onConfirm, onCancel, }); // Auto-close after 5 seconds if no confirm action const timer = setTimeout(() => { if (onCancel) { setModalState((prev) => ({ ...prev, isOpen: false })); } }, 5000); return () => clearTimeout(timer); }; const closeModal = () => { setModalState((prev) => prev ? { ...prev, isOpen: false } : null); }; return { modalState, openModal, closeModal, }; }; export default NotificationModal;