diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-18 22:15:42 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-18 22:15:42 -0700 |
| commit | 566f59cb00958caa073279a7bb698e1ede48c0d4 (patch) | |
| tree | 58bba0a7a3efe3d97349d397e957204e5260a11e /frontend | |
| parent | 257c25be1d5b6cba422ffe4f8bc2a31e76e1c68e (diff) | |
feat: add RatiosPage data-fetch wrapper
Diffstat (limited to 'frontend')
| -rw-r--r-- | frontend/components/prism/RatiosPage.tsx | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/frontend/components/prism/RatiosPage.tsx b/frontend/components/prism/RatiosPage.tsx new file mode 100644 index 0000000..26868f8 --- /dev/null +++ b/frontend/components/prism/RatiosPage.tsx @@ -0,0 +1,57 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { api } from "@/lib/api"; +import { RatiosCard } from "@/components/prism/RatiosCard"; +import type { RatiosResponse } from "@/types/api"; + +type RatiosState = "loading" | "ready" | "error"; + +type Props = { + ticker: string; +}; + +export function RatiosPage({ ticker }: Props) { + const [data, setData] = useState<RatiosResponse | null>(null); + const [ratiosState, setRatiosState] = useState<RatiosState>("loading"); + + useEffect(() => { + let cancelled = false; + setRatiosState("loading"); + setData(null); + + api + .ratios(ticker) + .then((res) => { + if (!cancelled) { + setData(res); + setRatiosState("ready"); + } + }) + .catch(() => { + if (!cancelled) setRatiosState("error"); + }); + + return () => { + cancelled = true; + }; + }, [ticker]); + + if (ratiosState === "loading") { + return <section className="psm-card psm-skeleton" style={{ minHeight: 320 }} />; + } + + if (ratiosState === "error") { + return ( + <section className="psm-card"> + <p className="psm-muted-copy">Ratio data unavailable for {ticker}.</p> + </section> + ); + } + + if (ratiosState === "ready" && data) { + return <RatiosCard data={data} />; + } + + return null; +} |
