import { useEffect, useState } from 'react'; import axios from 'axios'; import { useAppStore } from '../../store/appStore'; import { Power, PowerOff, Terminal, ShieldCheck, Plus, Bot, Cpu, Layers, RefreshCw } from 'lucide-react'; import { CreateBotModal } from './components/CreateBotModal'; import { KernelManagerModal } from './components/KernelManagerModal'; import { APP_ENDPOINTS } from '../../config/env'; import { pickLocale } from '../../i18n'; import { managementZhCn } from '../../i18n/management.zh-cn'; import { managementEn } from '../../i18n/management.en'; import { useLucentPrompt } from '../../components/lucent/LucentPromptProvider'; export function ManagementModule() { const { activeBots, setBots, mergeBot, updateBotStatus, locale } = useAppStore(); const { notify } = useLucentPrompt(); const t = pickLocale(locale, { 'zh-cn': managementZhCn, en: managementEn }); const [selectedBotId, setSelectedBotId] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [isKernelModalOpen, setIsKernelModalOpen] = useState(false); const [operatingBotId, setOperatingBotId] = useState(null); const fetchBots = async () => { try { const res = await axios.get(`${APP_ENDPOINTS.apiBase}/bots`); setBots(res.data); } catch (err) { console.error(err); } }; const toggleBot = async (botId: string, status: string) => { setOperatingBotId(botId); try { if (status === 'RUNNING') { await axios.post(`${APP_ENDPOINTS.apiBase}/bots/${botId}/stop`); updateBotStatus(botId, 'STOPPED'); } else { await axios.post(`${APP_ENDPOINTS.apiBase}/bots/${botId}/start`); updateBotStatus(botId, 'RUNNING'); } // 关键:操作完成后立即刷新列表 await fetchBots(); } catch { notify(t.opFail, { tone: 'error' }); } finally { setOperatingBotId(null); } }; const selectedBot = selectedBotId ? activeBots[selectedBotId] : null; useEffect(() => { if (!selectedBotId) return; let alive = true; const loadDetail = async () => { try { const res = await axios.get(`${APP_ENDPOINTS.apiBase}/bots/${selectedBotId}`); if (alive) mergeBot(res.data); } catch (err) { console.error(err); } }; void loadDetail(); return () => { alive = false; }; }, [selectedBotId, mergeBot]); return (

{t.botInstances}

{Object.values(activeBots).map((bot) => (
setSelectedBotId(bot.id)} className={`p-4 rounded-xl border cursor-pointer transition-all ${ selectedBotId === bot.id ? 'bg-blue-600/10 border-blue-500/50' : 'bg-slate-900/50 border-white/5 hover:border-white/10' }`} >

{bot.name}

{bot.id}

))}
{selectedBot ? ( <>

{selectedBot.name}

{t.detailsTitle}

{selectedBot.docker_status}
{t.kernel}

{selectedBot.image_tag || 'nanobot-base:v0.1.5'}

{t.model}

{selectedBot.llm_model || '-'}

{t.status}

{selectedBot.current_state || t.idle}

{t.consoleOutput}
{selectedBot.logs.map((log, i) => (
{(i + 1).toString().padStart(3, '0')} {log}
))}
) : (

{t.selectHint}

)}
setIsModalOpen(false)} onSuccess={fetchBots} /> setIsKernelModalOpen(false)} />
); }