import type { Metadata } from 'next'; import Link from 'next/link'; import { PageHeader } from '@/components/ui/page-header'; import { MarketTable } from '@/components/market/market-table'; import { getMarketRows } from '@/lib/queries/markets'; import { listIndices } from '@/lib/queries/indices'; import { fmtNum } from '@/lib/format'; export const metadata: Metadata = { title: 'Markets', description: 'Collectible category markets: index performance, sales, volume, listings, liquidity and market capitalization estimates.' }; export const revalidate = 300; export default async function MarketsPage() { const [rows, indices] = await Promise.all([getMarketRows(), listIndices()]); const active = rows.filter((r) => r.counts.assets > 0); const totals = active.reduce((a, r) => ({ assets: a.assets + r.counts.assets, sales: a.sales + r.counts.sales, listings: a.listings + r.counts.listings }), { assets: 0, sales: 0, listings: 0 }); const published = indices.filter((i) => i.latest).length; return (
{fmtNum(active.length)} families with data · {fmtNum(totals.assets)} assets · {fmtNum(totals.sales)} sales · {fmtNum(totals.listings)} active listings · {published}/{indices.length} indices published · Heatmap view → } />

Market capitalization estimates multiply an estimated population by a representative value and are shown only with their confidence label; they are indicative, never precise (§124). Listing prices are not confirmed transactions.

); }