import type { SaleRow, ListingRow } from '@/lib/queries/assets'; import type { LotRow } from '@/lib/queries/market-lists'; import { fmtDate, fmtMoney, fmtRelative, fmtPct, cn } from '@/lib/format'; import { humanize } from '@/lib/taxonomy'; import { Table, th, td, tdNum, EmptyState, Badge, VsRiv } from '@/components/ui/primitives'; import { AllInCell, AssetTitleCell, FeeBasisPill, GradeBadge, PriceCell, SourceLink, Thumb, VerificationBadge } from './bits'; /** Card list for sales on small screens (image, title, grade, price, source). */ export function SalesCards({ items, className }: { items: SaleRow[]; className?: string }) { return ( ); } export function SalesTable({ items, showAsset = true, className, emptyDescription = 'Sales appear once connectors ingest verified transactions.', responsive = true }: { items: SaleRow[]; showAsset?: boolean; className?: string; emptyDescription?: string; responsive?: boolean }) { if (!items.length) return ; if (responsive) { return ( <>
); } return ( {showAsset ? : } {items.map((s) => ( ))}
DateAssetListing titleGrade Price Type Source Quality
{fmtDate(s.saleDate)} {showAsset && s.assetSlug ? ( ) : ( {s.rawTitle} )} {s.condition ? {humanize(s.condition)} : null} {s.allInUsd !== null && Math.abs(s.allInUsd - s.priceUsd) >= 0.5 ? ( {fmtMoney(s.priceUsd)} hammer{s.currency !== 'USD' ? ` · ${fmtMoney(s.price, s.currency)}` : ''} ) : ( {s.feeBasis && s.feeBasis !== 'none' ? : null} )} {humanize(s.saleType)} {s.auctionHouse ? {s.auctionHouse} : null} {Math.round(s.confidence * 100)}% {s.flags.length ? ⚑ : null}
); } export function ListingsCards({ items, className }: { items: ListingRow[]; className?: string }) { return ( ); } export function ListingsTable({ items, showAsset = true, className, emptyDescription = 'Live listings appear once marketplace connectors run.', responsive = true }: { items: ListingRow[]; showAsset?: boolean; className?: string; emptyDescription?: string; responsive?: boolean }) { if (!items.length) return ; if (responsive) { return ( <>
); } return ( {showAsset ? : } {items.map((l) => ( ))}
AssetListingGrade Ask vs RIV Type Seller · location Source Seen
{showAsset && l.assetSlug ? ( ) : ( {l.rawTitle} )} {l.condition ? {humanize(l.condition)} : null} {l.shippingCost ? +{fmtMoney(l.shippingCost, l.currency ?? 'USD')} ship : null} {l.discountToRiv === null ? ( — ) : ( {l.assetRivUsd !== undefined && l.assetRivUsd !== null ? RIV {fmtMoney(l.assetRivUsd)} : null} )} {humanize(l.listingType)} {l.bidCount !== null ? {l.bidCount} bids : null} {l.endsAt ? ends {fmtRelative(l.endsAt)} : null} {l.seller ?? '—'} {l.location ? {l.location} : null} {fmtRelative(l.lastSeenAt)}
); } export function LotsTable({ items, className, emptyDescription = 'Auction lots appear once auction-house connectors run.' }: { items: LotRow[]; className?: string; emptyDescription?: string }) { if (!items.length) return ; return ( {items.map((l) => ( ))}
Lot Auction Estimate Bid / hammer RIV Ends Status
{l.lotNumber ? `Lot ${l.lotNumber} · ` : ''} {l.title} {l.assetSlug ? ( {l.assetTitle} ) : ( Not yet matched to a canonical asset )} {l.auctionHouse} {l.auctionName ? {l.auctionName} : null} {l.estimateLow !== null || l.estimateHigh !== null ? `${fmtMoney(l.estimateLow, l.currency ?? 'USD')} – ${fmtMoney(l.estimateHigh, l.currency ?? 'USD')}` : '—'} {l.hammerPrice !== null ? {fmtMoney(l.hammerPrice, l.currency ?? 'USD')} : l.currentBid !== null ? fmtMoney(l.currentBid, l.currency ?? 'USD') : '—'} {fmtMoney(l.rivUsd)} {l.endsAt ? `${fmtDate(l.endsAt, { time: true })} (${fmtRelative(l.endsAt)})` : '—'} {l.status}
); } export function pctLabel(v: number | null): string { return fmtPct(v); }