From ef55d9bb24430610b60c1b77821307cd72c08c55 Mon Sep 17 00:00:00 2001 From: zwlucas Date: Sat, 25 Jul 2026 18:23:29 -0300 Subject: feat: upload of the project Signed-off-by: zwlucas --- web/src/context/ToastContext.tsx | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 web/src/context/ToastContext.tsx (limited to 'web/src/context/ToastContext.tsx') diff --git a/web/src/context/ToastContext.tsx b/web/src/context/ToastContext.tsx new file mode 100644 index 0000000..87b3894 --- /dev/null +++ b/web/src/context/ToastContext.tsx @@ -0,0 +1,71 @@ +/** + * ToastContext.tsx + * Sistema minimalista de Toast Notifications. + */ + +import { createContext, useContext, useState, useCallback, type ReactNode } from 'react'; +import { createPortal } from 'react-dom'; +import styles from './Toast.module.css'; + +type ToastType = 'info' | 'success' | 'error'; + +interface ToastData { + id: string; + message: string; + type: ToastType; +} + +interface ToastContextValue { + addToast: (message: string, type?: ToastType) => void; +} + +const ToastContext = createContext(null); + +export function ToastProvider({ children }: { children: ReactNode }) { + const [toasts, setToasts] = useState([]); + + const addToast = useCallback((message: string, type: ToastType = 'info') => { + const id = Math.random().toString(36).substring(2, 9); + setToasts((prev) => [...prev, { id, message, type }]); + + // Remove automaticamente após 4 segundos + setTimeout(() => { + setToasts((prev) => prev.filter((t) => t.id !== id)); + }, 4000); + }, []); + + const removeToast = (id: string) => { + setToasts((prev) => prev.filter((t) => t.id !== id)); + }; + + return ( + + {children} + + {/* Portal renderiza os toasts no final do */} + {createPortal( +
+ {toasts.map((toast) => ( +
+ {toast.message} + +
+ ))} +
, + document.body + )} +
+ ); +} + +export function useToast() { + const ctx = useContext(ToastContext); + if (!ctx) throw new Error('useToast deve ser usado dentro do ToastProvider'); + return ctx; +} -- cgit v1.2.3