feat: Reports & Analytics page, CSV export, notification bell in header
- Reports page with overview stats, client growth chart, email activity chart - Engagement breakdown (engaged/warm/cooling/cold) with stacked bar - Industry and tag distribution charts - At-risk client lists (cold + cooling) - CSV export button downloads all clients - Notification bell in top bar: overdue events, upcoming events, stale clients, pending drafts - Dismissable notifications with priority indicators - Added Reports to sidebar nav between Network and Settings
This commit is contained in:
@@ -404,6 +404,49 @@ class ApiClient {
|
||||
}
|
||||
return response.json();
|
||||
}
|
||||
// Reports & Analytics
|
||||
async getReportsOverview(): Promise<any> {
|
||||
return this.fetch('/reports/overview');
|
||||
}
|
||||
|
||||
async getReportsGrowth(): Promise<any> {
|
||||
return this.fetch('/reports/growth');
|
||||
}
|
||||
|
||||
async getReportsIndustries(): Promise<any[]> {
|
||||
return this.fetch('/reports/industries');
|
||||
}
|
||||
|
||||
async getReportsTags(): Promise<any[]> {
|
||||
return this.fetch('/reports/tags');
|
||||
}
|
||||
|
||||
async getReportsEngagement(): Promise<any> {
|
||||
return this.fetch('/reports/engagement');
|
||||
}
|
||||
|
||||
async getNotifications(): Promise<any> {
|
||||
return this.fetch('/reports/notifications');
|
||||
}
|
||||
|
||||
async exportClientsCSV(): Promise<void> {
|
||||
const token = this.getToken();
|
||||
const headers: HeadersInit = token ? { Authorization: `Bearer ${token}` } : {};
|
||||
const response = await fetch(`${API_BASE}/reports/export/clients`, {
|
||||
headers,
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!response.ok) throw new Error('Export failed');
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `clients-export-${new Date().toISOString().split('T')[0]}.csv`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
export const api = new ApiClient();
|
||||
|
||||
Reference in New Issue
Block a user