57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { api } from '@/lib/api';
|
|
|
|
export function ConfigForm() {
|
|
const [configs, setConfigs] = useState<Record<string, string>>({});
|
|
const [saving, setSaving] = useState(false);
|
|
|
|
useEffect(() => {
|
|
api.getConfigs().then((list) => {
|
|
const map: Record<string, string> = {};
|
|
list.forEach((c) => { map[c.key] = JSON.stringify(c.value, null, 2); });
|
|
setConfigs(map);
|
|
});
|
|
}, []);
|
|
|
|
const handleSave = async (key: string, raw: string) => {
|
|
setSaving(true);
|
|
try {
|
|
await api.saveConfig(key, JSON.parse(raw));
|
|
} catch { alert('Invalid JSON'); }
|
|
setSaving(false);
|
|
};
|
|
|
|
const configKeys = [
|
|
{ key: 'api_keys', label: 'API 密钥' },
|
|
{ key: 'defaults', label: '默认参数' },
|
|
{ key: 'endpoints', label: '服务端点' },
|
|
];
|
|
|
|
return (
|
|
<div className="max-w-lg p-6 space-y-6">
|
|
<h2 className="text-lg font-semibold">设置</h2>
|
|
{configKeys.map(({ key, label }) => (
|
|
<div key={key}>
|
|
<label className="text-xs text-zinc-500">{label}</label>
|
|
<textarea
|
|
value={configs[key] || '{}'}
|
|
onChange={(e) => setConfigs((c) => ({ ...c, [key]: e.target.value }))}
|
|
rows={6}
|
|
className="mt-1 w-full rounded-md border border-zinc-800 bg-zinc-900 px-3 py-2 text-sm font-mono resize-y"
|
|
/>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
className="mt-1"
|
|
disabled={saving}
|
|
onClick={() => handleSave(key, configs[key])}
|
|
>
|
|
保存
|
|
</Button>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|