Added Discord message for reports, Fixed type on docs
This commit is contained in:
67
apps/discord-server/routes/report.ts
Normal file
67
apps/discord-server/routes/report.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { prisma } from "@repo/db";
|
||||
import { Embed, EmbedBuilder } from "discord.js";
|
||||
import { Router } from "express";
|
||||
import client from "modules/discord";
|
||||
|
||||
if (!process.env.DISCORD_REPORT_CHANNEL)
|
||||
throw new Error("DISCORD_REPORT_CHANNEL environment variable is not set.");
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
router.post("/admin-embed", async (req, res) => {
|
||||
const { reportId } = req.body;
|
||||
if (!reportId) {
|
||||
res.status(400).json({ error: "reportId is required" });
|
||||
return;
|
||||
}
|
||||
const report = await prisma.report.findUnique({
|
||||
where: {
|
||||
id: Number(reportId),
|
||||
},
|
||||
include: {
|
||||
Reported: true,
|
||||
Sender: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!report) {
|
||||
res.status(404).json({ error: "Report not found" });
|
||||
return;
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle(`Report #${report.id}`)
|
||||
.setURL(`${process.env.NEXT_PUBLIC_HUB_URL}/admin/report/${report.id}`)
|
||||
.setDescription(report.text)
|
||||
.addFields(
|
||||
{
|
||||
name: "gemeldeter Nutzer",
|
||||
value: `${report.Reported?.firstname} ${report.Reported?.lastname} (${report.Reported?.publicId})`,
|
||||
inline: true,
|
||||
},
|
||||
{ name: "angemeldet als", value: report.reportedUserRole, inline: true },
|
||||
{
|
||||
name: "gemeldet von",
|
||||
value: `${report.Sender?.firstname} ${report.Sender?.lastname} (${report.Sender?.publicId})`,
|
||||
},
|
||||
)
|
||||
.setFooter({
|
||||
text: "",
|
||||
})
|
||||
.setTimestamp(new Date(report.timestamp))
|
||||
.setColor("DarkRed");
|
||||
|
||||
const reportsChannel = await client.channels.fetch(process.env.DISCORD_REPORT_CHANNEL!);
|
||||
if (!reportsChannel || !reportsChannel.isSendable()) {
|
||||
res.status(500).json({ error: "Reports channel not found or is not a text channel" });
|
||||
return;
|
||||
}
|
||||
const message = await reportsChannel.send({ embeds: [embed] });
|
||||
message.react("🫡").catch(console.error);
|
||||
message.react("✅").catch(console.error);
|
||||
res.json({
|
||||
message: "Report embed sent to Discord channel",
|
||||
});
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Router } from "express";
|
||||
import memberRouter from "./member";
|
||||
import helperRouter from "./helper";
|
||||
import reportRouter from "./report";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
router.use("/member", memberRouter);
|
||||
router.use("/helper", helperRouter);
|
||||
router.use("/report", reportRouter);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -36,3 +36,13 @@ export const removeRolesFromMember = async (memberId: string, roleIds: string[])
|
||||
console.error("Error removing roles from member:", error);
|
||||
});
|
||||
};
|
||||
|
||||
export const sendReportEmbed = async (reportId: number) => {
|
||||
discordAxiosClient
|
||||
.post("/report/admin-embed", {
|
||||
reportId,
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error removing roles from member:", error);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Router } from "express";
|
||||
|
||||
import { prisma } from "@repo/db";
|
||||
import { sendReportEmbed } from "modules/discord";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
@@ -11,6 +12,9 @@ router.put("/", async (req, res) => {
|
||||
});
|
||||
|
||||
// TODO: send link to report on admin page to user
|
||||
sendReportEmbed(report.id).catch((error) => {
|
||||
console.error("Error sending report embed to Discord:", error);
|
||||
});
|
||||
|
||||
res.json(report);
|
||||
} catch (error) {
|
||||
|
||||
@@ -109,12 +109,16 @@ export const Report = () => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
if (message.length < 1 || !selectedPlayer) return;
|
||||
const dispatcher = filteredDispatcher?.find((d) => d.userId === selectedPlayer)
|
||||
? "Disponent"
|
||||
: null;
|
||||
const pilot = filteredAircrafts?.find((a) => a.userId === selectedPlayer)
|
||||
? "Pilot"
|
||||
: null;
|
||||
const selectedDispatcher = filteredDispatcher?.find(
|
||||
(d) => d.userId === selectedPlayer,
|
||||
);
|
||||
const dispatcher = selectedDispatcher ? selectedDispatcher.zone : null;
|
||||
|
||||
const selectedAircraft = filteredAircrafts?.find(
|
||||
(a) => a.userId === selectedPlayer,
|
||||
);
|
||||
const pilot = selectedAircraft ? selectedAircraft.Station.bosCallsignShort : null;
|
||||
|
||||
setSending(true);
|
||||
sendReportAPI({
|
||||
text: message,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Was ist neu? Quasi alles.
|
||||
|
||||
Nicht nur die Leitstelle erhält eine V2, nahezu alle Systeme und Vorgänge wurden überarbeitet.
|
||||
In diesem Beitrag gehen wir auf die wchtigsten einzelheiten ein.
|
||||
In diesem Beitrag gehen wir auf die wichtigsten einzelheiten ein.
|
||||
|
||||
### Das neue HUB
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ export const ReportSenderInfo = ({
|
||||
return (
|
||||
<div className="card-body">
|
||||
<Link href={`/admin/user/${Reported?.id}`} className="card-title link link-hover">
|
||||
{Reported?.firstname} {Reported?.lastname} ({Reported?.publicId})
|
||||
{Reported?.firstname} {Reported?.lastname} ({Reported?.publicId}) als{" "}
|
||||
<span className="text-primary">{report.reportedUserRole}</span>
|
||||
</Link>
|
||||
<div className="textarea w-full text-left">{report.text}</div>
|
||||
<Link
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
import { Check, Eye, X } from "lucide-react";
|
||||
import { Check, Eye, ShieldQuestion, X } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { PaginatedTable } from "_components/PaginatedTable";
|
||||
import { Report, User } from "@repo/db";
|
||||
import { ColumnDef } from "@tanstack/react-table";
|
||||
import { Workflow, Plane } from "lucide-react";
|
||||
|
||||
export default function ReportPage() {
|
||||
return (
|
||||
@@ -40,6 +41,20 @@ export default function ReportPage() {
|
||||
return `${user.firstname} ${user.lastname} (${user.publicId})`;
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "reportedUserRole",
|
||||
header: "Rolle des gemeldeten Nutzers",
|
||||
cell: ({ row }) => {
|
||||
const role = row.getValue("reportedUserRole") as string | undefined;
|
||||
const Icon = role ? (role.startsWith("LST") ? Workflow : Plane) : ShieldQuestion;
|
||||
return (
|
||||
<span className="flex items-center gap-2">
|
||||
<Icon className="w-4 h-4" />
|
||||
{role || "Unbekannt"}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "Reported",
|
||||
header: "Reported",
|
||||
|
||||
@@ -74,8 +74,8 @@ export const PasswortReset = () => {
|
||||
: ""}
|
||||
</p>
|
||||
<span className="text-sm font-medium flex justify-end">
|
||||
<Link href="/passwort-reset" className="link link-accent link-hover ">
|
||||
neues Passwort anfordern
|
||||
<Link href="/login" className="link link-accent link-hover ">
|
||||
zum Login
|
||||
</Link>
|
||||
</span>
|
||||
<div className="card-actions mt-6">
|
||||
|
||||
Reference in New Issue
Block a user