From 856af03b39cc9cd474d684fe23d2c59453084906 Mon Sep 17 00:00:00 2001 From: francy51 Date: Sun, 1 Mar 2026 18:48:59 -0500 Subject: [PATCH] Replace financial trend chart with financial table --- app/analysis/page.tsx | 71 +++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/app/analysis/page.tsx b/app/analysis/page.tsx index e7bf328..e78e70b 100644 --- a/app/analysis/page.tsx +++ b/app/analysis/page.tsx @@ -4,10 +4,7 @@ import Link from 'next/link'; import { Suspense, useCallback, useEffect, useMemo, useState } from 'react'; import { format } from 'date-fns'; import { - Bar, - BarChart, CartesianGrid, - Legend, Line, LineChart, ResponsiveContainer, @@ -29,12 +26,13 @@ import type { CompanyAnalysis } from '@/lib/types'; type FinancialPeriodFilter = 'quarterlyAndFiscalYearEnd' | 'quarterlyOnly' | 'fiscalYearEndOnly'; type FinancialSeriesPoint = { - label: string; + filingDate: string; filingType: '10-K' | '10-Q'; periodLabel: 'Quarter End' | 'Fiscal Year End'; revenue: number | null; netIncome: number | null; assets: number | null; + netMargin: number | null; }; const FINANCIAL_PERIOD_FILTER_OPTIONS: Array<{ value: FinancialPeriodFilter; label: string }> = [ @@ -47,6 +45,18 @@ function formatShortDate(value: string) { return format(new Date(value), 'MMM yyyy'); } +function formatLongDate(value: string) { + return format(new Date(value), 'MMM dd, yyyy'); +} + +function ratioPercent(numerator: number | null, denominator: number | null) { + if (numerator === null || denominator === null || denominator === 0) { + return null; + } + + return (numerator / denominator) * 100; +} + function isFinancialSnapshotForm( filingType: CompanyAnalysis['filings'][number]['filing_type'] ): filingType is '10-K' | '10-Q' { @@ -135,12 +145,13 @@ function AnalysisPageContent() { .slice() .sort((a, b) => Date.parse(a.filingDate) - Date.parse(b.filingDate)) .map((item) => ({ - label: formatShortDate(item.filingDate), + filingDate: item.filingDate, filingType: item.filingType, periodLabel: item.filingType === '10-Q' ? 'Quarter End' : 'Fiscal Year End', revenue: item.revenue, netIncome: item.netIncome, - assets: item.totalAssets + assets: item.totalAssets, + netMargin: ratioPercent(item.netIncome ?? null, item.revenue ?? null) })); }, [analysis?.financials]); @@ -250,8 +261,8 @@ function AnalysisPageContent() { {FINANCIAL_PERIOD_FILTER_OPTIONS.map((option) => ( @@ -271,21 +282,37 @@ function AnalysisPageContent() { {loading ? (

Loading financials...

) : filteredFinancialSeries.length === 0 ? ( -

No filing metrics match the selected period filter.

+

No financial rows match the selected period filter.

) : ( -
- - - - - `$${Math.round(value / 1_000_000_000)}B`} /> - formatCompactCurrency(value)} /> - - - - - - +
+ + + + + + + + + + + + + + {filteredFinancialSeries.map((point, index) => ( + + + + + + + + + + ))} + +
FiledPeriodFormRevenueNet IncomeAssetsNet Margin
{formatLongDate(point.filingDate)}{point.periodLabel}{point.filingType}{point.revenue === null ? 'n/a' : formatCompactCurrency(point.revenue)}= 0 ? 'text-[#96f5bf]' : 'text-[#ff9f9f]'}> + {point.netIncome === null ? 'n/a' : formatCompactCurrency(point.netIncome)} + {point.assets === null ? 'n/a' : formatCompactCurrency(point.assets)}{point.netMargin === null ? 'n/a' : formatPercent(point.netMargin)}
)}