60 lines
1.7 KiB
JavaScript
60 lines
1.7 KiB
JavaScript
import { createContext, useContext, useState, useCallback, useMemo, useRef } from 'react'
|
|
|
|
const AlertContext = createContext(null)
|
|
const AlertStateContext = createContext(null)
|
|
|
|
export function AlertProvider({ children }) {
|
|
const [alerts, setAlerts] = useState([])
|
|
|
|
const removeAlert = useCallback((id) => {
|
|
setAlerts(prev => prev.filter(alert => alert.id !== id))
|
|
}, [])
|
|
|
|
const counterRef = useRef(0)
|
|
const addAlert = useCallback((message, type = 'success', duration = 4000) => {
|
|
const id = `${Date.now()}-${counterRef.current++}`
|
|
setAlerts(prev => [...prev, { id, message, type }])
|
|
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
removeAlert(id)
|
|
}, duration)
|
|
}
|
|
|
|
return id
|
|
}, [removeAlert])
|
|
|
|
const methods = useMemo(() => ({
|
|
addAlert,
|
|
removeAlert,
|
|
success: (message, duration) => addAlert(message, 'success', duration),
|
|
error: (message, duration) => addAlert(message, 'error', duration),
|
|
warning: (message, duration) => addAlert(message, 'warning', duration),
|
|
info: (message, duration) => addAlert(message, 'info', duration)
|
|
}), [addAlert, removeAlert])
|
|
|
|
return (
|
|
<AlertContext.Provider value={methods}>
|
|
<AlertStateContext.Provider value={{ alerts, removeAlert }}>
|
|
{children}
|
|
</AlertStateContext.Provider>
|
|
</AlertContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useAlert() {
|
|
const context = useContext(AlertContext)
|
|
if (!context) {
|
|
throw new Error('useAlert must be used within an AlertProvider')
|
|
}
|
|
return context
|
|
}
|
|
|
|
export function useAlertState() {
|
|
const context = useContext(AlertStateContext)
|
|
if (!context) {
|
|
throw new Error('useAlertState must be used within an AlertProvider')
|
|
}
|
|
return context
|
|
}
|