Files
erika/app/leaderboard/xp/page.tsx
T

63 lines
2.3 KiB
TypeScript

import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { LeaderboardBoard } from "@/components/leaderboard/leaderboard-board";
import { LeaderboardError } from "@/components/leaderboard/leaderboard-error";
import { LeaderboardShell } from "@/components/leaderboard/leaderboard-shell";
import { RealtimeRefresh } from "@/components/realtime-refresh";
import { getXpLeaderboardPage } from "@/lib/leaderboard/database";
import { normalizeRequestedPage } from "@/lib/leaderboard/ranking";
export const dynamic = "force-dynamic";
export const metadata: Metadata = {
title: "อันดับ XP",
description: "ดูอันดับ XP รวมและเลเวลของสมาชิกใน Discord ของ Erika!",
alternates: {
canonical: "/leaderboard/xp",
},
};
type XpLeaderboardPageProps = {
searchParams: Promise<{
page?: string | string[];
}>;
};
export default async function XpLeaderboardPage({
searchParams,
}: XpLeaderboardPageProps) {
const query = await searchParams;
const requestedPage = normalizeRequestedPage(query.page);
let data;
try {
data = await getXpLeaderboardPage(requestedPage);
} catch (error) {
console.error("Failed to load XP leaderboard", error);
return (
<LeaderboardShell
active="xp"
title="อันดับ XP"
description="จัดอันดับจาก XP รวมของสมาชิกที่มีเลเวล 1 ขึ้นไป อันดับที่มี XP เท่ากันจะแชร์อันดับเดียวกัน"
>
<LeaderboardError source="database" />
</LeaderboardShell>
);
}
if (query.page !== undefined && query.page !== String(data.page)) {
redirect(data.page > 1 ? `/leaderboard/xp?page=${data.page}` : "/leaderboard/xp");
}
return (
<LeaderboardShell
active="xp"
title="อันดับ XP"
description="จัดอันดับจาก XP รวมของสมาชิกที่มีเลเวล 1 ขึ้นไป อันดับที่มี XP เท่ากันจะแชร์อันดับเดียวกัน"
>
<RealtimeRefresh topic="leaderboards" leaderboard="xp" />
<LeaderboardBoard kind="xp" data={data} />
</LeaderboardShell>
);
}