Files
n3wt-school/Front-End/src/components/FlashNotification.js

86 lines
2.5 KiB
JavaScript

import { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { X, CheckCircle, AlertCircle, Info, AlertTriangle } from 'lucide-react';
import { errorMessages } from '@/utils/errorCodes';
const typeStyles = {
success: {
icon: <CheckCircle className="h-6 w-6 text-green-500" />,
bg: 'bg-green-300',
},
error: {
icon: <AlertCircle className="h-6 w-6 text-red-500" />,
bg: 'bg-red-300',
},
info: {
icon: <Info className="h-6 w-6 text-blue-500" />,
bg: 'bg-blue-300',
},
warning: {
icon: <AlertTriangle className="h-6 w-6 text-yellow-500" />,
bg: 'bg-yellow-300',
},
};
export default function FlashNotification({
displayPeriod = 5000,
title,
message,
type = 'info',
errorCode,
onClose,
}) {
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
setIsVisible(true);
}, [message, type, errorCode, onClose]);
useEffect(() => {
if (type !== 'error') {
const timer = setTimeout(() => {
setIsVisible(false); // Déclenche la disparition
setTimeout(onClose, 300); // Appelle onClose après l'animation
}, displayPeriod);
return () => clearTimeout(timer);
}
// Pour les erreurs, pas de timeout : la notification reste affichée
}, [onClose, displayPeriod, type]);
if (!message || !isVisible) return null;
const { icon, bg } = typeStyles[type] || typeStyles.info;
return (
<motion.div
initial={{ opacity: 0, x: 50 }} // Animation d'entrée
animate={{ opacity: 1, x: 0 }} // Animation visible
exit={{ opacity: 0, x: 50 }} // Animation de sortie
transition={{ duration: 0.3 }} // Durée des animations
className="fixed top-5 right-5 flex items-stretch rounded-lg shadow-lg bg-white z-50 border border-gray-200"
>
{/* Rectangle gauche avec l'icône */}
<div className={`flex items-center justify-center w-14 ${bg}`}>
{icon}
</div>
{/* Zone de texte */}
<div className="flex-1 w-96 p-4">
<p className="font-bold text-black">{title}</p>
<p className="text-gray-700">{message}</p>
{type === 'error' && errorCode && (
<div className="mt-2 text-xs text-gray-500">
Code : <span className="font-mono font-bold">{errorCode}</span>
</div>
)}
</div>
{/* Bouton de fermeture */}
<button
onClick={() => setIsVisible(false)}
className="text-gray-500 hover:text-gray-700 focus:outline-none p-2"
>
<X className="h-5 w-5" />
</button>
</motion.div>
);
}