summaryrefslogtreecommitdiff
path: root/frontend/components/prism/ChartCard.tsx
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-17 13:07:40 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-17 13:07:40 -0700
commit62bdd79b3473262dde5fb0a90eab34fe7bf344fd (patch)
tree84f75baf7503e1df77c8335750650a72b088468a /frontend/components/prism/ChartCard.tsx
parent1482422f2f5b236cdcdff4429ae06bb55dca4083 (diff)
'UI Shell and General Architecture'
Diffstat (limited to 'frontend/components/prism/ChartCard.tsx')
-rw-r--r--frontend/components/prism/ChartCard.tsx55
1 files changed, 55 insertions, 0 deletions
diff --git a/frontend/components/prism/ChartCard.tsx b/frontend/components/prism/ChartCard.tsx
new file mode 100644
index 0000000..bc650d7
--- /dev/null
+++ b/frontend/components/prism/ChartCard.tsx
@@ -0,0 +1,55 @@
+import { PriceChart } from "@/components/PriceChart";
+import type { HistoryPoint } from "@/types/api";
+
+const PERIODS = [
+ { key: "1m", label: "1M" },
+ { key: "3m", label: "3M" },
+ { key: "6m", label: "6M" },
+ { key: "1y", label: "1Y" },
+ { key: "5y", label: "5Y" }
+];
+
+type Props = {
+ symbol: string;
+ period: string;
+ points: HistoryPoint[];
+ chartState: "idle" | "loading" | "ready" | "error";
+ chartError: string | null;
+ onChangePeriod: (period: string) => void;
+};
+
+export function ChartCard({ symbol, period, points, chartState, chartError, onChangePeriod }: Props) {
+ return (
+ <section className="psm-card">
+ <div className="psm-card-head">
+ <div>
+ <div className="psm-eyebrow">Price History</div>
+ <h2 className="psm-card-title">{symbol}</h2>
+ </div>
+ <div className="psm-tabs" role="tablist" aria-label="Chart range">
+ {PERIODS.map((option) => (
+ <button
+ key={option.key}
+ type="button"
+ role="tab"
+ className={`psm-tab${period === option.key ? " active" : ""}`}
+ aria-selected={period === option.key}
+ onClick={() => onChangePeriod(option.key)}
+ >
+ {option.label}
+ </button>
+ ))}
+ </div>
+ </div>
+
+ <p className="psm-chart-meta">Chart loading is isolated from the rest of Overview. A history miss only affects this card.</p>
+
+ <div className="psm-chart-frame">
+ {chartState === "loading" ? <div className="psm-card-empty">Loading {period.toUpperCase()} history…</div> : null}
+ {chartState === "error" ? <div className="psm-card-empty psm-error-copy">{chartError || "Could not load chart history."}</div> : null}
+ {chartState === "ready" ? <PriceChart symbol={symbol} points={points} /> : null}
+ </div>
+ </section>
+ );
+}
+