// FORGIUM CLOUD COCKPIT CONTROLLER const FORGIUM_API_BASE = 'https://panel.forgium.fr/api/client'; const DEFAULT_KEY = 'ptlc_8mAbydxokymforgium_144010543bd11119f4fe424b643e49d6d2e17c8271224b81'; class ForgiumCockpit { constructor() { this.apiKey = localStorage.getItem('forgium_cockpit_key') || DEFAULT_KEY; this.servers = []; this.currentServer = null; this.socket = null; this.pollInterval = null; this.initDOMElements(); this.bindEvents(); this.checkAuthAndStart(); } initDOMElements() { this.fleetView = document.getElementById('fleet-view'); this.serverView = document.getElementById('server-view'); this.serversGrid = document.getElementById('servers-grid'); this.configModal = document.getElementById('config-modal'); this.apiKeyInput = document.getElementById('api-key-input'); // Detail View Elements this.backBtn = document.getElementById('back-to-fleet'); this.serverTitle = document.getElementById('server-detail-title'); this.serverDesc = document.getElementById('server-detail-desc'); this.serverBadge = document.getElementById('server-detail-badge'); this.terminalOutput = document.getElementById('terminal-output'); this.terminalInput = document.getElementById('terminal-input'); // Stat counters this.countTotal = document.getElementById('stat-total-servers'); this.countRunning = document.getElementById('stat-running-servers'); // Detail Gauges this.gaugeCpu = document.getElementById('gauge-cpu'); this.gaugeCpuFill = document.getElementById('gauge-cpu-fill'); this.gaugeRam = document.getElementById('gauge-ram'); this.gaugeRamFill = document.getElementById('gauge-ram-fill'); this.gaugeDisk = document.getElementById('gauge-disk'); this.gaugeDiskFill = document.getElementById('gauge-disk-fill'); // Power Buttons this.btnStart = document.getElementById('btn-power-start'); this.btnRestart = document.getElementById('btn-power-restart'); this.btnStop = document.getElementById('btn-power-stop'); } bindEvents() { document.getElementById('save-key-btn').addEventListener('click', () => { const key = this.apiKeyInput.value.trim(); if (key) { this.apiKey = key; localStorage.setItem('forgium_cockpit_key', key); this.configModal.classList.add('hidden'); this.loadFleet(); } }); document.getElementById('btn-settings').addEventListener('click', () => { this.apiKeyInput.value = this.apiKey; this.configModal.classList.remove('hidden'); }); this.backBtn.addEventListener('click', () => { this.showFleetView(); }); this.terminalInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') { const cmd = this.terminalInput.value.trim(); if (cmd) { this.sendCommand(cmd); this.terminalInput.value = ''; } } }); this.btnStart.addEventListener('click', () => this.sendPowerSignal('start')); this.btnRestart.addEventListener('click', () => this.sendPowerSignal('restart')); this.btnStop.addEventListener('click', () => this.sendPowerSignal('stop')); } checkAuthAndStart() { if (!this.apiKey) { this.configModal.classList.remove('hidden'); } else { this.loadFleet(); } } async apiRequest(endpoint, method = 'GET', body = null) { const headers = { 'Authorization': `Bearer ${this.apiKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json' }; const res = await fetch(`${FORGIUM_API_BASE}${endpoint}`, { method, headers, body: body ? JSON.stringify(body) : null }); if (!res.ok) { if (res.status === 401 || res.status === 403) { this.configModal.classList.remove('hidden'); } throw new Error(`Erreur API: ${res.status}`); } return res.json(); } async loadFleet() { try { const data = await this.apiRequest(''); this.servers = data.data.map(item => item.attributes); this.renderFleet(); } catch (err) { console.error('Erreur chargement flotte:', err); } } async renderFleet() { this.serversGrid.innerHTML = ''; this.countTotal.textContent = this.servers.length; let onlineCount = 0; for (const s of this.servers) { const card = document.createElement('div'); card.className = 'server-card'; // Récupérer ressources en temps réel let resState = 'offline'; let cpu = '0.0%'; let ram = '0 Mo'; try { const stats = await this.apiRequest(`/servers/${s.identifier}/resources`); resState = stats.attributes.current_state; if (resState === 'running' || resState === 'starting') { onlineCount++; } cpu = (stats.attributes.resources.cpu_absolute || 0).toFixed(1) + '%'; const ramMb = (stats.attributes.resources.memory_bytes / 1024 / 1024).toFixed(0); ram = `${ramMb} Mo / ${s.limits.memory} Mo`; } catch (e) { console.log('Stats offline:', s.name); } const isOnline = resState === 'running' || resState === 'starting'; const badgeClass = isOnline ? 'status-running' : 'status-offline'; const badgeText = isOnline ? 'EN LIGNE' : 'ARRÊTÉ'; const defaultAlloc = s.relationships?.allocations?.data[0]?.attributes; const alias = defaultAlloc ? `node.forgium.fr:${defaultAlloc.port}` : 'Réseau Dédié'; card.innerHTML = `