feat: real notifications, interaction logging, bulk email compose
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { Profile, Client, ClientCreate, ClientNote, Event, EventCreate, Email, EmailGenerate, User, Invite, ActivityItem, InsightsData, ImportPreview, ImportResult, NetworkMatch, NetworkStats } from '@/types';
|
||||
import type { Profile, Client, ClientCreate, ClientNote, Event, EventCreate, Email, EmailGenerate, User, Invite, ActivityItem, InsightsData, ImportPreview, ImportResult, NetworkMatch, NetworkStats, Notification, Interaction, BulkEmailResult } from '@/types';
|
||||
|
||||
const API_BASE = import.meta.env.PROD
|
||||
? 'https://api.thenetwork.donovankelly.xyz/api'
|
||||
@@ -448,10 +448,78 @@ class ApiClient {
|
||||
return this.fetch('/reports/engagement');
|
||||
}
|
||||
|
||||
async getNotifications(): Promise<any> {
|
||||
async getNotificationsLegacy(): Promise<any> {
|
||||
return this.fetch('/reports/notifications');
|
||||
}
|
||||
|
||||
// Real notifications (from notifications table)
|
||||
async getNotifications(params?: { unreadOnly?: boolean; limit?: number }): Promise<{ notifications: Notification[]; unreadCount: number }> {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (params?.unreadOnly) searchParams.set('unreadOnly', 'true');
|
||||
if (params?.limit) searchParams.set('limit', String(params.limit));
|
||||
const query = searchParams.toString();
|
||||
return this.fetch(`/notifications${query ? `?${query}` : ''}`);
|
||||
}
|
||||
|
||||
async markNotificationRead(id: string): Promise<Notification> {
|
||||
return this.fetch(`/notifications/${id}/read`, { method: 'PUT' });
|
||||
}
|
||||
|
||||
async markAllNotificationsRead(): Promise<void> {
|
||||
await this.fetch('/notifications/mark-all-read', { method: 'POST' });
|
||||
}
|
||||
|
||||
async deleteNotification(id: string): Promise<void> {
|
||||
await this.fetch(`/notifications/${id}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
// Interactions
|
||||
async getClientInteractions(clientId: string): Promise<Interaction[]> {
|
||||
return this.fetch(`/clients/${clientId}/interactions`);
|
||||
}
|
||||
|
||||
async createInteraction(clientId: string, data: {
|
||||
type: string; title: string; description?: string; duration?: number; contactedAt: string;
|
||||
}): Promise<Interaction> {
|
||||
return this.fetch(`/clients/${clientId}/interactions`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
async updateInteraction(id: string, data: Partial<{
|
||||
type: string; title: string; description?: string; duration?: number; contactedAt: string;
|
||||
}>): Promise<Interaction> {
|
||||
return this.fetch(`/interactions/${id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
async deleteInteraction(id: string): Promise<void> {
|
||||
await this.fetch(`/interactions/${id}`, { method: 'DELETE' });
|
||||
}
|
||||
|
||||
async getRecentInteractions(limit?: number): Promise<Interaction[]> {
|
||||
const query = limit ? `?limit=${limit}` : '';
|
||||
return this.fetch(`/interactions/recent${query}`);
|
||||
}
|
||||
|
||||
// Bulk Email
|
||||
async bulkGenerateEmails(clientIds: string[], purpose: string, provider?: 'anthropic' | 'openai'): Promise<BulkEmailResult> {
|
||||
return this.fetch('/emails/bulk-generate', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ clientIds, purpose, provider }),
|
||||
});
|
||||
}
|
||||
|
||||
async bulkSendEmails(batchId: string): Promise<{ batchId: string; total: number; sent: number; failed: number }> {
|
||||
return this.fetch('/emails/bulk-send', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ batchId }),
|
||||
});
|
||||
}
|
||||
|
||||
async exportClientsCSV(): Promise<void> {
|
||||
const token = this.getToken();
|
||||
const headers: HeadersInit = token ? { Authorization: `Bearer ${token}` } : {};
|
||||
|
||||
Reference in New Issue
Block a user