import { getTranslations } from "next-intl/server"; import { ContentCard, EmptyState, StatBlock } from "@/components/public/ui"; import { prisma } from "@/lib/prisma"; export const dynamic = "force-dynamic"; export const metadata = { title: "Marketplace" }; // state == 1 → an active, unsold offer in the Arcturus marketplace. const STATE_ACTIVE = 1; type RelativeTimeTranslator = (key: string, values?: Record) => string; function listedAgo(ts: number, t: RelativeTimeTranslator): string { const now = Math.floor(Date.now() / 1000); const diff = Math.max(0, now - ts); if (diff < 60) return t("justNow"); const mins = Math.floor(diff / 60); if (mins < 60) return t("minutesAgo", { count: mins }); const hours = Math.floor(mins / 60); if (hours < 24) return t("hoursAgo", { count: hours }); const days = Math.floor(hours / 24); return t("daysAgo", { count: days }); } function listedAt(ts: number): string { return new Date(ts * 1000).toISOString().slice(0, 16).replace("T", " "); } export default async function MarketplacePage() { const t = await getTranslations("pages.marketplace"); let offers: { id: number; itemId: number; userId: number; price: number; timestamp: number; }[] = []; try { offers = await prisma.marketplaceItems.findMany({ where: { state: STATE_ACTIVE }, select: { id: true, itemId: true, userId: true, price: true, timestamp: true }, orderBy: { timestamp: "desc" }, take: 100, }); } catch { offers = []; } // Resolve seller usernames in a single query (read-only display join). let sellers = new Map(); try { const ids = [...new Set(offers.map((o) => o.userId))]; if (ids.length > 0) { const users = await prisma.user.findMany({ where: { id: { in: ids } }, select: { id: true, username: true }, }); sellers = new Map(users.map((u) => [u.id, u.username])); } } catch { sellers = new Map(); } const total = offers.reduce((sum, o) => sum + o.price, 0); return (
o.userId)).size.toLocaleString()} label={t("sellers")} icon="👥" />
0 ? t("mostRecentFirst") : undefined} padded={offers.length === 0} > {offers.length === 0 ? ( {t("empty")} ) : (
{offers.map((o) => ( ))}
{t("colOffer")} {t("colItem")} {t("colSeller")} {t("colPrice")} {t("colListed")}
#{o.id} {t("itemLabel", { id: o.itemId })} {sellers.get(o.userId) ?? t("userLabel", { id: o.userId })} {o.price.toLocaleString()} cr {listedAgo(o.timestamp, t)}
)}
); }