This commit is contained in:
2026-04-20 15:04:42 +03:00
parent 484ea9dc0f
commit eba29659d6
8 changed files with 587 additions and 588 deletions

125
static/js/api.js Normal file
View File

@@ -0,0 +1,125 @@
// ================================================================
// API & Networking
// ================================================================
window.fetchTowns = async function() {
try {
const res = await fetch('/dashboard/towns');
window.towns = await res.json();
window.renderTowns();
window.updateServerStatus(true);
if (window.selectedTownId) {
window.renderBuildQueuePreview();
window.renderBuildingDropdown();
window.renderTownDetails();
}
} catch (e) {
window.updateServerStatus(false);
}
};
window.fetchClientStatus = async function() {
try {
const res = await fetch('/dashboard/client-status');
const data = await res.json();
const isOnline = data.online === true;
// Detect transition: online → offline
if (window.wasClientOnline === true && !isOnline) {
// Fail all queued commands immediately
await fetch('/dashboard/commands/fail-stale', { method: 'POST' });
window.fetchLog();
}
window.clientOnline = isOnline;
window.wasClientOnline = isOnline;
window.updateClientStatus(isOnline);
} catch (e) {
window.updateClientStatus(false);
}
};
window.fetchLog = async function() {
try {
const res = await fetch('/dashboard/commands');
const cmds = await res.json();
window.renderLog(cmds);
} catch (e) {}
};
window.updateServerStatus = function(online) {
const el = document.getElementById('server-status');
if (online) {
el.textContent = '● Server';
el.className = 'conn-badge online';
} else {
el.textContent = '● Server offline';
el.className = 'conn-badge offline';
}
};
window.updateClientStatus = function(online) {
const el = document.getElementById('client-status');
if (online) {
el.textContent = '● Script';
el.className = 'conn-badge online';
} else {
el.textContent = '● Script offline';
el.className = 'conn-badge offline';
}
// Enable/disable the Send button
const btn = document.querySelector('#command-form-wrap .btn-gold');
if (btn) {
btn.disabled = !online;
btn.title = online ? '' : 'Script is offline — cannot send commands';
btn.style.opacity = online ? '' : '0.4';
btn.style.cursor = online ? '' : 'not-allowed';
}
};
window.sendCommand = async function() {
if (!window.clientOnline) return alert('Το script είναι offline — δεν μπορείτε να στείλετε εντολές.');
const town = window.getSelectedTown();
if (!town) return alert('Select a town first.');
const type = document.getElementById('cmd-type').value;
let payload = {};
if (type === 'build') {
payload = { building_id: document.getElementById('building-select').value };
} else {
payload = {
unit_id: document.getElementById('unit-select').value,
amount: parseInt(document.getElementById('recruit-amount').value) || 1,
};
}
try {
const res = await fetch('/dashboard/commands', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
town_id: town.town_id,
town_name: town.town_name,
type,
payload
})
});
const data = await res.json();
if (data.ok) {
window.fetchLog();
} else if (data.error === 'client_offline') {
alert(data.message || 'Το script είναι offline.');
} else {
alert('Error: ' + JSON.stringify(data));
}
} catch (e) {
alert('Failed to send command: ' + e);
}
};
window.cancelCommand = async function(id) {
await fetch(`/dashboard/commands/${id}`, { method: 'DELETE' });
window.fetchLog();
};