"use client"; import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { CheckCircle, XCircle, AlertTriangle, Info, X, } from 'lucide-react'; export type ToastType = 'success' | 'error' | 'warning' | 'info'; export interface Toast { id: string; type: ToastType; title: string; message: string; duration?: number; action?: { label: string; onClick: () => void; }; } interface ToastProps { toast: Toast; onRemove: (id: string) => void; } const ToastItem = ({ toast, onRemove }: ToastProps) => { useEffect(() => { if (toast.duration !== 0) { const timer = setTimeout(() => { setTimeout(() => onRemove(toast.id), 300); }, toast.duration || 5000); return () => clearTimeout(timer); } }, [toast.duration, toast.id, onRemove]); const getIcon = () => { switch (toast.type) { case 'success': return ; case 'error': return ; case 'warning': return ; case 'info': return ; default: return ; } }; const getColors = () => { switch (toast.type) { case 'success': return 'bg-white border-green-300 text-green-900 shadow-lg'; case 'error': return 'bg-white border-red-300 text-red-900 shadow-lg'; case 'warning': return 'bg-white border-yellow-300 text-yellow-900 shadow-lg'; case 'info': return 'bg-white border-blue-300 text-blue-900 shadow-lg'; default: return 'bg-white border-gray-300 text-gray-900 shadow-lg'; } }; return (
{getIcon()}

{toast.title}

{toast.message}

{toast.action && ( )}
{/* Progress bar */} {toast.duration !== 0 && ( )} ); }; // Toast context and provider import { createContext, useContext, useCallback } from 'react'; interface ToastContextType { addToast: (toast: Omit) => void; showToast: (toast: Omit) => void; showSuccess: (title: string, message?: string) => void; showError: (title: string, message?: string) => void; showWarning: (title: string, message?: string) => void; showInfo: (title: string, message?: string) => void; showEmailSent: (email: string) => void; showEmailError: (error: string) => void; showProjectSaved: (title: string) => void; showProjectDeleted: (title: string) => void; showImportSuccess: (count: number) => void; showImportError: (error: string) => void; } const ToastContext = createContext(undefined); export const useToast = () => { const context = useContext(ToastContext); if (!context) { throw new Error('useToast must be used within a ToastProvider'); } return context; }; export const ToastProvider = ({ children }: { children: React.ReactNode }) => { const [toasts, setToasts] = useState([]); const addToast = useCallback((toast: Omit) => { const id = Math.random().toString(36).substr(2, 9); const newToast = { ...toast, id }; setToasts(prev => [...prev, newToast]); }, []); const removeToast = useCallback((id: string) => { setToasts(prev => prev.filter(toast => toast.id !== id)); }, []); const showToast = useCallback((toast: Omit) => { addToast(toast); }, [addToast]); const showSuccess = useCallback((title: string, message?: string) => { addToast({ type: 'success', title, message: message || '', duration: 4000 }); }, [addToast]); const showError = useCallback((title: string, message?: string) => { addToast({ type: 'error', title, message: message || '', duration: 6000 }); }, [addToast]); const showWarning = useCallback((title: string, message?: string) => { addToast({ type: 'warning', title, message: message || '', duration: 5000 }); }, [addToast]); const showInfo = useCallback((title: string, message?: string) => { addToast({ type: 'info', title, message: message || '', duration: 4000 }); }, [addToast]); const showEmailSent = useCallback((email: string) => { addToast({ type: 'success', title: 'E-Mail gesendet! 📧', message: `Deine Nachricht an ${email} wurde erfolgreich versendet.`, duration: 5000, }); }, [addToast]); const showEmailError = useCallback((error: string) => { addToast({ type: 'error', title: 'E-Mail Fehler! ❌', message: `Fehler beim Senden: ${error}`, duration: 8000 }); }, [addToast]); const showProjectSaved = useCallback((title: string) => { addToast({ type: 'success', title: 'Projekt gespeichert! 💾', message: `"${title}" wurde erfolgreich in der Datenbank gespeichert.`, duration: 4000, }); }, [addToast]); const showProjectDeleted = useCallback((title: string) => { addToast({ type: 'warning', title: 'Projekt gelöscht! 🗑️', message: `"${title}" wurde aus der Datenbank entfernt.`, duration: 4000, }); }, [addToast]); const showImportSuccess = useCallback((count: number) => { addToast({ type: 'success', title: 'Import erfolgreich! 📥', message: `${count} Projekte wurden erfolgreich importiert.`, duration: 5000, }); }, [addToast]); const showImportError = useCallback((error: string) => { addToast({ type: 'error', title: 'Import Fehler! ❌', message: `Fehler beim Importieren: ${error}`, duration: 8000, }); }, [addToast]); const contextValue: ToastContextType = { addToast, showToast, showSuccess, showError, showWarning, showInfo, showEmailSent, showEmailError, showProjectSaved, showProjectDeleted, showImportSuccess, showImportError }; return ( {children} {/* Toast Container */}
{toasts.map((toast) => ( ))}
); }; export default ToastItem;