46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
import { useEffect } from 'react';
|
||
import type { ToastType } from '../../stores/uiStore';
|
||
|
||
interface ToastProps {
|
||
message: string;
|
||
type: ToastType;
|
||
onClose: () => void;
|
||
duration?: number;
|
||
}
|
||
|
||
export function Toast({ message, type, onClose, duration = 4000 }: ToastProps) {
|
||
useEffect(() => {
|
||
const timer = setTimeout(onClose, duration);
|
||
return () => clearTimeout(timer);
|
||
}, [duration, onClose]);
|
||
|
||
const bgColors = {
|
||
success: 'bg-green-500 dark:bg-green-600',
|
||
error: 'bg-red-500 dark:bg-red-600',
|
||
info: 'bg-blue-500 dark:bg-blue-600',
|
||
warning: 'bg-yellow-500 dark:bg-yellow-600',
|
||
};
|
||
|
||
const icons = {
|
||
success: '✓',
|
||
error: '✕',
|
||
info: 'ℹ',
|
||
warning: '⚠',
|
||
};
|
||
|
||
return (
|
||
<div
|
||
className={`${bgColors[type]} text-white px-6 py-4 rounded-lg shadow-lg flex items-center gap-3 min-w-[300px] max-w-md animate-slide-in`}
|
||
>
|
||
<div className="text-2xl">{icons[type]}</div>
|
||
<div className="flex-1 text-sm font-medium">{message}</div>
|
||
<button
|
||
onClick={onClose}
|
||
className="text-white hover:text-gray-200 text-xl font-bold leading-none"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|