import { useState, useEffect } from 'react'
import { Settings, MessageSquare, Play, Sun, Moon, Download, Save } from 'lucide-react'
import ChatInterface from './components/ChatInterface'
import AgentInterface from './components/AgentInterface'
import ExportDialog from './components/ExportDialog'
const DEFAULT_CONFIG = {
supplier: 'https://openrouter.ai/api/v1',
apiKey: '',
model: 'nvidia/nemotron-3-ultra-550b-a55b:free',
}
const CONFIG_KEY = 'agentStudioConfig'
const CONFIGS_KEY = 'agentStudioConfigs'
function loadInitialConfig() {
try {
const raw = localStorage.getItem(CONFIG_KEY)
if (raw) return { ...DEFAULT_CONFIG, ...JSON.parse(raw) }
} catch { /* 讀取失敗就用預設值 */ }
return DEFAULT_CONFIG
}
function SettingsModal({ apiConfig, onApply, onDuplicate, savedConfigs, onLoadSaved, onClose }) {
const [draft, setDraft] = useState(apiConfig)
const set = (field, value) => setDraft({ ...draft, [field]: value })
return (
API 連線設定
{savedConfigs.length > 0 && (
已儲存配置(點一下套用):
{savedConfigs.map((c, i) => (
))}
)}
)
}
function App() {
const [view, setView] = useState('chat')
const [showSettings, setShowSettings] = useState(false)
const [showExport, setShowExport] = useState(false)
const [theme, setTheme] = useState(() => localStorage.getItem('theme') || 'dark')
const [apiConfig, setApiConfig] = useState(loadInitialConfig)
const [savedConfigs, setSavedConfigs] = useState(() => {
try {
return JSON.parse(localStorage.getItem(CONFIGS_KEY) || '[]')
} catch {
return []
}
})
useEffect(() => {
document.documentElement.classList.remove('theme-dark', 'theme-light')
document.documentElement.classList.add(`theme-${theme}`)
localStorage.setItem('theme', theme)
}, [theme])
// 金鑰與模型設定即時寫回 localStorage,重新整理不丟失
useEffect(() => {
localStorage.setItem(CONFIG_KEY, JSON.stringify(apiConfig))
}, [apiConfig])
const applyConfig = (config) => {
setApiConfig(config)
setShowSettings(false)
}
const duplicateConfig = () => {
const updated = [...savedConfigs, apiConfig]
setSavedConfigs(updated)
localStorage.setItem(CONFIGS_KEY, JSON.stringify(updated))
setShowSettings(false)
}
return (
Agent Studio
{view === 'chat' ? (
) : (
setShowSettings(true)} />
)}
{showSettings && (
applyConfig(c)}
onClose={() => setShowSettings(false)}
/>
)}
{showExport && setShowExport(false)} />}
)
}
export default App