import React, { createContext, useContext, useState, useCallback, useRef } from 'react'; import { View, Text, Animated, TouchableOpacity, StyleSheet } from 'react-native'; import { CheckCircle, AlertTriangle, XCircle, X } from 'lucide-react-native'; export type ToastType = 'success' | 'warning' | 'error'; interface Toast { id: string; message: string; type: ToastType; } interface ToastContextValue { showToast: (message: string, type?: ToastType) => void; } const ToastContext = createContext({ showToast: () => {} }); const COLORS: Record = { success: '#4CAF7D', warning: '#D4A843', error: '#C0392B', }; function ToastItem({ toast, onDismiss }: { toast: Toast; onDismiss: (id: string) => void }) { const opacity = useRef(new Animated.Value(0)).current; const translateY = useRef(new Animated.Value(-20)).current; React.useEffect(() => { Animated.parallel([ Animated.timing(opacity, { toValue: 1, duration: 250, useNativeDriver: true }), Animated.timing(translateY, { toValue: 0, duration: 250, useNativeDriver: true }), ]).start(); const timer = setTimeout(() => dismiss(), 3000); return () => clearTimeout(timer); }, []); function dismiss() { Animated.parallel([ Animated.timing(opacity, { toValue: 0, duration: 200, useNativeDriver: true }), Animated.timing(translateY, { toValue: -20, duration: 200, useNativeDriver: true }), ]).start(() => onDismiss(toast.id)); } const color = COLORS[toast.type]; const Icon = toast.type === 'success' ? CheckCircle : toast.type === 'warning' ? AlertTriangle : XCircle; return ( {toast.message} ); } export function ToastProvider({ children }: { children: React.ReactNode }) { const [toasts, setToasts] = useState([]); const counterRef = useRef(0); const showToast = useCallback((message: string, type: ToastType = 'success') => { const id = `toast-${++counterRef.current}-${Date.now()}`; setToasts((prev) => [...prev, { id, message, type }]); }, []); const dismissToast = useCallback((id: string) => { setToasts((prev) => prev.filter((t) => t.id !== id)); }, []); return ( {children} {toasts.map((toast) => ( ))} ); } export function useToast(): ToastContextValue { return useContext(ToastContext); } const styles = StyleSheet.create({ container: { position: 'absolute', bottom: 90, left: 16, right: 16, gap: 8, zIndex: 9999, }, toast: { flexDirection: 'row', alignItems: 'center', borderRadius: 12, paddingVertical: 12, paddingHorizontal: 14, gap: 10, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 4, elevation: 6, }, message: { flex: 1, color: 'white', fontSize: 14, fontWeight: '500', lineHeight: 20, }, });