Add Reports to User View
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
"use server";
|
"use server";
|
||||||
import { prisma } from "@repo/db";
|
import { prisma, User } from "@repo/db";
|
||||||
|
|
||||||
export const markAsResolved = async (id: number) => {
|
export const markAsResolved = async (id: number) => {
|
||||||
await prisma.report.update({
|
await prisma.report.update({
|
||||||
@@ -28,6 +28,18 @@ export const getReports = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUserReports = async (user: User) => {
|
||||||
|
return prisma.report.findMany({
|
||||||
|
where: {
|
||||||
|
reportedUserId: user.id,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
sender: true,
|
||||||
|
reported: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const fetchReportDetails = async (id: number) => {
|
export const fetchReportDetails = async (id: number) => {
|
||||||
return prisma.report.findUnique({
|
return prisma.report.findUnique({
|
||||||
where: { id },
|
where: { id },
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import { User } from "@repo/db";
|
||||||
|
import { Check, Eye, X } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { getUserReports, handleMarkAsResolved } from "../../../report/actions";
|
||||||
|
|
||||||
|
export default function UserReports({ user }: { user: User }) {
|
||||||
|
const [reports, setReports] = useState<
|
||||||
|
{
|
||||||
|
id: number;
|
||||||
|
timestamp: string;
|
||||||
|
erledigt: boolean;
|
||||||
|
sender: {
|
||||||
|
id: string;
|
||||||
|
firstname: string;
|
||||||
|
lastname: string;
|
||||||
|
publicId: string;
|
||||||
|
};
|
||||||
|
}[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchReports = async (user: User) => {
|
||||||
|
const reps = await getUserReports(user);
|
||||||
|
const transformedReports = reps.map((report) => ({
|
||||||
|
id: report.id,
|
||||||
|
timestamp: report.timestamp.toISOString(),
|
||||||
|
erledigt: report.erledigt,
|
||||||
|
sender: {
|
||||||
|
id: report.sender.id,
|
||||||
|
firstname: report.sender.firstname,
|
||||||
|
lastname: report.sender.lastname,
|
||||||
|
publicId: report.sender.publicId,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
setReports(transformedReports);
|
||||||
|
};
|
||||||
|
fetchReports(user);
|
||||||
|
}, [user]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="overflow-x-auto">
|
||||||
|
<table className="table table-zebra w-full">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Erledigt</th>
|
||||||
|
<th>Sender</th>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{reports.map((report) => (
|
||||||
|
<tr key={report.id}>
|
||||||
|
<td className="text-center">
|
||||||
|
{report.erledigt ? (
|
||||||
|
<Check className="text-green-500 w-5 h-5" />
|
||||||
|
) : (
|
||||||
|
<X className="text-red-500 w-5 h-5" />
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td>{`${report.sender.firstname} ${report.sender.lastname} (${report.sender.publicId})`}</td>
|
||||||
|
<td>{new Date(report.timestamp).toLocaleString()}</td>
|
||||||
|
<td>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Link href={`/admin/report/${report.id}`}>
|
||||||
|
<button className="btn btn-sm btn-outline btn-info flex items-center gap-2">
|
||||||
|
<Eye className="w-4 h-4" /> Anzeigen
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
{!report.erledigt && (
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-outline btn-success flex items-center gap-2"
|
||||||
|
onClick={async () => {
|
||||||
|
const result = await handleMarkAsResolved(report.id);
|
||||||
|
if (result.success) {
|
||||||
|
setReports((prevReports) =>
|
||||||
|
prevReports.map((r) =>
|
||||||
|
r.id === report.id ? { ...r, erledigt: true } : r,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
alert("Error: " + result.error);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Check className="w-4 h-4" /> Erledigen
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import { min } from "date-fns";
|
|||||||
import { cn } from "../../../../../../helper/cn";
|
import { cn } from "../../../../../../helper/cn";
|
||||||
import { ChartBarBigIcon, PlaneIcon } from "lucide-react";
|
import { ChartBarBigIcon, PlaneIcon } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import UserReports from "./UserReports";
|
||||||
|
|
||||||
interface ProfileFormProps {
|
interface ProfileFormProps {
|
||||||
user: User;
|
user: User;
|
||||||
@@ -419,6 +420,7 @@ export const AdminForm = ({ user, dispoTime, pilotTime }: AdminFormProps) => {
|
|||||||
<h2 className="card-title">
|
<h2 className="card-title">
|
||||||
<ExclamationTriangleIcon className="w-5 h-5" /> Reports
|
<ExclamationTriangleIcon className="w-5 h-5" /> Reports
|
||||||
</h2>
|
</h2>
|
||||||
|
<UserReports user={user} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user