Fixed notifications button
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
import { createContext, useContext, useState, useCallback, useMemo, useEffect, ReactNode } from "react"
|
||||
import { Notification, NotificationType } from "@/types"
|
||||
import { leads } from "@/data/leads"
|
||||
|
||||
interface NotificationContextValue {
|
||||
notifications: Notification[]
|
||||
@@ -16,62 +15,29 @@ interface NotificationContextValue {
|
||||
|
||||
const NotificationContext = createContext<NotificationContextValue | null>(null)
|
||||
|
||||
function generateId(): string {
|
||||
return `notif-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`
|
||||
}
|
||||
|
||||
function seedInitialNotifications(): Notification[] {
|
||||
const result: Notification[] = []
|
||||
|
||||
const recentLeads = leads.slice(0, 5)
|
||||
recentLeads.forEach((lead) => {
|
||||
result.push({
|
||||
id: generateId(),
|
||||
type: "lead_created",
|
||||
title: "New Lead Created",
|
||||
description: `${lead.companyName} — ${lead.contactName}`,
|
||||
timestamp: lead.createdAt,
|
||||
read: false,
|
||||
link: `/leads/${lead.id}`,
|
||||
})
|
||||
})
|
||||
|
||||
const statusChanged = leads.filter((l) => l.status !== "open").slice(0, 3)
|
||||
statusChanged.forEach((lead) => {
|
||||
result.push({
|
||||
id: generateId(),
|
||||
type: "lead_status_changed",
|
||||
title: "Lead Status Updated",
|
||||
description: `${lead.companyName} moved to ${lead.status}`,
|
||||
timestamp: lead.updatedAt,
|
||||
read: false,
|
||||
link: `/leads/${lead.id}`,
|
||||
})
|
||||
})
|
||||
|
||||
const assignedLeads = leads.filter((l) => l.assignedUser).slice(0, 3)
|
||||
assignedLeads.forEach((lead) => {
|
||||
result.push({
|
||||
id: generateId(),
|
||||
type: "lead_assigned",
|
||||
title: "Lead Assigned",
|
||||
description: `${lead.companyName} assigned to ${lead.assignedUser!.name}`,
|
||||
timestamp: lead.updatedAt,
|
||||
read: false,
|
||||
link: `/leads/${lead.id}`,
|
||||
})
|
||||
})
|
||||
|
||||
result.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export function NotificationProvider({ children }: { children: ReactNode }) {
|
||||
const [notifications, setNotifications] = useState<Notification[]>(seedInitialNotifications)
|
||||
|
||||
const [notifications, setNotifications] = useState<Notification[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [unreadChatCount, setUnreadChatCount] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchNotifications() {
|
||||
try {
|
||||
const res = await fetch("/api/notifications")
|
||||
if (!res.ok) return
|
||||
const data = await res.json()
|
||||
if (data.notifications) {
|
||||
setNotifications(data.notifications)
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
fetchNotifications()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
async function fetchUnread() {
|
||||
@@ -99,9 +65,9 @@ export function NotificationProvider({ children }: { children: ReactNode }) {
|
||||
)
|
||||
|
||||
const addNotification = useCallback(
|
||||
(type: NotificationType, title: string, description: string, link?: string) => {
|
||||
async (type: NotificationType, title: string, description: string, link?: string) => {
|
||||
const notif: Notification = {
|
||||
id: generateId(),
|
||||
id: `temp-${Date.now()}`,
|
||||
type,
|
||||
title,
|
||||
description,
|
||||
@@ -110,22 +76,48 @@ export function NotificationProvider({ children }: { children: ReactNode }) {
|
||||
link,
|
||||
}
|
||||
setNotifications((prev) => [notif, ...prev])
|
||||
try {
|
||||
await fetch("/api/notifications", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ type, title, description, link }),
|
||||
})
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
const markAsRead = useCallback((id: string) => {
|
||||
const markAsRead = useCallback(async (id: string) => {
|
||||
if (id.startsWith("temp-")) return
|
||||
setNotifications((prev) =>
|
||||
prev.map((n) => (n.id === id ? { ...n, read: true } : n))
|
||||
)
|
||||
try {
|
||||
await fetch(`/api/notifications/${id}`, { method: "PATCH" })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, [])
|
||||
|
||||
const markAllAsRead = useCallback(() => {
|
||||
const markAllAsRead = useCallback(async () => {
|
||||
setNotifications((prev) => prev.map((n) => ({ ...n, read: true })))
|
||||
try {
|
||||
await fetch("/api/notifications", { method: "PATCH" })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, [])
|
||||
|
||||
const dismiss = useCallback((id: string) => {
|
||||
const dismiss = useCallback(async (id: string) => {
|
||||
setNotifications((prev) => prev.filter((n) => n.id !== id))
|
||||
if (id.startsWith("temp-")) return
|
||||
try {
|
||||
await fetch(`/api/notifications/${id}`, { method: "DELETE" })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user