feat(dashboard): message activity timeline + moderation donut
Backend: - GET /api/dashboard/activity?days=1..90 — daily buckets (messages, flagged, active_users) + hourly distribution last 24h - clamped days param, reuses existing indexes (idx_messages_created, ai_status_created) Frontend: - ActivityChart: area chart messages+flagged per day, 7/14/30d range - HourlyActivityChart: 24h bars with peak highlight - ModerationDonut: clean/flagged/warned/error breakdown with live summary line (server X% clean) - Dashboard layout: activity 2/3 + donut 1/3, hourly + top channels Verified: endpoint returns real data from prod DB (784/1897/8 msgs per day), tsc clean backend+frontend.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type {
|
||||
DashboardActivity,
|
||||
DashboardChannelDetail,
|
||||
DashboardStats,
|
||||
DashboardUserDetail,
|
||||
@@ -10,6 +11,9 @@ import { api } from "./client";
|
||||
export const dashboardApi = {
|
||||
getStats: () => api.get<DashboardStats>("/api/dashboard/stats"),
|
||||
|
||||
getActivity: (days = 14) =>
|
||||
api.get<DashboardActivity>(`/api/dashboard/activity?days=${days}`),
|
||||
|
||||
listUsers: (limit?: number, cursor?: string, search?: string) => {
|
||||
const params = new URLSearchParams();
|
||||
if (limit) params.set("limit", String(limit));
|
||||
|
||||
@@ -28,6 +28,25 @@ export interface ModerationOverview {
|
||||
error: number;
|
||||
}
|
||||
|
||||
export interface DashboardActivity {
|
||||
days: number;
|
||||
daily: DailyActivityPoint[];
|
||||
hourly: HourlyActivityPoint[];
|
||||
}
|
||||
|
||||
export interface DailyActivityPoint {
|
||||
day: string; // YYYY-MM-DD
|
||||
messages: number;
|
||||
flagged: number;
|
||||
active_users: number;
|
||||
}
|
||||
|
||||
export interface HourlyActivityPoint {
|
||||
hour: number; // 0-23
|
||||
messages: number;
|
||||
flagged: number;
|
||||
}
|
||||
|
||||
export interface DashboardUser {
|
||||
user_id: string;
|
||||
username?: string | null;
|
||||
|
||||
Reference in New Issue
Block a user