import { asc, count } from "drizzle-orm"; import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { db, WebsiteRareValueCategories, WebsiteRareValues } from "@/lib/db"; import { siteSettings } from "@/lib/services/site-settings"; // TODO: Cache Components adoption. Refactor this route so this opt-out can be removed. // See: https://nextjs.org/docs/app/guides/migrating-to-cache-components export const instant = false; export const metadata = { title: "Rare values" }; type CategoryRow = { id: bigint; name: string; badge: string; priority: number; }; export default async function RareValuesPage() { const t = await getTranslations("pages.rares"); let categories: CategoryRow[] = []; try { categories = await db .select({ id: WebsiteRareValueCategories.id, name: WebsiteRareValueCategories.name, badge: WebsiteRareValueCategories.badge, priority: WebsiteRareValueCategories.priority, }) .from(WebsiteRareValueCategories) .orderBy( asc(WebsiteRareValueCategories.priority), asc(WebsiteRareValueCategories.name), ); } catch { categories = []; } // Per-category rare counts (grouped so we avoid N queries). const counts = new Map(); try { const grouped = await db .select({ categoryId: WebsiteRareValues.categoryId, value: count(), }) .from(WebsiteRareValues) .groupBy(WebsiteRareValues.categoryId); for (const g of grouped) { counts.set(String(g.categoryId), Number(g.value)); } } catch { // leave counts empty -> shown as 0 } const badgesBase = (await siteSettings.get("badges_path", "")) ?? ""; return (
{categories.length === 0 ? ( {t("empty")} ) : (
{categories.map((c) => { const id = String(c.id); const rareCount = counts.get(id) ?? 0; const badgeSrc = badgesBase && c.badge ? `${badgesBase}/${c.badge}.gif` : ""; return (
{badgeSrc ? ( // eslint-disable-next-line @next/next/no-img-element {`${c.name} ) : ( 💎 )}

{c.name}

{t("rareCount", { count: rareCount })}

{t("viewRares")}
); })}
)}
); }