import React, { useEffect } from 'react';
import { motion } from 'framer-motion';
import { CheckCircle, XCircle, Info, AlertTriangle, X } from 'lucide-react';
import styles from './Toast.module.css';
export type ToastType = 'success' | 'error' | 'info' | 'warning';
export interface ToastProps {
id: string;
type: ToastType;
message: string;
duration?: number;
onClose: (id: string) => void;
}
const icons = {
success: CheckCircle,
error: XCircle,
info: Info,
warning: AlertTriangle,
};
export const Toast: React.FC<ToastProps> = ({
id,
type,
message,
duration = 5000,
onClose,
}) => {
const Icon = icons[type];
useEffect(() => {
if (duration > 0) {
const timer = setTimeout(() => {
onClose(id);
}, duration);
return () => clearTimeout(timer);
}
}, [id, duration, onClose]);
return (
<motion.div
layout
initial={{ opacity: 0, y: 50, scale: 0.9 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, scale: 0.9, transition: { duration: 0.2 } }}
className={`${styles.toast} ${styles[`toast_${type}`]}`}
>
<div className={`${styles.icon} ${styles[`icon_${type}`]}`}>
<Icon size={20} />
</div>
<div className={styles.message}>{message}</div>
<button className={styles.closeButton} onClick={() => onClose(id)}>
<X size={16} />
</button>
{duration > 0 && (
<div className={styles.progressBar}>
<motion.div
className={styles.progressFill}
initial={{ scaleX: 1 }}
animate={{ scaleX: 0 }}
transition={{ duration: duration / 1000, ease: 'linear' }}
/>
</div>
)}
</motion.div>
);
};