let links = [];
initPage({ onAuth: (user) => {
if (!user || user.role !== 'admin') {
window.location.href = '/';
}
}});
// ── Links table ───────────────────────────────────────────────
function renderLinks() {
const tbody = document.getElementById('linksList');
if (links.length === 0) {
tbody.innerHTML = '
| Keine Links. |
';
return;
}
tbody.innerHTML = links.map((l, i) =>
`
| ${escapeHtml(l.label)} |
${escapeHtml(l.url)} |
|
`
).join('');
}
function removeLink(idx) {
links.splice(idx, 1);
renderLinks();
}
document.getElementById('btnAddLink').addEventListener('click', () => {
const label = document.getElementById('newLinkLabel').value.trim();
const url = document.getElementById('newLinkUrl').value.trim();
if (!label || !url) return;
links.push({ label, url });
renderLinks();
document.getElementById('newLinkLabel').value = '';
document.getElementById('newLinkUrl').value = '';
});
// ── Load ─────────────────────────────────────────────────────
async function loadConfig() {
try {
const resp = await fetch('/api/config');
if (!resp.ok) return;
const cfg = await resp.json();
document.getElementById('botName').value = cfg.bot?.name ?? '';
document.getElementById('botPrefix').value = cfg.bot?.command_prefix ?? '';
document.getElementById('meshHost').value = cfg.meshtastic?.host ?? '';
document.getElementById('meshPort').value = cfg.meshtastic?.port ?? '';
document.getElementById('webPort').value = cfg.web?.port ?? '';
document.getElementById('onlineThreshold').value = cfg.web?.online_threshold ?? '';
links = Array.isArray(cfg.links) ? [...cfg.links] : [];
renderLinks();
} catch (e) {
console.error('Config load failed:', e);
}
}
// ── Save ──────────────────────────────────────────────────────
document.getElementById('btnSave').addEventListener('click', async () => {
const payload = {
bot: {
name: document.getElementById('botName').value.trim(),
command_prefix: document.getElementById('botPrefix').value.trim(),
},
meshtastic: {
host: document.getElementById('meshHost').value.trim(),
port: parseInt(document.getElementById('meshPort').value) || 4403,
},
web: {
port: parseInt(document.getElementById('webPort').value) || 8081,
online_threshold: parseInt(document.getElementById('onlineThreshold').value) || 900,
},
links: [...links],
};
const statusEl = document.getElementById('saveStatus');
try {
const resp = await fetch('/api/config', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
});
if (resp.ok) {
statusEl.textContent = 'Gespeichert ✓';
statusEl.className = 'small text-success';
statusEl.classList.remove('d-none');
setTimeout(() => statusEl.classList.add('d-none'), 3000);
} else {
statusEl.textContent = 'Fehler beim Speichern';
statusEl.className = 'small text-danger';
statusEl.classList.remove('d-none');
}
} catch (e) {
console.error('Save failed:', e);
statusEl.textContent = 'Netzwerkfehler';
statusEl.className = 'small text-danger';
statusEl.classList.remove('d-none');
}
});
loadConfig();