import { useEffect, useRef, useState } from "react"; import { listMessages } from "./api/client"; import { connectDashboardSocket } from "./ws/client"; import type { DashboardEvent } from "./ws/client"; interface MessageItem { id: string; channel_id: string; user_id: string; username: string; avatar_url: string | null; content: string; created_at: number; type: "text" | "edited" | "deleted"; } export default function App() { const [messages, setMessages] = useState([]); const [wsStatus, setWsStatus] = useState("connecting"); const wsRef = useRef(null); useEffect(() => { let cancelled = false; listMessages(new URLSearchParams({ limit: "30" })) .then((result) => { if (!cancelled) { setMessages(result.data); } }) .catch((err) => { if (!cancelled) { console.error("Failed to load messages:", err); } }); const ws = connectDashboardSocket((event: DashboardEvent) => { switch (event.type) { case "message_created": setMessages((prev) => [event.data, ...prev].slice(0, 200)); break; case "message_analyzed": setMessages((prev) => prev.map((m) => (m.id === event.data.id ? event.data : m)), ); break; case "message_updated": setMessages((prev) => prev.map((m) => (m.id === event.data.id ? { ...m, ...event.data } : m)), ); break; case "message_deleted": setMessages((prev) => prev.map((m) => m.id === event.data.id ? { ...m, type: "deleted" as const } : m, ), ); break; } }); wsRef.current = ws; ws.addEventListener("open", () => setWsStatus("connected")); ws.addEventListener("close", () => setWsStatus("disconnected")); ws.addEventListener("error", () => setWsStatus("error")); return () => { cancelled = true; ws.close(); wsRef.current = null; }; }, []); return (
Moderation
Channels placeholder

Discord Moderation Dashboard

{wsStatus}
{messages.length === 0 ? (

No messages yet

) : ( messages.map((msg) => (
{msg.username}
{msg.username} {new Date(msg.created_at).toLocaleString()} {msg.type === "deleted" && ( [deleted] )}

{msg.content}

)) )}
Review placeholder
); }