import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Check, X } from 'lucide-react';
import { cn } from '@/utils/cn';
export type ToastType = 'success' | 'error' | 'info' | 'warning';
export interface ToastProps {
message: string;
type?: ToastType;
duration?: number;
onClose: () => void;
visible: boolean;
}
const Toast: React.FC<ToastProps> = ({
message,
type = 'info',
duration = 3000,
onClose,
visible,
}) => {
const { t } = useTranslation();
useEffect(() => {
if (visible) {
const timer = setTimeout(() => {
onClose();
}, duration);
return () => clearTimeout(timer);
}
}, [visible, duration, onClose]);
const icons = {
success: <Check className="w-5 h-5 text-green-500" />,
error: <X className="w-5 h-5 text-red-500" />,
info: (
<svg className="w-5 h-5 text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
),
warning: (
<svg
className="w-5 h-5 text-yellow-500"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
/>
</svg>
),
};
const bgColors = {
success: 'bg-green-50 border-green-200',
error: 'bg-red-50 border-red-200',
info: 'bg-blue-50 border-blue-200',
warning: 'bg-yellow-50 border-yellow-200',
};
const textColors = {
success: 'text-green-800',
error: 'text-red-800',
info: 'text-blue-800',
warning: 'text-yellow-800',
};
return (
<div
className={cn(
'fixed top-4 right-4 z-50 max-w-sm p-4 rounded-md shadow-lg border',
bgColors[type],
'transform transition-all duration-300 ease-in-out',
visible ? 'translate-x-0 opacity-100' : 'translate-x-full opacity-0',
)}
>
<div className="flex items-start">
<div className="flex-shrink-0">{icons[type]}</div>
<div className="ml-3">
<p className={cn('text-sm font-medium', textColors[type])}>{message}</p>
</div>
<div className="ml-auto pl-3">
<div className="-mx-1.5 -my-1.5">
<button
onClick={onClose}
className={cn(
'inline-flex rounded-md p-1.5',
`hover:bg-${type}-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-${type}-500`,
)}
>
<span className="sr-only">{t('common.dismiss')}</span>
<X className="h-5 w-5" />
</button>
</div>
</div>
</div>
</div>
);
};
export default Toast;