1
0
Fork 0
panel/components/inspector/RelevantModerationNotices.tsx

157 lines
4.8 KiB
TypeScript

"use client";
import { AccountStrike, Message } from "revolt-api";
import { ListCompactor } from "../common/ListCompactor";
import { CompactMessage } from "../cards/CompactMessage";
import { useRef, useState } from "react";
import { Button } from "../ui/button";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "../ui/alert-dialog";
import { Input } from "../ui/input";
import { createStrike } from "@/lib/actions";
import { useToast } from "../ui/use-toast";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../ui/table";
import dayjs from "dayjs";
import { decodeTime } from "ulid";
/**
*
* @param param0 You have received an account strike, for one or more reasons:
- REASON_HERE
Further violations will result in suspension or a permanent ban depending on severity, please abide by the [Acceptable Usage Policy](https://revolt.chat/aup).
* @returns
*/
export function RelevantModerationNotices({
userId,
strikes,
notices,
}: {
userId: string;
strikes: AccountStrike[];
notices: Message[];
}) {
const { toast } = useToast();
const [strikesDraft, setStrikesDraft] = useState(strikes);
const givenReason = useRef("");
const additionalContext = useRef("");
return (
<div className="flex gap-2">
<div className="flex-1 min-w-0 flex flex-col gap-2">
<h2 className="text-md text-center pb-2">Strikes</h2>
<Table>
<TableHeader>
<TableRow>
<TableHead>Reason</TableHead>
<TableHead>Created</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{strikesDraft.map((strike) => (
<TableRow key={strike._id}>
<TableCell>{strike.reason}</TableCell>
<TableCell>
{dayjs(decodeTime(strike._id))?.fromNow()}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<AlertDialog>
<AlertDialogTrigger asChild>
<Button className="mx-auto" variant="outline">
Create
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Create Strike</AlertDialogTitle>
</AlertDialogHeader>
<p className="text-sm flex flex-col gap-2">
<span>
You have received an account strike, for one or more reasons:
</span>
<Input
defaultValue=""
placeholder="Short reason"
onChange={(e) => (givenReason.current = e.currentTarget.value)}
/>
<span>
Further violations will result in suspension or a permanent ban
depending on severity, please abide by the{" "}
<a href="https://revolt.chat/aup" target="_blank">
Acceptable Usage Policy
</a>
.
</span>
<Input
defaultValue=""
placeholder="Additional context (only moderators see this)"
onChange={(e) =>
(additionalContext.current = e.currentTarget.value)
}
/>
</p>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={() =>
givenReason.current &&
createStrike(
userId,
givenReason.current,
additionalContext.current
)
.then((strike) => {
setStrikesDraft((strikes) => [strike, ...strikes]);
toast({ title: "Created strike" });
})
.catch((err) =>
toast({
title: "Failed to create strike!",
description: String(err),
variant: "destructive",
})
)
.finally(() => {
givenReason.current = "";
additionalContext.current = "";
})
}
>
Create
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
<div className="flex-1 min-w-0 flex flex-col gap-2">
<h2 className="text-md text-center pb-2">Alerts</h2>
<ListCompactor
data={notices}
Component={({ item }) => <CompactMessage message={item} hideUser />}
/>
</div>
</div>
);
}