88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { X, CheckCircle, AlertCircle, Info } from 'lucide-react';
|
|
|
|
interface NotificationModalProps {
|
|
isOpen: boolean;
|
|
title?: string;
|
|
message?: string;
|
|
type?: 'success' | 'error' | 'info';
|
|
onConfirm: () => void;
|
|
}
|
|
|
|
/**
|
|
* NotificationModal - Component hiển thị thông báo phản hồi cho người dùng
|
|
*/
|
|
export const NotificationModal: React.FC<NotificationModalProps> = ({
|
|
isOpen,
|
|
title = 'Thông báo',
|
|
message,
|
|
type = 'info',
|
|
onConfirm,
|
|
}) => {
|
|
if (!isOpen) return null;
|
|
|
|
const icons = {
|
|
success: <CheckCircle className="w-12 h-12 text-green-500" />,
|
|
error: <AlertCircle className="w-12 h-12 text-red-500" />,
|
|
info: <Info className="w-12 h-12 text-blue-500" />,
|
|
};
|
|
|
|
const colors = {
|
|
success: 'bg-green-600 hover:bg-green-700 shadow-green-100',
|
|
error: 'bg-red-600 hover:bg-red-700 shadow-red-100',
|
|
info: 'bg-blue-600 hover:bg-blue-700 shadow-blue-100',
|
|
};
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-[3000] flex items-center justify-center p-4">
|
|
{/* Backdrop */}
|
|
<div className="absolute inset-0 bg-gray-900/60 backdrop-blur-sm animate-in fade-in duration-200" onClick={onConfirm} />
|
|
|
|
{/* Modal Content */}
|
|
<div className="relative w-full max-w-sm bg-white rounded-[32px] shadow-2xl overflow-hidden p-8 text-center animate-in zoom-in-95 duration-200">
|
|
<div className="flex justify-center mb-5">
|
|
{icons[type]}
|
|
</div>
|
|
|
|
<h2 className="text-xl font-black text-gray-900 mb-2">{title}</h2>
|
|
<p className="text-gray-500 text-sm leading-relaxed mb-8">
|
|
{message || "Bạn không được phép gỡ bỏ thành viên này!"}
|
|
</p>
|
|
|
|
<button
|
|
onClick={onConfirm}
|
|
className={`w-full py-4 text-white font-bold rounded-2xl transition-all shadow-lg active:scale-95 ${colors[type]}`}
|
|
>
|
|
Đã hiểu
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Custom hook để quản lý trạng thái của NotificationModal
|
|
*/
|
|
export const useNotificationModal = () => {
|
|
const [modalState, setModalState] = useState<{
|
|
isOpen: boolean;
|
|
title?: string;
|
|
message?: string;
|
|
type?: 'success' | 'error' | 'info';
|
|
}>({
|
|
isOpen: false,
|
|
title: 'Thông báo',
|
|
message: '',
|
|
type: 'info',
|
|
});
|
|
|
|
const openModal = (title: string, message: string, type: 'success' | 'error' | 'info' = 'info') => {
|
|
setModalState({ isOpen: true, title, message, type });
|
|
};
|
|
|
|
const closeModal = () => {
|
|
setModalState((prev) => ({ ...prev, isOpen: false }));
|
|
};
|
|
|
|
return { modalState, openModal, closeModal };
|
|
}; |