import { useEffect, useState, useCallback } from 'react' import { apiFetch } from './utils/api' import { RefreshCw, Server, Wifi, WifiOff, Power, PowerOff, Users, Loader2, Globe } from 'lucide-react' interface EndpointRow { name: string connected: boolean mode: string guildCount: number channelCount: number status: string user: { tag: string; id: string } | null } interface GuildInfo { id: string name: string memberCount: number icon: string | null } type Tab = 'overview' | 'guilds' export default function DiscordDashboard() { const [endpoints, setEndpoints] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [tab, setTab] = useState('overview') const [actionLoading, setActionLoading] = useState>({}) // Guild browser state const [selectedEndpoint, setSelectedEndpoint] = useState('') const [guilds, setGuilds] = useState([]) const [guildsLoading, setGuildsLoading] = useState(false) const fetchData = useCallback(async () => { setLoading(true) setError('') try { const res = await apiFetch('/api/discord/endpoints') const json = await res.json() if (json.success) setEndpoints(json.data) else setError(json.error || '获取数据失败') } catch { setError('无法连接服务器') } finally { setLoading(false) } }, []) useEffect(() => { fetchData() }, [fetchData]) const toggleConnect = async (name: string, connected: boolean) => { setActionLoading(prev => ({ ...prev, [name]: true })) try { const endpoint = connected ? 'disconnect' : 'connect' const res = await apiFetch(`/api/discord/endpoints/${encodeURIComponent(name)}/${endpoint}`, { method: 'POST' }) const json = await res.json() if (!json.success) setError(json.error || '操作失败') await fetchData() } catch { setError('操作失败') } finally { setActionLoading(prev => ({ ...prev, [name]: false })) } } const loadGuilds = async (endpointName: string) => { setSelectedEndpoint(endpointName) setGuildsLoading(true) setGuilds([]) try { const res = await apiFetch(`/api/discord/endpoints/${encodeURIComponent(endpointName)}/guilds`) const json = await res.json() if (json.success) setGuilds(json.data) else setError(json.error || '获取服务器列表失败') } catch { setError('获取服务器列表失败') } finally { setGuildsLoading(false) } } const gatewayEndpoints = endpoints.filter((e) => e.connected && e.mode === 'gateway') return (

Discord 机器人

{error &&
{error}
} {/* Tabs */}
{/* Overview Tab */} {tab === 'overview' && ( <> {!loading && !endpoints.length && !error && (
暂无 Discord Endpoint 实例
)}
{endpoints.map((endpoint) => (
{endpoint.name} {endpoint.connected ? 在线 : 离线}
{endpoint.user &&
@{endpoint.user.tag}
}
模式{endpoint.mode}
服务器{endpoint.guildCount}
频道{endpoint.channelCount}
{endpoint.connected && endpoint.mode === 'gateway' && ( )}
))}
)} {/* Guilds Tab */} {tab === 'guilds' && (
{gatewayEndpoints.length > 0 && (
仅 Gateway 模式支持
)} {!gatewayEndpoints.length &&
暂无 Gateway 模式在线 Endpoint
} {guildsLoading &&
} {!guildsLoading && guilds.length > 0 && (
{guilds.map(g => (
{g.icon ? :
{g.name[0]}
}
{g.name}
{g.memberCount} 成员
))}
)} {!guildsLoading && selectedEndpoint && !guilds.length &&
该机器人未加入任何服务器
}
)}
) }