diff options
Diffstat (limited to 'frontend/app/page.tsx')
| -rw-r--r-- | frontend/app/page.tsx | 48 |
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> ); |
