import React, { useEffect, useState } from "react"; import Navbar from "../components/Navbar"; import SettingsSidebar, { type SettingsSection } from "../components/SettingsSidebar"; import LlmSettings from "../components/LlmSettings"; import TradingSettings from "../components/TradingSettings"; import StockTable from "../components/StockTable"; import SystemSettings from "../components/SystemSettings"; interface Stock { id: string; ticker: string; notes: string | null; lastDecision: string | null; lastJobId: string | null; createdAt: string; updatedAt: string; } export default function SettingsPage() { const [activeSection, setActiveSection] = useState("llm"); const [settings, setSettings] = useState>({}); const [stocks, setStocks] = useState([]); const [loading, setLoading] = useState(true); const [saveError, setSaveError] = useState(null); const [alpacaMode, setAlpacaMode] = useState(null); useEffect(() => { Promise.all([ fetch("/api/admin/settings").then((r) => r.json()), fetch("/api/stocks").then((r) => r.json()), fetch("/api/alpaca/account").then((r) => r.ok ? r.json() : null), ]).then(([settingsData, stocksData, accountData]) => { const settingsMap: Record = {}; if (Array.isArray(settingsData)) { settingsData.forEach((s: { key: string; value: any }) => { settingsMap[s.key] = s.value; }); } setSettings(settingsMap); if (Array.isArray(stocksData)) setStocks(stocksData); if (accountData?.trading?.paper !== undefined) { setAlpacaMode(accountData.trading.paper ? "paper" : "live"); } setLoading(false); }).catch((err) => { console.error("Failed to load settings:", err); setLoading(false); }); }, []); const saveSetting = async (key: string, value: any) => { setSaveError(null); const prevValue = settings[key]; setSettings((s) => ({ ...s, [key]: value })); try { const res = await fetch(`/api/admin/settings/${encodeURIComponent(key)}`, { method: "PUT", headers: { "content-type": "application/json" }, body: JSON.stringify({ value }), }); if (!res.ok) { throw new Error(`Failed to save ${key}`); } } catch (err) { setSettings((s) => ({ ...s, [key]: prevValue })); setSaveError(err instanceof Error ? err.message : "Save failed"); } }; const saveStockNotes = async (ticker: string, notes: string) => { setSaveError(null); const prevStocks = [...stocks]; setStocks((s) => s.map((st) => (st.ticker === ticker ? { ...st, notes } : st))); try { const fd = new FormData(); fd.append("ticker", ticker); fd.append("notes", notes); const res = await fetch("/api/stocks", { method: "POST", body: fd }); if (!res.ok) { throw new Error("Failed to save notes"); } } catch (err) { setStocks(prevStocks); setSaveError(err instanceof Error ? err.message : "Save failed"); } }; if (loading) { return (
Loading settings...
); } const renderSection = () => { switch (activeSection) { case "llm": return ; case "trading": return ; case "stocks": return ; case "system": return ; default: return null; } }; return (
{renderSection()}
); }