// ================================================================ // Command Log & Build Queue Component // ================================================================ // -- Panel state: 'queue' | 'log' ---------------------------- window._logPanelMode = 'queue'; // ---- Toggle buttons ------------------------------------------- window.switchToQueueMode = function() { window._logPanelMode = 'queue'; document.getElementById('tab-queue').classList.add('tab-active'); document.getElementById('tab-log').classList.remove('tab-active'); window.refreshLogPanel(); }; window.switchToLogMode = function() { window._logPanelMode = 'log'; document.getElementById('tab-log').classList.add('tab-active'); document.getElementById('tab-queue').classList.remove('tab-active'); window.fetchLog(); }; // ---- Main dispatcher ------------------------------------------ window.refreshLogPanel = function() { if (window._logPanelMode === 'queue') { const town = window.getSelectedTown(); if (town) { window.fetchBuildQueue(town.town_id); } else { document.getElementById('log-content').innerHTML = '

← Επιλέξτε πόλη για να δείτε την ουρά.

'; } } }; // ================================================================ // BUILD QUEUE (per-town, draggable) // ================================================================ window.fetchBuildQueue = async function(townId) { if (window._logPanelMode !== 'queue') return; try { const res = await fetch(`/dashboard/commands/queue?player_id=${window.PLAYER_ID}&town_id=${encodeURIComponent(townId)}`); const cmds = await res.json(); window.renderBuildQueue(cmds, townId); } catch(e) {} }; // Drag state let _dragSrcIdx = null; window.renderBuildQueue = function(cmds, townId) { const el = document.getElementById('log-content'); if (!cmds || cmds.length === 0) { el.innerHTML = `
🏗️

Η ουρά κατασκευών είναι κενή.

Χρησιμοποιήστε την φόρμα για να προσθέσετε κατασκευές.

`; return; } const rows = cmds.map((cmd, idx) => { const p = typeof cmd.payload === 'string' ? JSON.parse(cmd.payload) : cmd.payload; const nameGr = window.BUILDING_NAMES_GR?.[p.building_id] || p.building_id || '?'; const icon = window.BUILDING_ICONS?.[p.building_id] || '🏗️'; const isExec = cmd.status === 'executing'; const statusDot = isExec ? `` : ``; return `
${idx + 1} ${statusDot} ${icon} ${nameGr}
`; }).join(''); el.innerHTML = `
${rows}
`; }; // ---- Drag-and-drop handlers ----------------------------------- window._bqDragStart = function(e, idx) { _dragSrcIdx = idx; e.dataTransfer.effectAllowed = 'move'; setTimeout(() => { const rows = document.querySelectorAll('.bq-row'); if (rows[idx]) rows[idx].style.opacity = '0.4'; }, 0); }; window._bqDragOver = function(e) { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; // Highlight target row document.querySelectorAll('.bq-row').forEach(r => r.classList.remove('bq-drag-over')); const row = e.currentTarget; if (row) row.classList.add('bq-drag-over'); }; window._bqDrop = function(e, targetIdx, townId) { e.preventDefault(); e.stopPropagation(); if (_dragSrcIdx === null || _dragSrcIdx === targetIdx) return; // Re-order the DOM const list = document.getElementById('bq-list'); const rows = Array.from(list.querySelectorAll('.bq-row')); const movedRow = rows.splice(_dragSrcIdx, 1)[0]; rows.splice(targetIdx, 0, movedRow); // Update numbering & opacity rows.forEach((r, i) => { r.style.opacity = '1'; r.classList.remove('bq-drag-over'); r.dataset.idx = i; r.querySelector('.bq-pos').textContent = i + 1; r.setAttribute('ondragstart', `window._bqDragStart(event,${i})`); r.setAttribute('ondrop', `window._bqDrop(event,${i},'${townId}')`); }); list.innerHTML = ''; rows.forEach(r => list.appendChild(r)); // Persist new order to server const orderedIds = rows.map(r => parseInt(r.dataset.id)); fetch('/dashboard/commands/reorder', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ player_id: window.PLAYER_ID, town_id: townId, order: orderedIds }) }); _dragSrcIdx = null; }; window._bqDragEnd = function(e) { document.querySelectorAll('.bq-row').forEach(r => { r.style.opacity = '1'; r.classList.remove('bq-drag-over'); }); _dragSrcIdx = null; }; window._bqCancel = async function(id) { await fetch(`/dashboard/commands/${id}`, { method: 'DELETE' }); // Refresh the queue for the currently selected town const town = window.getSelectedTown(); if (town) window.fetchBuildQueue(town.town_id); }; // ================================================================ // COMMAND LOG (full history, existing behaviour) // ================================================================ window.renderLog = function(cmds) { if (window._logPanelMode !== 'log') return; const el = document.getElementById('log-content'); if (!cmds.length) { el.innerHTML = '

No commands sent yet.

'; return; } const rows = cmds.map(cmd => { const p = typeof cmd.payload === 'string' ? JSON.parse(cmd.payload) : cmd.payload; let desc = ''; if (cmd.type === 'build') { const nameGr = window.BUILDING_NAMES_GR?.[p.building_id] || p.building_id; desc = `Build: ${nameGr}`; } else if (cmd.type === 'recruit') { const nameGr = window.UNIT_NAMES_GR?.[p.unit_id] || p.unit_id; desc = `Recruit: ${p.amount}x ${nameGr}`; } else if (cmd.type === 'market_offer') { desc = `Market: ${p.offer} ${p.offer_type} ➞ ${p.demand} ${p.demand_type}`; } else { desc = cmd.type; } const statusClass = `status-${cmd.status}`; const cancelBtn = ``; const timeStr = new Date(cmd.created_at + 'Z').toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); return ` #${cmd.id}
${timeStr} ${cmd.town_name || cmd.town_id} ${desc} ${cmd.status} ${cmd.result_msg || ''} ${cancelBtn} `; }).join(''); el.innerHTML = `${rows}
#TownCommandStatusResult
`; };