import Link from 'next/link'; import type { AssetCard as AssetCardData, SaleRow } from '@/lib/queries/assets'; import type { RadarRow, LotRow } from '@/lib/queries/market-lists'; import type { LatestSale } from '@/lib/queries/site'; import type { MarketRow } from '@/lib/queries/markets'; import { fmtMoney, fmtRelative, fmtNum, cn, fmtDate } from '@/lib/format'; import { catName, humanize } from '@/lib/taxonomy'; import { Card, CardHeader, Delta, EmptyState } from '@/components/ui/primitives'; import { GradeBadge, SourceLink, Thumb } from '@/components/market/bits'; import { heatStyle } from '@/components/charts/heat'; function Row({ href, image, title, sub, right, rightSub }: { href: string; image?: string | null; title: string; sub?: string | null; right: React.ReactNode; rightSub?: React.ReactNode }) { return (
  • {title} {sub ? {sub} : null} {right} {rightSub ? {rightSub} : null}
  • ); } const EMPTY = 'Populates as the pipeline ingests data.'; export function AssetRail({ title, subtitle, href, items, metric, empty = EMPTY }: { title: string; subtitle?: string; href: string; items: AssetCardData[]; metric: 'change7d' | 'change1d' | 'change30d' | 'trending' | 'watchers' | 'riv' | 'opportunity' | 'new' | 'guide'; empty?: string }) { return ( View all →} /> {items.length ? ( ) : ( )} ); } export function SalesRail({ title, subtitle, href, items, hideWhenEmpty = false }: { title: string; subtitle?: string; href: string; items: SaleRow[]; hideWhenEmpty?: boolean }) { if (hideWhenEmpty && !items.length) return null; return ( View all →} /> {items.length ? ( ) : ( )} ); } export function RadarRail({ items, hideWhenEmpty = false }: { items: RadarRow[]; hideWhenEmpty?: boolean }) { if (hideWhenEmpty && !items.length) return null; return ( Open radar →} /> {items.length ? ( ) : ( )} ); } export function LotsRail({ items, hideWhenEmpty = false }: { items: LotRow[]; hideWhenEmpty?: boolean }) { if (hideWhenEmpty && !items.length) return null; return ( All auctions →} /> {items.length ? ( ) : ( )} ); } export function MarketInsights({ rows }: { rows: MarketRow[] }) { const withData = rows.filter((r) => r.counts.assets > 0); return ( Markets →} /> {withData.length ? ( ) : ( )} ); } export interface LatestObservation { id: string; assetSlug: string; assetTitle: string; categorySlug: string; heroImageUrl: string | null; priceUsd: number; priceKind: string; observationDate: string; sourceName: string; } export function LatestTransactions({ items, observations = [] }: { items: LatestSale[]; observations?: LatestObservation[] }) { if (!items.length && observations.length) { return ( Browse →} /> ); } return ( All sales →} /> {items.length ? ( ) : ( )} ); } export function cls(...c: Array): string { return cn(...c); }