Files
instrucoes_gerais/clube67/newwhats.local/frontend/store/notificationStore.ts
T

73 lines
2.3 KiB
TypeScript

import { create } from 'zustand'
export type NotificationType = 'info' | 'warning' | 'success' | 'error'
export interface Notification {
id: string
tag?: string
message: string
type: NotificationType
durationMs?: number
}
interface NotificationState {
notifications: Notification[]
timers: Record<string, ReturnType<typeof setTimeout>>
add: (msg: string, type?: NotificationType, durationMs?: number, tag?: string) => void
remove: (id: string) => void
}
export const useNotificationStore = create<NotificationState>((set, get) => ({
notifications: [],
timers: {},
add(msg, type = 'info', durationMs = 5000, tag) {
const { timers } = get()
// Se tem tag, remove a notificação anterior com a mesma tag (sem animação de saída)
// e cancela o timer dela, para não empilhar
if (tag) {
const existing = get().notifications.find((n) => n.tag === tag)
if (existing) {
if (timers[existing.id]) {
clearTimeout(timers[existing.id])
set((s) => {
const { [existing.id]: _, ...rest } = s.timers
return { timers: rest }
})
}
set((s) => ({ notifications: s.notifications.filter((n) => n.tag !== tag) }))
}
}
const id = tag ?? `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`
set((s) => ({ notifications: [...s.notifications, { id, tag, message: msg, type, durationMs }] }))
if (durationMs > 0) {
const timer = setTimeout(() => {
set((s) => ({
notifications: s.notifications.filter((n) => n.id !== id),
timers: Object.fromEntries(Object.entries(s.timers).filter(([k]) => k !== id)),
}))
}, durationMs)
set((s) => ({ timers: { ...s.timers, [id]: timer } }))
}
},
remove(id) {
const { timers } = get()
if (timers[id]) {
clearTimeout(timers[id])
set((s) => {
const { [id]: _, ...rest } = s.timers
return { timers: rest }
})
}
set((s) => ({ notifications: s.notifications.filter((n) => n.id !== id) }))
},
}))
/** Atalho para usar fora de componentes React (stores, services, etc.) */
export const notify = (msg: string, type?: NotificationType, durationMs?: number, tag?: string) =>
useNotificationStore.getState().add(msg, type, durationMs, tag)