function updateSortArrows() { const arrows = { sensorNr: document.getElementById('sortArrowSensorNr'), espId: document.getElementById('sortArrowEspId'), date: document.getElementById('sortArrowDate') }; Object.entries(arrows).forEach(([key, el]) => { if (!el) return; // Aktiver Pfeil fett, andere ausgegraut el.textContent = currentSort.key === key ? (currentSort.asc ? '↑' : '↓') : '↑'; el.style.fontWeight = currentSort.key === key ? 'bold' : 'normal'; el.style.opacity = currentSort.key === key ? '1' : '0.3'; }); } // Tab-Wechsel Funktion aus index.pug function showTab(tab) { document.getElementById('tabInputContent').style.display = tab === 'input' ? '' : 'none'; document.getElementById('tabListContent').style.display = tab === 'list' ? '' : 'none'; document.getElementById('tabInput').classList.toggle('active', tab === 'input'); document.getElementById('tabList').classList.toggle('active', tab === 'list'); } document.addEventListener('DOMContentLoaded', () => { const saveBtn = document.getElementById('saveBtn'); const refreshBtn = document.getElementById('refreshBtn'); const espIdInput = document.getElementById('espId'); const sensorNumberInput = document.getElementById('sensorNumber'); const nameInput = document.getElementById('name'); const descriptionInput = document.getElementById('description'); const addressInput = document.getElementById('address'); const pageInput = document.getElementById('page'); const limitInput = document.getElementById('limit'); const resultDiv = document.getElementById('result'); const tableBody = document.querySelector('#entriesTable tbody'); const tabInput = document.getElementById('tabInput'); const tabList = document.getElementById('tabList'); let editId = null; // Modal für Fehleranzeige function showModal(message, showCancelButton, callback) { // Remove previous modals document.querySelectorAll('.custom-modal-popup').forEach(m => m.remove()); let modal = document.createElement('div'); modal.className = 'custom-modal-popup'; let box = document.createElement('div'); box.className = 'custom-modal-box'; let msg = document.createElement('div'); msg.className = 'custom-modal-msg'; msg.textContent = message; box.appendChild(msg); let btndiv = document.createElement('div') btndiv.className = 'twobuttons' // Cancel Button (only if showCancelButton is true) if (showCancelButton) { let btnCancel = document.createElement('button'); btnCancel.className = 'custom-modal-btn'; btnCancel.textContent = 'Abbruch'; btnCancel.onclick = () => { if (modal.parentNode) { modal.parentNode.removeChild(modal); } if (callback) callback(false); // Pass false for Cancel }; btndiv.appendChild(btnCancel); } // OK Button let btnOk = document.createElement('button'); btnOk.className = 'custom-modal-btn'; btnOk.textContent = 'OK'; btnOk.onclick = () => { if (modal.parentNode) { modal.parentNode.removeChild(modal); } if (callback) callback(true); // Pass true for OK }; btndiv.appendChild(btnOk); box.appendChild(btndiv) modal.appendChild(box); document.body.appendChild(modal); // Optional: Close modal when clicking outside modal.onclick = (e) => { if (e.target === modal) { if (modal.parentNode) { modal.parentNode.removeChild(modal); } if (callback) callback(false); // Treat as cancel } }; } // Sensornummer nur Zahlen erlauben sensorNumberInput.addEventListener('input', () => { sensorNumberInput.value = sensorNumberInput.value.replace(/\D/g, ''); }); // Adresse vom Server holen, wenn Enter oder Feld verlassen async function fetchAddressIfValid() { const value = sensorNumberInput.value.trim(); if (value.length > 0) { try { const res = await fetch(`/api/address/${value}`); const data = await res.json(); console.dir(data) if (!data.error && data.address) { addressInput.value = data.address; // Felder automatisch füllen, wenn props vorhanden if (!data.props.error) { if (data.props.erg.chip !== undefined) { let pp = data.props.erg.chip espIdInput.value = pp.id || '' nameInput.value = pp.name || '' descriptionInput.value = pp.description || '' // Weitere Felder nach Bedarf } } } else { addressInput.value = ''; sensorNumberInput.disabled = true; showModal('Sensor unbekannt', false, () => { sensorNumberInput.disabled = false; sensorNumberInput.focus(); }); } } catch (err) { console.error('Fehler beim Abrufen der Adresse:', err); addressInput.value = ''; sensorNumberInput.disabled = true; showModal('Sensor unbekannt', false, () => { sensorNumberInput.disabled = false; sensorNumberInput.focus(); }); } } } // Enter-Taste sensorNumberInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); fetchAddressIfValid(); } }); // Feld verlassen sensorNumberInput.addEventListener('blur', fetchAddressIfValid); async function saveEntry() { const espId = espIdInput.value.trim(); const sensorNumber = sensorNumberInput.value.trim(); const name = nameInput.value.trim(); const description = descriptionInput.value.trim(); const address = addressInput.value.trim(); if (!espId || !sensorNumber) { resultDiv.textContent = 'ESP-ID und Sensornummer sind Pflichtfelder.'; return; } try { const url = '/api/save'; const method = 'POST'; const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ espId, sensorNumber, name, description, address }) }); const data = await res.json(); if (data.error) { resultDiv.textContent = data.error; } else { resultDiv.textContent = 'OK!'; setTimeout(() => { resultDiv.textContent = '' saveBtn.textContent = 'Speichern'; }, 5000) clearForm(false); await loadEntries(); } } catch (err) { console.error(err); resultDiv.textContent = 'Fehler beim Speichern.'; } } function clearForm(mitButton) { espIdInput.value = ''; sensorNumberInput.value = ''; nameInput.value = ''; descriptionInput.value = ''; addressInput.value = ''; editId = null; if (mitButton) { saveBtn.textContent = 'Speichern'; } } // Globale Sortier-Variable window.currentSort = window.currentSort || { key: null, asc: true }; async function loadEntries() { const page = parseInt(pageInput.value) || 1; const limit = parseInt(limitInput.value) || 50; try { const res = await fetch(`/api/list?page=${page}&limit=${limit}`); const erg = await res.json(); const items = erg.items const gz = document.getElementById('gzahl'); gz.innerHTML = `Gesamtzahl: ${erg.anzahl}` let currentSort = window.currentSort || { key: null, asc: true }; function renderTable(sortedItems) { tableBody.innerHTML = ''; sortedItems.forEach(item => { const date = new Date(item.chip.lastUpdatedAt).toISOString().split('T')[0]; const tr = document.createElement('tr'); tr.innerHTML = `