Files
EpicNext-Cms/src/app/admin/devops/errors/page.tsx
T
2026-07-13 21:57:41 +02:00

94 lines
2.5 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>
);
}