37 lines
1.6 KiB
TypeScript
37 lines
1.6 KiB
TypeScript
import type { CompanyValuationSnapshot } from '@/lib/types';
|
|
import { formatCompactCurrency, formatScaledNumber } from '@/lib/format';
|
|
|
|
type ValuationStatGridProps = {
|
|
valuation: CompanyValuationSnapshot;
|
|
};
|
|
|
|
function formatRatio(value: number | null) {
|
|
return value === null ? 'n/a' : `${value.toFixed(2)}x`;
|
|
}
|
|
|
|
function formatShares(value: number | null) {
|
|
return value === null ? 'n/a' : formatScaledNumber(value, { maximumFractionDigits: 2 });
|
|
}
|
|
|
|
export function ValuationStatGrid(props: ValuationStatGridProps) {
|
|
const items = [
|
|
{ label: 'Market cap', value: props.valuation.marketCap === null ? 'n/a' : formatCompactCurrency(props.valuation.marketCap) },
|
|
{ label: 'Enterprise value', value: props.valuation.enterpriseValue === null ? 'n/a' : formatCompactCurrency(props.valuation.enterpriseValue) },
|
|
{ label: 'Shares out.', value: formatShares(props.valuation.sharesOutstanding) },
|
|
{ label: 'Trailing P/E', value: formatRatio(props.valuation.trailingPe) },
|
|
{ label: 'EV / Revenue', value: formatRatio(props.valuation.evToRevenue) },
|
|
{ label: 'EV / EBITDA', value: formatRatio(props.valuation.evToEbitda) }
|
|
];
|
|
|
|
return (
|
|
<div className="grid gap-3 sm:grid-cols-2">
|
|
{items.map((item) => (
|
|
<div key={item.label} className="rounded-2xl border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] p-3">
|
|
<p className="text-xs uppercase tracking-[0.14em] text-[color:var(--terminal-muted)]">{item.label}</p>
|
|
<p className="mt-2 text-lg font-semibold text-[color:var(--terminal-bright)]">{item.value}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|