"use client"; import React, { useEffect, useState } from 'react'; import { useNotificationsStore } from '@/stores/notifications-store'; import { X } from 'lucide-react'; const NotificationsToast = () => { const { notifications, dismissNotification } = useNotificationsStore(); return (
{notifications.map((notification) => ( ))}
); }; interface NotificationItemProps { notification: { id: string; message: string; type: 'error' | 'warning' | 'info'; duration: number; }; onDismiss: (id: string) => void; } const NotificationItem: React.FC = ({ notification, onDismiss }) => { const [show, setShow] = useState(false); useEffect(() => { // Animate in const showTimer = setTimeout(() => setShow(true), 50); // Small delay to ensure transition triggers // Schedule hide const hideTimer = setTimeout(() => { setShow(false); }, notification.duration); return () => { clearTimeout(showTimer); clearTimeout(hideTimer); }; }, [notification.duration]); useEffect(() => { if (!show) { // If show is false (either initially or after hide animation started) // Wait for animation to complete before unmounting const unmountTimer = setTimeout(() => { // Check again because the component might receive new props or be unmounted by parent already // This check is primarily if a notification was dismissed manually very quickly if (!show) { onDismiss(notification.id); } }, 500); // This duration should match the Tailwind CSS transition duration for exit return () => clearTimeout(unmountTimer); } }, [show, notification.id, onDismiss]); let bgColor = 'bg-blue-500'; let borderColor = 'border-blue-700'; let textColor = 'text-white'; if (notification.type === 'error') { bgColor = 'bg-red-500'; borderColor = 'border-red-700'; } else if (notification.type === 'warning') { bgColor = 'bg-yellow-500'; borderColor = 'border-yellow-700'; textColor = 'text-gray-800'; } return (

{notification.message}

); }; export default NotificationsToast; // Add this to your global CSS (e.g., globals.css or tailwind.config.js if using plugins) /* @keyframes slideInRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .animate-slide-in-right { animation: slideInRight 0.3s ease-out forwards; } */