forked from administration/panel
feat: show related reports for content
parent
f499c0179e
commit
8d31b59255
|
@ -1,37 +1,47 @@
|
||||||
import { MessageContextCard } from "@/components/cards/MessageContextCard";
|
import { MessageContextCard } from "@/components/cards/MessageContextCard";
|
||||||
|
import { ReportCard } from "@/components/cards/ReportCard";
|
||||||
import { UserCard } from "@/components/cards/UserCard";
|
import { UserCard } from "@/components/cards/UserCard";
|
||||||
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button, buttonVariants } from "@/components/ui/button";
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
CardDescription,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/components/ui/popover";
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import {
|
import {
|
||||||
fetchReportById,
|
fetchReportById,
|
||||||
|
fetchReports,
|
||||||
fetchSnapshotsByReport,
|
fetchSnapshotsByReport,
|
||||||
fetchUserById,
|
fetchUserById,
|
||||||
} from "@/lib/db";
|
} from "@/lib/db";
|
||||||
import { ArrowLeft } from "lucide-react";
|
import { ArrowLeft } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { notFound } from "next/navigation";
|
||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
|
|
||||||
export default async function Reports({ params }: { params: { id: string } }) {
|
export default async function Reports({ params }: { params: { id: string } }) {
|
||||||
const report = await fetchReportById(params.id);
|
const report = await fetchReportById(params.id);
|
||||||
if (!report) return <span>404</span>;
|
if (!report) return notFound();
|
||||||
|
|
||||||
const author = await fetchUserById(report.author_id);
|
const author = await fetchUserById(report.author_id);
|
||||||
const snapshots = await fetchSnapshotsByReport(report._id);
|
const snapshots = await fetchSnapshotsByReport(report._id);
|
||||||
|
|
||||||
|
const relatedReports = await Promise.all(
|
||||||
|
snapshots
|
||||||
|
.map((snapshot) => snapshot._id)
|
||||||
|
.map((contentId) =>
|
||||||
|
fetchReports({
|
||||||
|
_id: {
|
||||||
|
$ne: report._id,
|
||||||
|
},
|
||||||
|
status: "Created",
|
||||||
|
"content.id": contentId,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<Link
|
<Link
|
||||||
|
@ -57,19 +67,26 @@ export default async function Reports({ params }: { params: { id: string } }) {
|
||||||
</Card>
|
</Card>
|
||||||
<UserCard user={author!} subtitle="Report Author" />
|
<UserCard user={author!} subtitle="Report Author" />
|
||||||
|
|
||||||
{snapshots.map((snapshot) => (
|
{snapshots.map((snapshot, index) => (
|
||||||
<Fragment key={snapshot._id}>
|
<Fragment key={snapshot._id}>
|
||||||
{/*<Separator />*/}
|
<Separator className="my-2" />
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<div className="flex-[2]">
|
<div className="flex-[2]">
|
||||||
{/*<h2 className="text-md"> </h2>*/}
|
{relatedReports[index].length ? (
|
||||||
|
<h2 className="text-md pb-2"> </h2>
|
||||||
|
) : undefined}
|
||||||
{snapshot._type === "Message" && (
|
{snapshot._type === "Message" && (
|
||||||
<MessageContextCard snapshot={snapshot} />
|
<MessageContextCard snapshot={snapshot} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
{relatedReports[index].length ? (
|
||||||
{/*<h2 className="text-md text-center">Related Open Reports</h2>*/}
|
<div className="flex-1">
|
||||||
</div>
|
<h2 className="text-md text-center pb-2">Other Reports</h2>
|
||||||
|
{relatedReports[index].map((relatedReport) => (
|
||||||
|
<ReportCard key={relatedReport._id} report={relatedReport} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : undefined}
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { ReportCard } from "@/components/cards/ReportCard";
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardDescription,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from "@/components/ui/card";
|
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { fetchReports } from "@/lib/db";
|
import { fetchReports } from "@/lib/db";
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
export default async function Reports() {
|
export default async function Reports() {
|
||||||
const reports = (await fetchReports()).sort((b, _) =>
|
const reports = (await fetchReports()).sort((b, _) =>
|
||||||
|
@ -18,22 +11,7 @@ export default async function Reports() {
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<Input placeholder="Search for reports..." disabled />
|
<Input placeholder="Search for reports..." disabled />
|
||||||
{reports.map((report) => (
|
{reports.map((report) => (
|
||||||
<Link href={`/panel/reports/${report._id}`} key={report._id as never}>
|
<ReportCard key={report._id} report={report} />
|
||||||
<Card className="transition-all hover:-translate-y-1 hover:shadow-md">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle className="overflow-ellipsis whitespace-nowrap overflow-x-clip flex gap-2 items-center">
|
|
||||||
{report.content.report_reason.includes("Illegal") && (
|
|
||||||
<Badge variant="destructive">Urgent</Badge>
|
|
||||||
)}{" "}
|
|
||||||
{report.additional_context || "No reason specified"}
|
|
||||||
</CardTitle>
|
|
||||||
<CardDescription>
|
|
||||||
{report._id.toString().substring(20, 26)} ·{" "}
|
|
||||||
{report.content.report_reason} · {report.content.type}
|
|
||||||
</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
</Card>
|
|
||||||
</Link>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
export default function Sparkle() {
|
export default function Sparkle() {
|
||||||
return (
|
return (
|
||||||
<div className="grid place-items-center">
|
<div>
|
||||||
|
<h1 className="text-xl text-center">Running version v0.0.1</h1>
|
||||||
<img
|
<img
|
||||||
className="absolute right-0 bottom-0"
|
className="absolute right-0 bottom-0"
|
||||||
src="https://api.gifbox.me/file/posts/MF3oORlDjfHAVJ-DgPyRQSjMdy9WNIxk.webp"
|
src="https://api.gifbox.me/file/posts/MF3oORlDjfHAVJ-DgPyRQSjMdy9WNIxk.webp"
|
||||||
|
|
|
@ -34,7 +34,10 @@ function Message({
|
||||||
<AlertDialog>
|
<AlertDialog>
|
||||||
<AlertDialogTrigger className="w-full">
|
<AlertDialogTrigger className="w-full">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<div className="flex-1 min-w-0 overflow-ellipsis overflow-hidden text-right">
|
<div
|
||||||
|
className="flex-1 min-w-0 overflow-ellipsis overflow-hidden text-right"
|
||||||
|
title={`${user?.username}#${user?.discriminator}`}
|
||||||
|
>
|
||||||
{user?.avatar && (
|
{user?.avatar && (
|
||||||
<Avatar className="w-4 h-4 inline-block align-middle mr-1">
|
<Avatar className="w-4 h-4 inline-block align-middle mr-1">
|
||||||
<AvatarImage
|
<AvatarImage
|
||||||
|
@ -61,8 +64,8 @@ function Message({
|
||||||
src={`https://autumn.revolt.chat/avatars/${user.avatar._id}`}
|
src={`https://autumn.revolt.chat/avatars/${user.avatar._id}`}
|
||||||
/>
|
/>
|
||||||
</Avatar>
|
</Avatar>
|
||||||
)}
|
)}{" "}
|
||||||
{user?.username}
|
{user?.username}#{user?.discriminator}
|
||||||
</AlertDialogTitle>
|
</AlertDialogTitle>
|
||||||
<AlertDialogDescription className="flex flex-col gap-2 max-w-full">
|
<AlertDialogDescription className="flex flex-col gap-2 max-w-full">
|
||||||
{message.content && <span>{message.content}</span>}
|
{message.content && <span>{message.content}</span>}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import Link from "next/link";
|
||||||
|
import { Report } from "revolt-api";
|
||||||
|
import { Card, CardDescription, CardHeader, CardTitle } from "../ui/card";
|
||||||
|
import { Badge } from "../ui/badge";
|
||||||
|
|
||||||
|
export function ReportCard({ report }: { report: Report }) {
|
||||||
|
return (
|
||||||
|
<Link href={`/panel/reports/${report._id}`}>
|
||||||
|
<Card className="transition-all hover:-translate-y-1 hover:shadow-md">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="overflow-ellipsis whitespace-nowrap overflow-x-clip flex gap-2 items-center">
|
||||||
|
{report.content.report_reason.includes("Illegal") && (
|
||||||
|
<Badge variant="destructive">Urgent</Badge>
|
||||||
|
)}{" "}
|
||||||
|
{report.additional_context || "No reason specified"}
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
{report._id.toString().substring(20, 26)} ·{" "}
|
||||||
|
{report.content.report_reason} · {report.content.type}
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue