summaryrefslogtreecommitdiff
path: root/frontend/components/prism/FinancialsPage.tsx
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-18 22:18:20 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-18 22:18:20 -0700
commit16d9eb4f864fe8c29a9dee57ec47f77b34ae0df4 (patch)
tree36d56f7ed8bc5d893fafce807f7846e6c320b1cc /frontend/components/prism/FinancialsPage.tsx
parent566f59cb00958caa073279a7bb698e1ede48c0d4 (diff)
feat: wire Ratios subtab into FinancialsPage, move tab strip up from FinancialsCard
Diffstat (limited to 'frontend/components/prism/FinancialsPage.tsx')
-rw-r--r--frontend/components/prism/FinancialsPage.tsx68
1 files changed, 50 insertions, 18 deletions
diff --git a/frontend/components/prism/FinancialsPage.tsx b/frontend/components/prism/FinancialsPage.tsx
index fcd2763..9a56f2c 100644
--- a/frontend/components/prism/FinancialsPage.tsx
+++ b/frontend/components/prism/FinancialsPage.tsx
@@ -4,10 +4,12 @@ import { api } from "@/lib/api";
import { buildKpis } from "@/lib/overview";
import { FinancialsCard } from "@/components/prism/FinancialsCard";
import { KPIStrip } from "@/components/prism/KPIStrip";
+import { RatiosPage } from "@/components/prism/RatiosPage";
import { TickerHeader } from "@/components/prism/TickerHeader";
import type { FinancialsResponse, TickerOverview } from "@/types/api";
-type StatementKey = "income" | "balance" | "cash_flow";
+type StatementKey = "income" | "balance" | "cash_flow" | "ratios";
+type FinancialStatementKey = Exclude<StatementKey, "ratios">;
type PeriodKey = "annual" | "quarterly";
type FinState = "loading" | "ready" | "error";
@@ -18,6 +20,13 @@ type Props = {
onToggleWatchlist: () => void;
};
+const STATEMENT_LABELS: Record<StatementKey, string> = {
+ income: "INCOME",
+ balance: "BALANCE",
+ cash_flow: "CASH FLOW",
+ ratios: "RATIOS",
+};
+
export function FinancialsPage({ ticker, overview, isSaved, onToggleWatchlist }: Props) {
const [statement, setStatement] = useState<StatementKey>("income");
const [period, setPeriod] = useState<PeriodKey>("annual");
@@ -26,6 +35,10 @@ export function FinancialsPage({ ticker, overview, isSaved, onToggleWatchlist }:
const kpis = buildKpis(overview);
useEffect(() => {
+ if (statement === "ratios") {
+ return;
+ }
+
let cancelled = false;
setFinState("loading");
setData(null);
@@ -45,28 +58,47 @@ export function FinancialsPage({ ticker, overview, isSaved, onToggleWatchlist }:
return () => {
cancelled = true;
};
- }, [ticker, period]);
+ }, [ticker, period, statement]);
return (
<>
<TickerHeader overview={overview} isSaved={isSaved} onToggleWatchlist={onToggleWatchlist} />
<KPIStrip items={kpis} />
- {finState === "loading" && (
- <section className="psm-card psm-skeleton" style={{ minHeight: 320 }} />
- )}
- {finState === "error" && (
- <section className="psm-card">
- <p className="psm-muted-copy">Financial statements unavailable for {ticker}.</p>
- </section>
- )}
- {finState === "ready" && data && (
- <FinancialsCard
- data={data}
- statement={statement}
- period={period}
- onChangeStatement={setStatement}
- onChangePeriod={setPeriod}
- />
+ <section className="psm-fin-tab-bar">
+ <div className="psm-fin-tabs">
+ {(["income", "balance", "cash_flow", "ratios"] as StatementKey[]).map((key) => (
+ <button
+ key={key}
+ type="button"
+ className={`psm-fin-tab${statement === key ? " active" : ""}`}
+ onClick={() => setStatement(key)}
+ >
+ {STATEMENT_LABELS[key]}
+ </button>
+ ))}
+ </div>
+ </section>
+ {statement === "ratios" ? (
+ <RatiosPage ticker={ticker} />
+ ) : (
+ <>
+ {finState === "loading" && (
+ <section className="psm-card psm-skeleton" style={{ minHeight: 320 }} />
+ )}
+ {finState === "error" && (
+ <section className="psm-card">
+ <p className="psm-muted-copy">Financial statements unavailable for {ticker}.</p>
+ </section>
+ )}
+ {finState === "ready" && data && (
+ <FinancialsCard
+ data={data}
+ statement={statement as FinancialStatementKey}
+ period={period}
+ onChangePeriod={setPeriod}
+ />
+ )}
+ </>
)}
</>
);