TradingAgents/ui/features/settings/components/SettingsForm.tsx

100 lines
3.8 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
import { getSettings, updateSettings } from '@/lib/api-client'
import type { SettingsFormState } from '../types'
const DEFAULTS: SettingsFormState = {
deep_think_llm: 'gpt-5.2',
quick_think_llm: 'gpt-5-mini',
max_debate_rounds: 1,
max_risk_discuss_rounds: 1,
}
export default function SettingsForm() {
const [form, setForm] = useState<SettingsFormState>(DEFAULTS)
const [saved, setSaved] = useState(false)
const set = (k: keyof SettingsFormState, v: unknown) =>
setForm((f) => ({ ...f, [k]: v }))
useEffect(() => { getSettings().then(setForm).catch(() => {}) }, [])
const save = async (e: React.FormEvent) => {
e.preventDefault()
await updateSettings(form)
setSaved(true)
setTimeout(() => setSaved(false), 2000)
}
return (
<form onSubmit={save} className="max-w-lg space-y-4">
{/* ── Model Configuration ─────────────────────────────────── */}
<section className="rounded-lg p-6 space-y-4" style={{ background: 'var(--bg-card)', border: '1px solid var(--border)' }}>
<h2
className="apex-label"
style={{ fontFamily: 'var(--font-manrope)' }}
>
Model Configuration
</h2>
{(['deep_think_llm', 'quick_think_llm'] as const).map((key) => (
<div key={key}>
<label className="block text-xs mb-2 capitalize" style={{ color: 'var(--text-mid)' }}>
{key.replace(/_/g, ' ')}
</label>
<input
className="vault-input"
value={form[key]}
onChange={(e) => set(key, e.target.value)}
/>
</div>
))}
</section>
{/* ── Analysis Parameters ─────────────────────────────────── */}
<section className="rounded-lg p-6 space-y-4" style={{ background: 'var(--bg-card)', border: '1px solid var(--border)' }}>
<h2
className="apex-label"
style={{ fontFamily: 'var(--font-manrope)' }}
>
Analysis Parameters
</h2>
{(['max_debate_rounds', 'max_risk_discuss_rounds'] as const).map((key) => (
<div key={key}>
<label className="block text-xs mb-2 capitalize" style={{ color: 'var(--text-mid)' }}>
{key.replace(/_/g, ' ')}
</label>
<input
type="number" min={1} max={5}
className="vault-input"
value={form[key]}
onChange={(e) => set(key, Number(e.target.value))}
/>
</div>
))}
</section>
{/* ── Security notice ─────────────────────────────────────── */}
<div className="rounded-lg px-5 py-3.5 text-xs leading-relaxed" style={{ background: 'var(--bg-elevated)', color: 'var(--text-mid)', border: '1px solid var(--border)' }}>
API keys and secrets are configured via <code style={{ color: 'var(--accent-light)' }} className="font-mono">.env</code> on the server and are not editable here.
</div>
{/* ── Actions ─────────────────────────────────────────────── */}
<div className="flex gap-3 justify-end pt-1">
<button
type="button"
onClick={() => setForm(DEFAULTS)}
className="btn-secondary px-4 py-2.5 text-sm"
>
Reset to Defaults
</button>
<button
type="submit"
className="btn-primary px-5 py-2.5 text-sm"
>
{saved ? '✓ Saved' : 'Save Changes'}
</button>
</div>
</form>
)
}