import { useState } from "react"; import { useSuspenseQuery } from "@tanstack/react-query"; import { useAuth } from "../lib/auth"; import { bbsQuery, sysopModerationQuery } from "../lib/queries"; import { bbsUrl } from "../lib/routes"; import HandleInput from "../components/form/HandleInput"; import { Button } from "../components/form/Form"; import { useBreadcrumb } from "../hooks/useBreadcrumb"; import { usePageTitle } from "../hooks/usePageTitle"; import { useModerationMutations } from "../hooks/useModerationMutations"; interface ModerationListItemProps { label: string; href: string; title: string; actionLabel: string; onAction?: () => void; } function ModerationListItem({ label, href, title, actionLabel, onAction, }: ModerationListItemProps) { return (
{label} {onAction && ( )}
); } export default function SysopModerate() { const { user } = useAuth(); const [identifier, setIdentifier] = useState(""); const [hideUri, setHideUri] = useState(""); usePageTitle("Moderate community — atbbs"); // requireAuthLoader guarantees user is present at render time. const { data: bbs } = useSuspenseQuery(bbsQuery(user!.handle)); const { data: moderation } = useSuspenseQuery( sysopModerationQuery(user!.pdsUrl, user!.did), ); const { banRkeys, bannedHandles, hideRkeys, hidden } = moderation; useBreadcrumb( [ { label: bbs.site.name, to: bbsUrl(user!.handle) }, { label: "Moderate" }, ], [bbs, user!.handle], ); const { ban, unban, hide, unhide } = useModerationMutations(); function onBan() { const id = identifier.trim(); if (!id) return; ban.mutate(id, { onSuccess: () => setIdentifier("") }); } function onUnban(rkey: string) { if (!confirm("Unban this user?")) return; unban.mutate(rkey); } function onHide() { const uri = hideUri.trim(); if (!uri.startsWith("at://")) { alert("Enter a valid AT-URI."); return; } hide.mutate(uri, { onSuccess: () => setHideUri("") }); } function onUnhide(rkey: string) { if (!confirm("Unhide this post?")) return; unhide.mutate(rkey); } return ( <>

Moderate community

Manage banned users and hidden posts for {bbs.site.name}.

{Object.keys(banRkeys).map((did) => ( onUnban(banRkeys[did]) : undefined } /> ))}
{hidden.map((post) => ( onUnhide(hideRkeys[post.uri]) : undefined } /> ))}
setHideUri(e.target.value)} placeholder="at://did/collection/rkey" aria-label="Post URI to hide" className="flex-1 bg-neutral-900 border border-neutral-800 rounded px-3 py-2 text-neutral-200 placeholder-neutral-500 focus:outline-none focus:border-neutral-600" />
); }