import { sql } from "drizzle-orm"; import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { ContentCard, EmptyState, RankBadge } from "@/components/public/ui"; import { db } from "@/lib/db"; import { avatarImageUrl } from "@/lib/format"; type LeaderRow = { username: string; look: string; points: number | bigint; }; async function loadRows(): Promise< { username: string; look: string; points: number }[] > { try { const [rows] = (await db.execute(sql` SELECT u.username AS username, u.look AS look, p.points AS points FROM radio_listener_points p INNER JOIN users u ON u.id = p.user_id ORDER BY p.points DESC LIMIT 50 `)) as unknown as [LeaderRow[], unknown]; return (rows ?? []).map((r) => ({ username: r.username, look: r.look, points: Number(r.points), })); } catch { return []; } } export default async function RadioLeaderboardPage() { const t = await getTranslations("pages.radioLeaderboard"); const rows = await loadRows(); return (
{rows.length === 0 ? ( {t("empty")} ) : ( {rows.map((row, i) => { const avatar = avatarImageUrl(row.look, { size: "s", headOnly: true, }); return ( ); })}
{t("colRank")} {t("colAvatar")} {t("colListener")} {t("colPoints")}
{/* eslint-disable-next-line @next/next/no-img-element */} {`${row.username} {row.username} {row.points.toLocaleString()}
)}
); }