summaryrefslogtreecommitdiff
path: root/frontend/app/page.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/app/page.tsx')
-rw-r--r--frontend/app/page.tsx48
1 files changed, 34 insertions, 14 deletions
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx
index 02bd706..41408b0 100644
--- a/frontend/app/page.tsx
+++ b/frontend/app/page.tsx
@@ -377,12 +377,12 @@ function SignalCard({ overview }: { overview: TickerOverview }) {
<h2 className="psm-card-title">Readthrough</h2>
</div>
</div>
- <div className="psm-signal-grid">
+ <div className="psm-signal-list">
{overview.signals.map((signal) => (
- <article key={signal.key} className={`psm-signal ${signalTone(signal.state)}`}>
+ <article key={signal.key} className={`psm-signal-row ${signalTone(signal.state)}`}>
<span className="psm-signal-key">{signal.key}</span>
- <span className="psm-signal-value">{signal.value}</span>
<span className="psm-signal-copy">{signal.description}</span>
+ <span className="psm-signal-value">{signal.value}</span>
</article>
))}
</div>
@@ -392,12 +392,14 @@ function SignalCard({ overview }: { overview: TickerOverview }) {
function DataStatusCard({ overview, missingFields }: { overview: TickerOverview; missingFields: string[] }) {
const entries = Object.entries(overview.meta.sources).slice(0, 6);
+ const visibleMissing = missingFields.slice(0, 4);
+ const hiddenMissingCount = Math.max(0, missingFields.length - visibleMissing.length);
return (
<section className="psm-card">
<div className="psm-card-head">
<div>
- <div className="psm-eyebrow">Data Quality</div>
+ <div className="psm-eyebrow">Coverage</div>
<h2 className="psm-card-title">Coverage</h2>
</div>
<span className={`psm-status-chip${overview.meta.is_partial ? " partial" : ""}`}>{overview.meta.status}</span>
@@ -405,7 +407,8 @@ function DataStatusCard({ overview, missingFields }: { overview: TickerOverview;
<p className="psm-quality-copy">{availableFieldSummary(overview)}</p>
{overview.meta.is_partial ? (
<div className="psm-stack">
- {missingFields.length ? missingFields.slice(0, 8).map((field) => <span key={field} className="psm-field-tag missing">{field}</span>) : null}
+ {missingFields.length ? visibleMissing.map((field) => <span key={field} className="psm-field-tag missing">{field}</span>) : null}
+ {hiddenMissingCount ? <span className="psm-field-tag missing">+{hiddenMissingCount} more</span> : null}
</div>
) : null}
<div className="psm-source-list">
@@ -433,7 +436,7 @@ function ProfileCard({ overview }: { overview: TickerOverview }) {
<div className="psm-card-head">
<div>
<div className="psm-eyebrow">Company Profile</div>
- <h2 className="psm-card-title">Context</h2>
+ <h2 className="psm-card-title">Company Profile</h2>
</div>
</div>
<div className="psm-profile-list">
@@ -474,7 +477,7 @@ function ShortInterestCard({ overview }: { overview: TickerOverview }) {
<div className="psm-card-head">
<div>
<div className="psm-eyebrow">Short Interest</div>
- <h2 className="psm-card-title">Pressure</h2>
+ <h2 className="psm-card-title">Short Interest</h2>
</div>
</div>
<div className="psm-detail-grid">
@@ -488,21 +491,38 @@ function ShortInterestCard({ overview }: { overview: TickerOverview }) {
}
function StatsCard({ overview }: { overview: TickerOverview }) {
+ const referenceRows = [
+ { label: "Market Cap", value: fmtLarge(overview.stats.market_cap), missing: overview.stats.market_cap == null },
+ { label: "P/E TTM", value: overview.stats.trailing_pe == null ? "-" : `${fmtNumber(overview.stats.trailing_pe)}x`, missing: overview.stats.trailing_pe == null },
+ { label: "EPS TTM", value: fmtCurrency(overview.stats.trailing_eps), missing: overview.stats.trailing_eps == null },
+ { label: "P/B", value: overview.ratios.price_to_book == null ? "-" : `${fmtNumber(overview.ratios.price_to_book)}x`, missing: overview.ratios.price_to_book == null },
+ { label: "P/S", value: overview.ratios.price_to_sales == null ? "-" : `${fmtNumber(overview.ratios.price_to_sales)}x`, missing: overview.ratios.price_to_sales == null },
+ { label: "EV/Sales", value: overview.ratios.ev_to_sales == null ? "-" : `${fmtNumber(overview.ratios.ev_to_sales)}x`, missing: overview.ratios.ev_to_sales == null },
+ { label: "EV/EBITDA", value: overview.ratios.ev_to_ebitda == null ? "-" : `${fmtNumber(overview.ratios.ev_to_ebitda)}x`, missing: overview.ratios.ev_to_ebitda == null },
+ { label: "Gross Margin", value: fmtPct(overview.ratios.gross_margin_ttm), missing: overview.ratios.gross_margin_ttm == null },
+ { label: "Op Margin", value: fmtPct(overview.ratios.operating_margin_ttm), missing: overview.ratios.operating_margin_ttm == null },
+ { label: "Net Margin", value: fmtPct(overview.ratios.net_margin_ttm), missing: overview.ratios.net_margin_ttm == null },
+ { label: "ROE", value: fmtPct(overview.ratios.roe_ttm), missing: overview.ratios.roe_ttm == null },
+ { label: "ROA", value: fmtPct(overview.ratios.roa_ttm), missing: overview.ratios.roa_ttm == null },
+ { label: "ROIC", value: fmtPct(overview.ratios.roic_ttm), missing: overview.ratios.roic_ttm == null },
+ { label: "D/E", value: overview.ratios.debt_to_equity == null ? "-" : `${fmtNumber(overview.ratios.debt_to_equity)}x`, missing: overview.ratios.debt_to_equity == null },
+ { label: "Current Ratio", value: overview.ratios.current_ratio == null ? "-" : `${fmtNumber(overview.ratios.current_ratio)}x`, missing: overview.ratios.current_ratio == null },
+ { label: "Dividend Yield", value: fmtPct(overview.ratios.dividend_yield_ttm), missing: overview.ratios.dividend_yield_ttm == null },
+ { label: "Payout Ratio", value: fmtPct(overview.ratios.dividend_payout_ratio_ttm), missing: overview.ratios.dividend_payout_ratio_ttm == null }
+ ];
+
return (
<section className="psm-card">
<div className="psm-card-head">
<div>
- <div className="psm-eyebrow">Overview Stats</div>
+ <div className="psm-eyebrow">Reference</div>
<h2 className="psm-card-title">Reference</h2>
</div>
</div>
<div className="psm-stat-list">
- <StatRow label="Market Cap" value={fmtLarge(overview.stats.market_cap)} missing={overview.stats.market_cap == null} />
- <StatRow label="P/E TTM" value={fmtNumber(overview.stats.trailing_pe)} missing={overview.stats.trailing_pe == null} />
- <StatRow label="EPS TTM" value={fmtCurrency(overview.stats.trailing_eps)} missing={overview.stats.trailing_eps == null} />
- <StatRow label="Volume" value={fmtNumber(overview.stats.volume, 0)} missing={overview.stats.volume == null} />
- <StatRow label="Avg Volume" value={fmtNumber(overview.stats.average_volume, 0)} missing={overview.stats.average_volume == null} />
- <StatRow label="Beta" value={fmtNumber(overview.stats.beta)} missing={overview.stats.beta == null} />
+ {referenceRows.map((row) => (
+ <StatRow key={row.label} label={row.label} value={row.value} missing={row.missing} />
+ ))}
</div>
</section>
);