import Link from 'next/link'; import { ExternalLink } from 'lucide-react'; import { cn, fmtMoney } from '@/lib/format'; import { catName, gradeLabel } from '@/lib/taxonomy'; import { Badge } from '@/components/ui/primitives'; /** Small shared building blocks for market tables and cards. */ import { Thumb } from '@/components/ui/tile-image'; export { Thumb }; export function CategoryTag({ slug, className }: { slug: string | null | undefined; className?: string }) { if (!slug) return null; return ( {catName(slug)} ); } export function GradeBadge({ grader, grade, className }: { grader: string | null | undefined; grade: string | null | undefined; className?: string }) { const label = gradeLabel(grader, grade); if (!label) return —; return ( {label} ); } /** §178: source attribution with outbound link. */ export function SourceLink({ name, url, className }: { name: string; url: string | null | undefined; className?: string }) { if (!url) return {name}; return ( {name} ); } export function PriceCell({ usd, native, currency, className }: { usd: number | null | undefined; native?: number | null; currency?: string | null; className?: string }) { const showNative = native !== null && native !== undefined && currency && currency !== 'USD'; return ( {fmtMoney(usd)} {showNative ? {fmtMoney(native, currency!)} : null} ); } export function AssetTitleCell({ slug, title, categorySlug, image, sub, size = 36 }: { slug: string; title: string; categorySlug?: string | null; image?: string | null; sub?: string | null; size?: number }) { return ( {title} {categorySlug ? catName(categorySlug) : null} {sub ? (categorySlug ? ` · ${sub}` : sub) : null} ); } /** Heuristic sale verification label (§39, §205): verified · likely · unverified · excluded. Never a claim of independent confirmation. */ export function VerificationBadge({ label, reason, className }: { label: 'verified' | 'likely' | 'unverified' | 'excluded'; reason?: string; className?: string }) { const tone = label === 'verified' ? 'gain' : label === 'likely' ? 'neutral' : 'alert'; const text = label === 'verified' ? 'Verified' : label === 'likely' ? 'Likely' : label === 'unverified' ? 'Unverified' : 'Excluded'; return ( {text} ); }