/** * Notification API Service * Fetches notifications from /api/v1/notifications/ endpoints */ import { fetchAPI } from './api'; // ============================================================================ // TYPES // ============================================================================ // Notification types - match backend NotificationType choices export type NotificationTypeAPI = // AI Operations | 'ai_cluster_complete' | 'ai_cluster_failed' | 'ai_ideas_complete' | 'ai_ideas_failed' | 'ai_content_complete' | 'ai_content_failed' | 'ai_images_complete' | 'ai_images_failed' | 'ai_prompts_complete' | 'ai_prompts_failed' // Workflow | 'content_ready_review' | 'content_published' | 'content_publish_failed' // WordPress Sync | 'wordpress_sync_success' | 'wordpress_sync_failed' // Credits/Billing | 'credits_low' | 'credits_depleted' // Setup | 'site_setup_complete' | 'keywords_imported' // System | 'system_info' // Legacy/fallback | 'ai_task' | 'system' | 'credit' | 'billing' | 'integration' | 'content' | 'info'; export type NotificationSeverityAPI = 'info' | 'success' | 'warning' | 'error'; export interface NotificationAPI { id: number; notification_type: NotificationTypeAPI; severity: NotificationSeverityAPI; title: string; message: string; is_read: boolean; created_at: string; read_at: string | null; action_label: string | null; action_url: string | null; metadata: Record | null; related_object_type: string | null; related_object_id: number | null; } export interface NotificationListResponse { count: number; next: string | null; previous: string | null; results: NotificationAPI[]; } export interface UnreadCountResponse { unread_count: number; } // ============================================================================ // API FUNCTIONS // ============================================================================ /** * Fetch notifications list */ export async function fetchNotifications(params?: { page?: number; page_size?: number; is_read?: boolean; notification_type?: NotificationTypeAPI; }): Promise { const searchParams = new URLSearchParams(); if (params?.page) searchParams.set('page', params.page.toString()); if (params?.page_size) searchParams.set('page_size', params.page_size.toString()); if (params?.is_read !== undefined) searchParams.set('is_read', params.is_read.toString()); if (params?.notification_type) searchParams.set('notification_type', params.notification_type); const queryString = searchParams.toString(); const url = `/v1/notifications/${queryString ? `?${queryString}` : ''}`; return fetchAPI(url); } /** * Get unread notification count */ export async function fetchUnreadCount(): Promise { return fetchAPI('/v1/notifications/unread-count/'); } /** * Mark a single notification as read */ export async function markNotificationRead(id: number): Promise { return fetchAPI(`/v1/notifications/${id}/read/`, { method: 'POST', }); } /** * Mark all notifications as read */ export async function markAllNotificationsRead(): Promise<{ message: string; count: number }> { return fetchAPI('/v1/notifications/read-all/', { method: 'POST', }); } /** * Delete a notification */ export async function deleteNotification(id: number): Promise { await fetchAPI(`/v1/notifications/${id}/`, { method: 'DELETE', }); } /** * Delete multiple notifications */ export async function deleteNotifications(ids: number[]): Promise { await Promise.all(ids.map(id => deleteNotification(id))); }