import Link from 'next/link';
import type { ReactNode } from 'react';
import type { AssetCard as AssetCardData } from '@/lib/queries/assets';
import { cn, confidenceLabel, fmtMoney, fmtNum, fmtRelative } from '@/lib/format';
import { catName } from '@/lib/taxonomy';
import { Delta, VsRiv } from '@/components/ui/primitives';
export type TileMetric = 'change7d' | 'change1d' | 'change30d' | 'trending' | 'watchers' | 'riv' | 'opportunity' | 'new' | 'guide' | 'latestSale';
import { TileImage } from '@/components/ui/tile-image';
export { TileImage };
/** Price line: RIV with confidence, or the guide price honestly labelled, or the latest sale. */
export function PriceLine({ a, size = 'md', className }: { a: AssetCardData; size?: 'sm' | 'md' | 'lg'; className?: string }) {
const valueCls = size === 'lg' ? 'text-xl' : size === 'sm' ? 'text-[13px]' : 'text-[15px]';
if (a.rivUsd !== null) {
return (
{fmtMoney(a.rivUsd)}
RIV · {confidenceLabel(a.rivConfidence)} · n={a.rivSampleSize}
);
}
if (a.guideUsd !== null && a.guideUsd !== undefined) {
return (
{fmtMoney(a.guideUsd)}
Guide · {a.guideSource ?? a.guideKind ?? 'observed'}
);
}
if (a.latestSaleUsd !== null) {
return (
{fmtMoney(a.latestSaleUsd)}
Last sale · {fmtRelative(a.latestSaleAt)}
);
}
return (
—
Catalogued · no price yet
);
}
function MetricNode({ a, metric }: { a: AssetCardData; metric: TileMetric }) {
switch (metric) {
case 'change1d':
return
{subtitle}
: null}