feat(dashboard): add moderation log page + message edit history

- Backend moderation module: GET /api/moderation/stats (per-status + failed rate)
  + GET /api/moderation/actions (filter by status/actionType, cursor paging),
  joins messages for target username + content
- Message GET /api/messages/detail/:id now returns edit_count + edit_history
  (old_content snapshots from message_edits, newest first)
- FE: new /moderation page — summary cards (total/executed/failed/pending +
  failed-rate), status+type filter chips, timeline rows with action icon,
  target user, reason, status badge, timestamps, error text
- FE: message detail shows 'Riwayat edit' panel with previous versions
This commit is contained in:
asepharyana
2026-08-05 11:11:10 +07:00
parent a309570d29
commit f999be4fa0
18 changed files with 664 additions and 2 deletions
+1
View File
@@ -4,6 +4,7 @@ export { configApi } from "./config";
export { dashboardApi } from "./dashboard";
export { mediaApi } from "./media";
export { messagesApi } from "./messages";
export { moderationApi } from "./moderation";
export { recordingsApi } from "./recordings";
export { uiStateApi } from "./ui-state";
export { voiceApi } from "./voice";
@@ -0,0 +1,23 @@
import type { ModerationStats, PaginatedModerationActions } from "@/lib/types";
import { api } from "./client";
export const moderationApi = {
getStats: () => api.get<ModerationStats>("/api/moderation/stats"),
listActions: (
limit?: number,
status?: string,
actionType?: string,
cursor?: string,
) => {
const params = new URLSearchParams();
if (limit) params.set("limit", String(limit));
if (status) params.set("status", status);
if (actionType) params.set("actionType", actionType);
if (cursor) params.set("cursor", cursor);
const qs = params.toString();
return api.get<PaginatedModerationActions>(
`/api/moderation/actions${qs ? `?${qs}` : ""}`,
);
},
};