64 lines
2.0 KiB
TypeScript

import { createReducer } from '@reduxjs/toolkit';
import { getStaffNotifications, markNotificationRead, clearNotifications } from './thunk';
import { NotificationItem } from '@interfaces';
export interface NotificationState {
items: NotificationItem[];
loading: boolean;
error: string | null;
hasFetched: boolean;
}
const initialState: NotificationState = {
items: [],
loading: false,
error: null,
hasFetched: false,
};
export const reducers = createReducer(initialState, builder => {
builder
.addCase(getStaffNotifications.pending, acc => {
acc.loading = true;
acc.error = null;
})
.addCase(getStaffNotifications.fulfilled, (acc, action) => {
acc.loading = false;
acc.items = action.payload;
acc.error = null;
acc.hasFetched = true;
})
.addCase(getStaffNotifications.rejected, (acc, action) => {
acc.loading = false;
acc.hasFetched = true;
acc.error =
(action.payload as string) ??
action.error.message ??
'Failed to load notifications';
})
.addCase(markNotificationRead.pending, (acc, action) => {
// Optimistic update: mark as read immediately
const item = acc.items.find(i => i.id === action.meta.arg.notificationId);
if (item) {
item.isread = '1';
}
})
.addCase(markNotificationRead.rejected, (acc, action) => {
// If it fails, revert it (simple approach: you could also re-fetch)
const item = acc.items.find(i => i.id === action.meta.arg.notificationId);
if (item) {
item.isread = '0';
}
acc.error = (action.payload as string) ?? 'Failed to mark notification as read';
})
.addCase(clearNotifications.pending, (acc) => {
// Optimistic update: clear items immediately
acc.items = [];
})
.addCase(clearNotifications.rejected, (acc, action) => {
acc.error = (action.payload as string) ?? 'Failed to clear notifications';
});
});
export default reducers;