erp-core-frontend-web/src/features/notifications/api/notifications.api.ts
rckrdmrd 6b7f438669 feat(frontend): Add Audit and Notifications modules (MGN-007, MGN-008)
Audit module (MGN-007):
- AuditLogsPage.tsx: Full audit logs UI with filtering, stats cards, detail modal
- Uses existing types, api, hooks from settings feature

Notifications module (MGN-008):
- types/notifications.types.ts: Complete types for channels, templates, preferences, in-app
- api/notifications.api.ts: API clients for all notification operations
- hooks/useNotifications.ts: 5 hooks (useChannels, useTemplates, useNotificationPreferences,
  useInAppNotifications, useNotificationBell)
- NotificationsPage.tsx: Full notifications center with category cards, filtering,
  read/unread management

Both modules complement complete backends with comprehensive frontend UIs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 11:20:25 -06:00

149 lines
5.5 KiB
TypeScript

import { api } from '@services/api/axios-instance';
import type {
NotificationChannel,
NotificationTemplate,
NotificationTemplateCreateInput,
NotificationPreference,
NotificationPreferenceUpdateInput,
Notification,
NotificationCreateInput,
NotificationStatus,
InAppNotification,
InAppNotificationCreateInput,
InAppNotificationsFilters,
InAppNotificationsResponse,
} from '../types';
const NOTIFICATIONS_BASE = '/api/v1/notifications';
// ============================================================================
// Channels API
// ============================================================================
export const channelsApi = {
getAll: async (): Promise<NotificationChannel[]> => {
const response = await api.get<NotificationChannel[]>(`${NOTIFICATIONS_BASE}/channels`);
return response.data;
},
getByCode: async (code: string): Promise<NotificationChannel> => {
const response = await api.get<NotificationChannel>(`${NOTIFICATIONS_BASE}/channels/${code}`);
return response.data;
},
};
// ============================================================================
// Templates API
// ============================================================================
export const templatesApi = {
getAll: async (): Promise<NotificationTemplate[]> => {
const response = await api.get<NotificationTemplate[]>(`${NOTIFICATIONS_BASE}/templates`);
return response.data;
},
getByCode: async (code: string): Promise<NotificationTemplate> => {
const response = await api.get<NotificationTemplate>(`${NOTIFICATIONS_BASE}/templates/${code}`);
return response.data;
},
create: async (data: NotificationTemplateCreateInput): Promise<NotificationTemplate> => {
const response = await api.post<NotificationTemplate>(`${NOTIFICATIONS_BASE}/templates`, data);
return response.data;
},
update: async (id: string, data: Partial<NotificationTemplateCreateInput>): Promise<NotificationTemplate> => {
const response = await api.patch<NotificationTemplate>(`${NOTIFICATIONS_BASE}/templates/${id}`, data);
return response.data;
},
delete: async (id: string): Promise<void> => {
await api.delete(`${NOTIFICATIONS_BASE}/templates/${id}`);
},
};
// ============================================================================
// Preferences API
// ============================================================================
export const preferencesApi = {
get: async (): Promise<NotificationPreference> => {
const response = await api.get<NotificationPreference>(`${NOTIFICATIONS_BASE}/preferences`);
return response.data;
},
update: async (data: NotificationPreferenceUpdateInput): Promise<NotificationPreference> => {
const response = await api.patch<NotificationPreference>(`${NOTIFICATIONS_BASE}/preferences`, data);
return response.data;
},
};
// ============================================================================
// Notifications API
// ============================================================================
export const notificationsApi = {
create: async (data: NotificationCreateInput): Promise<Notification> => {
const response = await api.post<Notification>(`${NOTIFICATIONS_BASE}`, data);
return response.data;
},
getPending: async (limit = 50): Promise<Notification[]> => {
const response = await api.get<Notification[]>(`${NOTIFICATIONS_BASE}/pending?limit=${limit}`);
return response.data;
},
updateStatus: async (id: string, status: NotificationStatus, errorMessage?: string): Promise<Notification> => {
const response = await api.patch<Notification>(`${NOTIFICATIONS_BASE}/${id}/status`, {
status,
errorMessage,
});
return response.data;
},
};
// ============================================================================
// In-App Notifications API
// ============================================================================
export const inAppApi = {
getAll: async (filters: InAppNotificationsFilters = {}): Promise<InAppNotificationsResponse> => {
const params = new URLSearchParams();
if (filters.includeRead !== undefined) params.append('include_read', String(filters.includeRead));
if (filters.category) params.append('category', filters.category);
if (filters.page) params.append('page', String(filters.page));
if (filters.limit) params.append('limit', String(filters.limit));
const response = await api.get<InAppNotificationsResponse>(`${NOTIFICATIONS_BASE}/in-app?${params}`);
return response.data;
},
getUnreadCount: async (): Promise<number> => {
const response = await api.get<{ count: number }>(`${NOTIFICATIONS_BASE}/in-app/unread-count`);
return response.data.count;
},
markAsRead: async (id: string): Promise<InAppNotification> => {
const response = await api.post<InAppNotification>(`${NOTIFICATIONS_BASE}/in-app/${id}/read`);
return response.data;
},
markAllAsRead: async (): Promise<void> => {
await api.post(`${NOTIFICATIONS_BASE}/in-app/read-all`);
},
create: async (data: InAppNotificationCreateInput): Promise<InAppNotification> => {
const response = await api.post<InAppNotification>(`${NOTIFICATIONS_BASE}/in-app`, data);
return response.data;
},
archive: async (id: string): Promise<InAppNotification> => {
const response = await api.post<InAppNotification>(`${NOTIFICATIONS_BASE}/in-app/${id}/archive`);
return response.data;
},
delete: async (id: string): Promise<void> => {
await api.delete(`${NOTIFICATIONS_BASE}/in-app/${id}`);
},
};