refactor(notifications): fetch from backend API instead of local generation

Rewrite store/notifications.ts to fetch via listNotifications
API and remove local generateId-based notification creation.
The store now acts as a simple cache with fetch/invalidate methods.
Header unread count reads from this API-backed cache.
This commit is contained in:
zetaloop
2026-05-01 04:21:03 +08:00
parent d76866ac3b
commit cd469d3d54
4 changed files with 84 additions and 74 deletions
+20 -32
View File
@@ -1,48 +1,36 @@
import { generateId } from "@/lib/id"
import { listNotifications } from "@/lib/api/notifications"
import type { Notification } from "@/lib/types"
import { create } from "zustand"
interface CreateNotificationInput {
type: Notification["type"]
title: string
content: string
link?: string
}
interface NotificationState {
notifications: Notification[]
addNotification: (input: CreateNotificationInput) => Notification
markAsRead: (notificationId: string) => void
markAllAsRead: () => void
loading: boolean
fetchNotifications: () => Promise<void>
setNotifications: (notifications: Notification[]) => void
markAllRead: () => void
invalidate: () => void
}
export const useNotificationStore = create<NotificationState>((set) => ({
notifications: [],
addNotification: (input) => {
const notification: Notification = {
id: generateId("notif"),
type: input.type,
title: input.title,
content: input.content,
link: input.link,
read: false,
createdAt: new Date().toISOString(),
loading: false,
fetchNotifications: async () => {
set({ loading: true })
try {
const items = await listNotifications({ offset: 0, limit: 50 })
set({ notifications: items, loading: false })
} catch {
set({ loading: false })
}
set((state) => ({
notifications: [notification, ...state.notifications],
}))
return notification
},
markAsRead: (notificationId) =>
setNotifications: (notifications) => set({ notifications }),
markAllRead: () =>
set((state) => ({
notifications: state.notifications.map((notification) =>
notification.id === notificationId ? { ...notification, read: true } : notification,
notification.read ? notification : { ...notification, read: true },
),
})),
markAllAsRead: () =>
set((state) => ({
notifications: state.notifications.map((notification) => ({ ...notification, read: true })),
})),
invalidate: () => {
set({ notifications: [] })
},
}))