import { useState, useEffect, useCallback } from 'react' import { ScrollArea } from '@/components/ui/scroll-area' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Switch } from '@/components/ui/switch' import { Slider } from '@/components/ui/slider' import { Textarea } from '@/components/ui/textarea' import { Badge } from '@/components/ui/badge' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' import { ListFieldEditor } from '@/components/ListFieldEditor' import { Alert, AlertDescription } from '@/components/ui/alert' import { CodeEditor } from '@/components' import { parse as parseToml } from 'smol-toml' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Settings, Package, AlertCircle, CheckCircle2, RefreshCw, ChevronRight, ChevronDown, Save, RotateCcw, Power, Loader2, Search, ArrowLeft, Info, Eye, EyeOff, RotateCw, Code2, Layout, } from 'lucide-react' import { useToast } from '@/hooks/use-toast' import { RestartProvider, useRestart } from '@/lib/restart-context' import { RestartOverlay } from '@/components/restart-overlay' import { getInstalledPlugins, getPluginConfigSchema, getPluginConfig, getPluginConfigRaw, updatePluginConfig, updatePluginConfigRaw, resetPluginConfig, togglePlugin, type InstalledPlugin, type PluginConfigSchema, type ConfigFieldSchema, type ConfigSectionSchema, } from '@/lib/plugin-api' // 字段渲染组件 interface FieldRendererProps { field: ConfigFieldSchema value: unknown onChange: (value: unknown) => void sectionName: string } function FieldRenderer({ field, value, onChange }: FieldRendererProps) { const [showPassword, setShowPassword] = useState(false) // 根据 ui_type 渲染不同的控件 switch (field.ui_type) { case 'switch': return (
{field.hint && (

{field.hint}

)}
) case 'number': return (
onChange(parseFloat(e.target.value) || 0)} min={field.min} max={field.max} step={field.step ?? 1} placeholder={field.placeholder} disabled={field.disabled} /> {field.hint && (

{field.hint}

)}
) case 'slider': return (
{value as number ?? field.default}
onChange(v[0])} min={field.min ?? 0} max={field.max ?? 100} step={field.step ?? 1} disabled={field.disabled} /> {field.hint && (

{field.hint}

)}
) case 'select': return (
{field.hint && (

{field.hint}

)}
) case 'textarea': return (