From 538b4b62d218cbfc1ba8b4c4ea849a5cd56045d5 Mon Sep 17 00:00:00 2001 From: Henry Winkel Date: Sat, 16 May 2026 14:16:37 +0200 Subject: [PATCH] MostActiveStocks: add Save button to upsert ticker and trigger background trading graph; show saving/saved state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- app/components/MostActiveStocks.tsx | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/app/components/MostActiveStocks.tsx b/app/components/MostActiveStocks.tsx index 840d9b6..7f5fb79 100644 --- a/app/components/MostActiveStocks.tsx +++ b/app/components/MostActiveStocks.tsx @@ -21,6 +21,8 @@ export default function MostActiveStocks() { const [stocks, setStocks] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [saving, setSaving] = useState>({}); + const [saved, setSaved] = useState>({}); const fetchData = useCallback(async () => { try { @@ -46,6 +48,29 @@ export default function MostActiveStocks() { return () => clearInterval(interval); }, [fetchData]); + const handleSave = async (symbol: string) => { + setSaving((p) => ({ ...p, [symbol]: true })); + setSaved((p) => ({ ...p, [symbol]: false })); + try { + const res = await fetch("/api/stocks", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ symbol }), + }); + if (!res.ok) { + const data = await res.json().catch(() => null); + throw new Error(data?.error || "Failed to save stock"); + } + // trigger analysis in background (non-blocking) + fetch(`/api/analyze`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ticker: symbol }) }).catch(() => {}); + setSaved((p) => ({ ...p, [symbol]: true })); + } catch (err) { + console.error(err); + } finally { + setSaving((p) => ({ ...p, [symbol]: false })); + } + }; + if (loading) { return (
@@ -104,6 +129,7 @@ export default function MostActiveStocks() { Price Change % Volume + Actions @@ -123,6 +149,21 @@ export default function MostActiveStocks() { {formatChangePercent(stock.changePercent)} {formatVolume(stock.volume)} + + + ))}