From 62bdd79b3473262dde5fb0a90eab34fe7bf344fd Mon Sep 17 00:00:00 2001
From: Tyler Hoang <tyler@tylerhoang.xyz>
Date: Sun, 17 May 2026 13:07:40 -0700
Subject: 'UI Shell and General Architecture'

---
 frontend/components/prism/ChartCard.tsx | 55 +++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 frontend/components/prism/ChartCard.tsx

(limited to 'frontend/components/prism/ChartCard.tsx')

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>
+  );
+}
+
-- 
cgit v1.3-2-g0d8e

