This commit is contained in:
NextJS
2026-05-05 20:02:40 +00:00
commit 0f6e979aac
51 changed files with 10161 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
import type { Metadata } from "next";
import Link from "next/link";
import { cookies } from "next/headers";
import { notFound, redirect } from "next/navigation";
import { ADMIN_SESSION_COOKIE } from "@/lib/auth/session";
import { MatchLogColoredBody } from "@/components/match-log-colored-body";
import {
parseMatchIdParam,
readMatchLogFile,
} from "@/lib/match-logs-server";
export async function generateMetadata({
params,
}: {
params: Promise<{ matchId: string }>;
}): Promise<Metadata> {
const { matchId } = await params;
return {
title: `Match ${matchId} log · Kick Kings Admin`,
};
}
export default async function MatchLogPage({
params,
}: {
params: Promise<{ matchId: string }>;
}) {
const cookieStore = await cookies();
if (cookieStore.get(ADMIN_SESSION_COOKIE)?.value !== "1") {
redirect("/login");
}
const { matchId: raw } = await params;
const matchId = parseMatchIdParam(raw);
if (matchId == null) {
notFound();
}
const result = await readMatchLogFile(matchId);
return (
<div className="flex min-h-dvh flex-col bg-[#0d1117] text-zinc-100">
<header className="flex shrink-0 items-center gap-2 border-b border-zinc-700/80 bg-[#161b22] px-3 py-2">
<div className="flex gap-1.5 pr-2" aria-hidden="true">
<span className="h-3 w-3 rounded-full bg-[#ff5f56]" />
<span className="h-3 w-3 rounded-full bg-[#ffbd2e]" />
<span className="h-3 w-3 rounded-full bg-[#27c93f]" />
</div>
<p className="min-w-0 flex-1 truncate font-mono text-xs text-zinc-300">
<span className="text-emerald-400/90">soccar</span>
<span className="text-zinc-500"> </span>
<span className="text-zinc-100">match_{matchId}.txt</span>
</p>
<Link
href="/?tab=matches"
className="shrink-0 rounded border border-zinc-600 bg-zinc-800 px-2.5 py-1 font-mono text-xs text-zinc-200 transition hover:bg-zinc-700 hover:text-white"
>
Back to matches
</Link>
</header>
<div className="min-h-0 flex-1 overflow-auto p-4">
{!result.ok ? (
<p className="font-mono text-sm text-red-400">
<span className="text-red-500/80">error:</span> {result.message}
</p>
) : result.content === "" ? (
<p className="font-mono text-sm text-zinc-600">(empty file)</p>
) : (
<MatchLogColoredBody content={result.content} />
)}
</div>
<footer className="shrink-0 border-t border-zinc-800 bg-[#161b22] px-3 py-1.5">
<p className="font-mono text-[11px] text-zinc-500">
<span className="text-emerald-600/80"></span> UTF-8
</p>
</footer>
</div>
);
}