"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;
}
*/