refactor(frontend): remove warn moderation status — hardcode warn to 0 in charts, drop warn filter/badge/buttons/Api, simplify to flagged-only

This commit is contained in:
MythEclipse
2026-06-03 01:13:47 +07:00
parent b7d4e66600
commit 8d34aa7125
10 changed files with 15 additions and 108 deletions
@@ -27,7 +27,7 @@ export function ActivityChart({ hourly, loading }: ActivityChartProps) {
return {
hour: `${String(jakartaHour).padStart(2, "0")}:00`,
clean: b.clean,
warned: b.warned,
warned: 0,
flagged: b.flagged,
error: b.error,
total: b.count,
@@ -22,10 +22,6 @@ export function SummaryCards({
messages && messages.total > 0
? Math.round((messages.clean / messages.total) * 100)
: 0;
const warnedPct =
messages && messages.total > 0
? Math.round((messages.warned / messages.total) * 100)
: 0;
const flaggedPct =
messages && messages.total > 0
? Math.round((messages.flagged / messages.total) * 100)
@@ -47,11 +43,6 @@ export function SummaryCards({
value: cleanPct > 0 ? `${cleanPct}%` : "—",
accent: "text-emerald-400",
},
{
label: "Warned",
value: warnedPct > 0 ? `${warnedPct}%` : "—",
accent: "text-amber-400",
},
{
label: "Flagged",
value: flaggedPct > 0 ? `${flaggedPct}%` : "—",
@@ -24,7 +24,7 @@ export function TrendChart({ trend, loading }: TrendChartProps) {
const data = trend.map((bucket) => ({
date: bucket.date,
clean: bucket.clean,
warned: bucket.warned,
warned: 0,
flagged: bucket.flagged,
error: bucket.error,
total: bucket.count,
@@ -53,7 +53,6 @@ export function UserTable({ users, loading }: UserTableProps) {
<th className="py-2 pr-2 font-semibold">User</th>
<th className="py-2 pr-2 font-semibold text-right">Pesan</th>
<th className="py-2 pr-2 font-semibold text-right">Edit</th>
<th className="py-2 pr-2 font-semibold text-right">Hapus</th>
<th className="py-2 pr-4 font-semibold text-right">Flag</th>
</tr>
</thead>
@@ -103,9 +102,6 @@ export function UserTable({ users, loading }: UserTableProps) {
<td className="py-1.5 pr-2 text-right font-mono text-[10px] text-muted-foreground tabular-nums">
{user.edited_count > 0 ? user.edited_count : "—"}
</td>
<td className="py-1.5 pr-2 text-right font-mono text-[10px] text-muted-foreground tabular-nums">
{user.deleted_count > 0 ? user.deleted_count : "—"}
</td>
<td className="py-1.5 pr-4 text-right">
{user.flagged_count > 0 ? (
<Badge
@@ -48,7 +48,7 @@ export function ViolatorTable({ users, loading }: ViolatorTableProps) {
Pelanggar Terbanyak
</CardTitle>
<CardDescription className="text-xs">
Skor: flagged × 3 + warned × 1.
Skor: flagged × 3.
</CardDescription>
</div>
<Badge variant="destructive">{users.length} pelanggar</Badge>
@@ -61,7 +61,6 @@ export function ViolatorTable({ users, loading }: ViolatorTableProps) {
<tr className="sticky top-0 z-10 bg-card/95 backdrop-blur border-b border-border text-left text-[10px] uppercase tracking-wider text-muted-foreground">
<th className="py-2 pl-4 pr-2 font-semibold">#</th>
<th className="py-2 pr-2 font-semibold">User</th>
<th className="py-2 pr-2 font-semibold text-right">Warned</th>
<th className="py-2 pr-2 font-semibold text-right">Flagged</th>
<th className="py-2 pr-4 font-semibold text-right">Skor</th>
</tr>
@@ -102,9 +101,6 @@ export function ViolatorTable({ users, loading }: ViolatorTableProps) {
</Badge>
</div>
</td>
<td className="py-1.5 pr-2 text-right font-mono text-xs text-amber-400 tabular-nums">
{user.warned_count}
</td>
<td className="py-1.5 pr-2 text-right font-mono text-xs text-red-400 tabular-nums">
{user.flagged_count}
</td>
@@ -1,6 +1,5 @@
import {
AlertCircle,
AlertTriangle,
CheckCircle2,
ChevronDown,
ChevronUp,
@@ -12,7 +11,6 @@ import {
} from "lucide-react";
import { Fragment, useMemo, useState } from "react";
import type { MessageRecord } from "../../../shared/api/client";
import { moderateMessage } from "../../../shared/api/client";
import { Badge, Button, Skeleton } from "../../../shared/ui";
import { parseMetadata } from "../../../entities/message/types";
@@ -89,7 +87,6 @@ function parseStringList(value?: string | null): string[] {
function aiVariant(status: string) {
if (status === "clean") return "success";
if (status === "warn") return "warning";
if (status === "flagged" || status === "error") return "destructive";
return "secondary";
}
@@ -138,7 +135,7 @@ export function MessageCard({
message.ai_confidence ?? message.ai_moderation_score ?? null;
const [isReanalyzing, setIsReanalyzing] = useState(false);
const [showAnalysis, setShowAnalysis] = useState(
aiStatus === "warn" || aiStatus === "flagged",
aiStatus === "flagged",
);
// Build a human-readable analysis summary from categories + confidence + severity
@@ -223,9 +220,6 @@ export function MessageCard({
{aiStatus === "clean" && (
<CheckCircle2 className="h-3.5 w-3.5" />
)}
{aiStatus === "warn" && (
<AlertTriangle className="h-3.5 w-3.5" />
)}
{aiStatus === "flagged" && (
<AlertCircle className="h-3.5 w-3.5" />
)}
@@ -328,9 +322,7 @@ export function MessageCard({
className={`rounded-xl border-l-2 p-3 ${
aiStatus === "flagged"
? "border-l-red-500 bg-red-500/5"
: aiStatus === "warn"
? "border-l-yellow-500 bg-yellow-500/5"
: "border-l-blue-500 bg-blue-500/5"
: "border-l-blue-500 bg-blue-500/5"
}`}
>
<button
@@ -341,9 +333,7 @@ export function MessageCard({
<span className="font-medium text-foreground/80">
{aiStatus === "flagged"
? "🚨"
: aiStatus === "warn"
? "⚠️"
: "️"}{" "}
: "️"}{" "}
{analysisSummary}
</span>
{showAnalysis ? (
@@ -384,52 +374,6 @@ export function MessageCard({
Click to retry analysis
</span>
)}
{/* Moderation action buttons for flagged/warned messages */}
{(aiStatus === "flagged" || aiStatus === "warn") && (
<div className="flex items-center gap-1.5 border-l border-border pl-2">
<Button
size="sm"
variant="destructive"
className="text-xs"
onClick={() => {
if (
window.confirm(
`Delete message from ${message.username}?\n\n"${(message.edited_content ?? message.content).slice(0, 120)}"`,
)
) {
moderateMessage(
message.id,
"delete_message",
"Manual moderation from dashboard",
);
}
}}
>
<Trash2 className="h-3 w-3 mr-1" /> Delete
</Button>
<Button
size="sm"
variant="outline"
className="text-xs"
onClick={() => {
if (
window.confirm(
`Warn user ${message.username} for this message?`,
)
) {
moderateMessage(
message.id,
"warn_user",
"Manual moderation from dashboard",
);
}
}}
>
<AlertTriangle className="h-3 w-3 mr-1" /> Warn
</Button>
</div>
)}
</div>
</div>
</div>
@@ -1,12 +1,12 @@
// ─── Moderation alert toast listener ───────────────────────────────────────
// Listens for "moderation_alert" custom events dispatched from WebSocket
// message_analyzed handler, and shows toast notifications for flagged/warned
// message_analyzed handler, and shows toast notifications for flagged
// messages so moderators don't miss important alerts.
import { useEffect } from "react";
import { useToast } from "../../../shared/ui";
interface AlertDetail {
type: "flagged" | "warn";
type: "flagged";
username: string;
severity: string;
categories: string;
@@ -18,19 +18,18 @@ export function ModerationAlertListener() {
useEffect(() => {
const handler = (e: Event) => {
const { type, username, severity, categories, brief } = (
const { username, severity, categories, brief } = (
e as CustomEvent<AlertDetail>
).detail;
const emoji = type === "flagged" ? "🚨" : "⚠️";
const sevLabel = severity ? `[${severity}]` : "";
const catLabel = categories
? `${categories.split(",").slice(0, 2).join(", ")}`
: "";
addToast(
`${emoji} ${username} ${sevLabel}${catLabel}: ${brief}`,
type === "flagged" ? "error" : "warning",
`🚨 ${username} ${sevLabel}${catLabel}: ${brief}`,
"error",
);
};
@@ -27,7 +27,7 @@ interface MessagesPanelProps {
loadingMore?: boolean;
}
type AiFilter = "all" | "clean" | "warn" | "flagged" | "error" | "pending";
type AiFilter = "all" | "clean" | "flagged" | "error" | "pending";
export function MessagesPanel({
guildName,
@@ -73,7 +73,6 @@ export function MessagesPanel({
return {
total: base.length,
clean: base.filter((m) => m.ai_status === "clean").length,
warn: base.filter((m) => m.ai_status === "warn").length,
flagged: base.filter((m) => m.ai_status === "flagged").length,
error: base.filter((m) => m.ai_status === "error").length,
pending: base.filter((m) => m.ai_status === "pending" || !m.ai_status)
@@ -125,12 +124,6 @@ export function MessagesPanel({
>
{stats.clean} clean
</Badge>
<Badge
variant="outline"
className="text-xs text-yellow-400 border-yellow-400/30"
>
{stats.warn} warn
</Badge>
<Badge
variant="outline"
className="text-xs text-red-400 border-red-400/30"
@@ -227,7 +220,6 @@ export function MessagesPanel({
[
"all",
"clean",
"warn",
"flagged",
"error",
"pending",