feat: Preparation des modèles Settings pour l'enregistrement SMTP [#17]

This commit is contained in:
Luc SORIGNET
2025-05-05 09:25:07 +02:00
parent 99a882a64a
commit eda6f587fb
33 changed files with 468 additions and 74 deletions

View File

@ -0,0 +1,70 @@
import { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { X, CheckCircle, AlertCircle, Info, AlertTriangle } from 'lucide-react';
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({
title,
message,
type = 'info',
onClose,
}) {
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(false); // Déclenche la disparition
setTimeout(onClose, 300); // Appelle onClose après l'animation
}, 3000); // Notification visible pendant 3 secondes
return () => clearTimeout(timer);
}, [onClose]);
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 w-96 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-12 ${bg}`}>
{icon}
</div>
{/* Zone de texte */}
<div className="flex-1 p-4">
<p className="font-bold text-black">{title}</p>
<p className="text-gray-700">{message}</p>
</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>
);
}