Files
Epicnabbo-Catalogus-Updated…/src/app/admin/devops/errors/page.tsx
T

84 lines
2.7 KiB
TypeScript

import { redirect } from "next/navigation";
import { Card, CardContent } from "@/components/ui/card";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
export default async function EmulatorErrorsPage({
searchParams,
}: {
searchParams: Promise<Record<string, string>>;
}) {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.DEVOPS_VIEW, session.user.rank)) {
redirect("/admin");
}
const params = await searchParams;
const page = Math.max(1, Number(params.page) || 1);
const perPage = 50;
const [errors, total] = await Promise.all([
prisma.emulatorErrors.findMany({
orderBy: { id: "desc" },
skip: (page - 1) * perPage,
take: perPage,
}),
prisma.emulatorErrors.count(),
]);
const lastPage = Math.ceil(total / perPage);
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold tracking-tight">Emulator Errors</h1>
<p className="text-muted-foreground">
{total} total errors — showing page {page} of {lastPage}
</p>
</div>
<Card>
<CardContent className="p-0">
{errors.length === 0 ? (
<div className="p-6 text-center text-muted-foreground">No emulator errors found</div>
) : (
<div className="divide-y">
{errors.map((error) => (
<div key={error.id} className="p-4">
<div className="flex items-center justify-between mb-2">
<span className="font-mono text-xs text-muted-foreground">#{error.id}</span>
<span className="text-xs text-muted-foreground">
{new Date(error.timestamp * 1000).toLocaleString()}
</span>
</div>
<pre className="text-xs whitespace-pre-wrap break-all font-mono bg-muted p-2 rounded">
{Buffer.from(error.stacktrace).toString("utf-8")}
</pre>
</div>
))}
</div>
)}
</CardContent>
</Card>
{lastPage > 1 && (
<div className="flex justify-center gap-2">
{page > 1 && (
<a href={`?page=${page - 1}`} className="text-sm text-primary hover:underline">
Previous
</a>
)}
<span className="text-sm text-muted-foreground">
Page {page} of {lastPage}
</span>
{page < lastPage && (
<a href={`?page=${page + 1}`} className="text-sm text-primary hover:underline">
Next
</a>
)}
</div>
)}
</div>
);
}