diff --git a/components/analysis/company-overview-card.tsx b/components/analysis/company-overview-card.tsx index 1fb56e2..6bb79f0 100644 --- a/components/analysis/company-overview-card.tsx +++ b/components/analysis/company-overview-card.tsx @@ -11,39 +11,46 @@ type CompanyOverviewCardProps = { export function CompanyOverviewCard(props: CompanyOverviewCardProps) { const [expanded, setExpanded] = useState(false); - const description = - props.analysis.companyProfile.description ?? - "No annual filing business description is available yet."; + + // Get the actual business description, filtering out raw data artifacts + const rawDescription = props.analysis.companyProfile.description; + const isRawData = rawDescription && ( + rawDescription.includes('http://') || + rawDescription.includes('P1Y') || + rawDescription.includes('P3Y') || + rawDescription.includes('FY false') + ); + + const description = !rawDescription || isRawData + ? "No business description available." + : rawDescription; + const needsClamp = description.length > 320; + // Combine metadata into a single line + const metadata = [ + props.analysis.company.ticker, + props.analysis.company.sector ?? props.analysis.companyProfile.industry, + props.analysis.company.cik ? `CIK ${props.analysis.company.cik}` : null, + ].filter(Boolean).join(' · '); + return (
+ {/* Header with company name and metadata */}
-
-

- {props.analysis.company.companyName} -

-

- {props.analysis.company.ticker} -

-

- {props.analysis.company.sector ?? - props.analysis.companyProfile.industry ?? - "Sector unavailable"} - {props.analysis.company.category - ? ` · ${props.analysis.company.category}` - : ""} - {props.analysis.company.cik - ? ` · CIK ${props.analysis.company.cik}` - : ""} -

-
+

+ {props.analysis.company.companyName} +

+

+ {metadata} +

+ {/* Business description section */}
-
+

Business description

@@ -58,7 +65,7 @@ export function CompanyOverviewCard(props: CompanyOverviewCardProps) { href={props.analysis.companyProfile.website} target="_blank" rel="noreferrer" - className="inline-flex items-center gap-1 text-xs uppercase tracking-[0.14em] text-[color:var(--accent)] hover:text-[color:var(--accent-strong)]" + className="inline-flex shrink-0 items-center gap-1 text-xs uppercase tracking-[0.14em] text-[color:var(--accent)] hover:text-[color:var(--accent-strong)]" > Website diff --git a/components/analysis/price-history-card.tsx b/components/analysis/price-history-card.tsx index c0cf47d..50702c3 100644 --- a/components/analysis/price-history-card.tsx +++ b/components/analysis/price-history-card.tsx @@ -72,6 +72,8 @@ export function PriceHistoryCard(props: PriceHistoryCardProps) { tickLine={{ stroke: CHART_MUTED }} tick={{ fill: CHART_MUTED }} tickFormatter={(value: number) => `$${value.toFixed(0)}`} + domain={[(dataMin) => dataMin * 0.05, (dataMax) => dataMax * 1.05]} + allowDataOverflow /> formatCurrency(Array.isArray(value) ? value[0] : value)} diff --git a/components/analysis/valuation-facts-table.tsx b/components/analysis/valuation-facts-table.tsx index 6988768..f166e23 100644 --- a/components/analysis/valuation-facts-table.tsx +++ b/components/analysis/valuation-facts-table.tsx @@ -8,18 +8,22 @@ type ValuationFactsTableProps = { }; function formatRatio(value: number | null) { - return value === null ? 'n/a' : `${value.toFixed(2)}x`; + return value === null ? '—' : `${value.toFixed(2)}x`; } function formatShares(value: number | null) { - return value === null ? 'n/a' : formatScaledNumber(value, { maximumFractionDigits: 2 }); + return value === null ? '—' : formatScaledNumber(value, { maximumFractionDigits: 2 }); +} + +function formatCompactCurrencyOrDash(value: number | null) { + return value === null ? '—' : formatCompactCurrency(value); } export function ValuationFactsTable(props: ValuationFactsTableProps) { const items = [ { label: 'Source', value: props.analysis.valuationSnapshot.source }, - { label: 'Market cap', value: props.analysis.valuationSnapshot.marketCap === null ? 'n/a' : formatCompactCurrency(props.analysis.valuationSnapshot.marketCap) }, - { label: 'Enterprise value', value: props.analysis.valuationSnapshot.enterpriseValue === null ? 'n/a' : formatCompactCurrency(props.analysis.valuationSnapshot.enterpriseValue) }, + { label: 'Market cap', value: formatCompactCurrencyOrDash(props.analysis.valuationSnapshot.marketCap) }, + { label: 'Enterprise value', value: formatCompactCurrencyOrDash(props.analysis.valuationSnapshot.enterpriseValue) }, { label: 'Shares outstanding', value: formatShares(props.analysis.valuationSnapshot.sharesOutstanding) }, { label: 'Trailing P/E', value: formatRatio(props.analysis.valuationSnapshot.trailingPe) }, { label: 'EV / Revenue', value: formatRatio(props.analysis.valuationSnapshot.evToRevenue) }, diff --git a/next-env.d.ts b/next-env.d.ts index c4b7818..9edff1c 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.