Implement DatabaseBackend, Verschiedenes

This commit is contained in:
Carsten Graf
2025-06-06 22:07:47 +02:00
parent 4f4d0757d5
commit a1434347d8
10 changed files with 256 additions and 681 deletions

View File

@@ -11,6 +11,11 @@
<body>
<div class="container">
<div class="header">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<button onclick="window.location.href='/settings'" class="back-btn" style="background: #6c757d; color: white; border: none; padding: 8px 15px; border-radius: 5px; cursor: pointer; font-size: 14px; display: flex; align-items: center; gap: 5px;">
← Zurück zu Einstellungen
</button>
</div>
<h1>🏷️ RFID Daten Eingabe</h1>
<p>Erfassen Sie RFID-Tag Informationen</p>
</div>
@@ -51,19 +56,10 @@
</div>
</form>
<div class="data-table">
<h3>📋 Gespeicherte Einträge</h3>
<div class="counter">
<span id="entryCounter">0 Einträge gespeichert</span>
</div>
<div id="dataEntries"></div>
</div>
</div>
<script>
// API Base URL - anpassen an Ihre Backend-URL
const API_BASE_URL = 'http://localhost:3000/api';
// Globale Variablen
let rfidData = [];
let isLoading = false;
@@ -91,7 +87,7 @@
try {
// API Aufruf zum Erstellen des Benutzers
const response = await fetch(`${API_BASE_URL}/users`, {
const response = await fetch(`/api/users`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -132,25 +128,7 @@
setLoadingState(false);
}
});
// Benutzer laden
async function loadUserData() {
try {
const response = await fetch(`${API_BASE_URL}/users?limit=50`);
const result = await response.json();
if (result.success) {
rfidData = result.data;
updateDataTable();
} else {
console.error('Fehler beim Laden der Daten:', result.error);
showErrorMessage('Fehler beim Laden der Daten');
}
} catch (error) {
console.error('Fehler beim Laden der Daten:', error);
showErrorMessage('Verbindungsfehler beim Laden der Daten');
}
}
function showSuccessMessage(message = 'Daten erfolgreich gespeichert!') {
const successMsg = document.getElementById('successMessage');
@@ -185,7 +163,7 @@
errorDiv.style.display = 'block';
setTimeout(() => {
errorDiv.style.display = 'none';
}, 5000);
}, 10000);
}
function setLoadingState(loading) {
@@ -209,99 +187,6 @@
document.getElementById('uid').focus();
}
function updateDataTable() {
const container = document.getElementById('dataEntries');
const counter = document.getElementById('entryCounter');
// Counter aktualisieren
counter.textContent = `${rfidData.length} Einträge gespeichert`;
// Tabelle leeren
container.innerHTML = '';
// Einträge anzeigen (neueste zuerst)
rfidData.forEach((entry, index) => {
const entryDiv = document.createElement('div');
entryDiv.className = 'data-entry';
// Datum formatieren
const createdAt = new Date(entry.created_at).toLocaleString('de-DE', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
entryDiv.innerHTML = `
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
<div style="flex: 1;">
<div><strong>UID:</strong> <span>${entry.uid}</span></div>
<div><strong>Name:</strong> <span>${entry.vorname} ${entry.nachname}</span></div>
<div><strong>Alter:</strong> <span>${entry.alter} Jahre</span></div>
<div><strong>Erfasst:</strong> <span>${createdAt}</span></div>
</div>
<div style="margin-left: 10px;">
<button onclick="deleteUser('${entry.uid}')"
style="background: #dc3545; color: white; border: none; padding: 5px 10px; border-radius: 5px; cursor: pointer; font-size: 12px;"
title="Benutzer löschen">
🗑️
</button>
</div>
</div>
`;
container.appendChild(entryDiv);
});
if (rfidData.length === 0) {
container.innerHTML = '<div style="text-align: center; color: #999; padding: 20px;">Noch keine Daten erfasst</div>';
}
}
// Benutzer löschen
async function deleteUser(uid) {
if (!confirm(`Möchten Sie den Benutzer mit UID "${uid}" wirklich löschen?`)) {
return;
}
try {
const response = await fetch(`${API_BASE_URL}/users/${encodeURIComponent(uid)}`, {
method: 'DELETE'
});
const result = await response.json();
if (result.success) {
showSuccessMessage('Benutzer erfolgreich gelöscht!');
await loadUserData();
} else {
showErrorMessage(result.error || 'Fehler beim Löschen des Benutzers');
}
} catch (error) {
console.error('Fehler beim Löschen:', error);
showErrorMessage('Verbindungsfehler beim Löschen des Benutzers');
}
}
// Server Status prüfen
async function checkServerStatus() {
try {
const response = await fetch(`${API_BASE_URL}/health`);
const result = await response.json();
if (result.status === 'OK') {
console.log('✅ Server ist erreichbar');
// Daten laden
await loadUserData();
} else {
throw new Error('Server nicht verfügbar');
}
} catch (error) {
console.error('❌ Server nicht erreichbar:', error);
showErrorMessage('Server nicht erreichbar. Bitte stellen Sie sicher, dass das Backend läuft.');
}
}
// Beim Laden der Seite
window.addEventListener('load', function() {
document.getElementById('uid').focus();
@@ -336,7 +221,7 @@
try {
// API Aufruf zum RFID Reader
const response = await fetch(`${API_BASE_URL}/rfid/read`, {
const response = await fetch(`/api/rfid/read`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -372,7 +257,7 @@
uidInput.style.borderColor = '#dc3545';
setTimeout(() => {
uidInput.style.borderColor = '#e1e5e9';
}, 3000);
}, 10000);
}
} catch (error) {
@@ -392,15 +277,24 @@
readBtn.innerHTML = '📡 Read UID';
}
}
document.addEventListener('DOMContentLoaded', function() {
const refreshBtn = document.createElement('button');
refreshBtn.innerHTML = '🔄 Aktualisieren';
refreshBtn.className = 'btn btn-secondary';
refreshBtn.style.cssText = 'margin-top: 10px; width: 100%;';
refreshBtn.onclick = loadUserData;
document.querySelector('.data-table').appendChild(refreshBtn);
});
async function checkServerStatus() {
try {
const response = await fetch('/api/health');
const data = await response.json();
if (!data.status || data.status !== 'connected') {
showErrorMessage('Server nicht verbunden. Einige Funktionen könnten eingeschränkt sein.');
return false;
}
return true;
} catch (error) {
console.error('Server Status Check fehlgeschlagen:', error);
showErrorMessage('Verbindung zum Server nicht möglich.');
return false;
}
}
</script>
</body>
</html>

View File

@@ -1,33 +1,33 @@
<!DOCTYPE html>
<html lang="de">
<head>
<!-- Meta Tags -->
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Stylesheets -->
<link rel="stylesheet" href="settings.css" />
<title>Ninjacross Timer - Einstellungen</title>
</head>
<body>
<div class="container">
<!-- Header Section -->
<div class="header">
<h1>⏱️ Ninjacross Timer</h1>
<p>Einstellungen & Konfiguration</p>
</div>
<div class="content">
<!-- Navigation Buttons -->
<div class="nav-buttons">
<a href="/" class="nav-button">🏠 Hauptseite</a>
<a
href="/settings"
class="nav-button"
style="background: #667eea; color: white; border-color: #667eea"
>⚙️ Einstellungen</a
>
<a href="/rfid" class="nav-button">📡 RFID</a>
</div>
<!-- Status Message Container -->
<div id="statusMessage" class="status-message"></div>
<!-- Date & Time Section -->
<div class="section">
<h2>🕐 Datum & Uhrzeit</h2>
<div class="current-time" id="currentTime">
@@ -65,6 +65,7 @@
</form>
</div>
<!-- Basic Settings Section -->
<div class="section">
<h2>🔧 Grundeinstellungen</h2>
<form id="settingsForm">
@@ -102,6 +103,7 @@
</form>
</div>
<!-- Times Management Section -->
<div class="section">
<h2>🏆 Zeiten verwalten</h2>
<div class="button-group">
@@ -111,6 +113,7 @@
</div>
</div>
<!-- Button Configuration Section -->
<div class="section">
<h2>📡 Button-Konfiguration</h2>
<div class="button-group">
@@ -136,6 +139,7 @@
</div>
</div>
<!-- WiFi Configuration Section -->
<div class="section" id="wifiSection">
<h2>📡 WLAN-Konfiguration</h2>
<div id="wifiRestrictionNotice" class="restriction-notice" style="display: none;">
@@ -169,6 +173,7 @@
</form>
</div>
<!-- OTA Update Section -->
<div class="section">
<h2>🔄 OTA Update</h2>
<div id="otaRestrictionNotice" class="restriction-notice" style="display: none;">
@@ -185,6 +190,7 @@
</div>
</div>
<!-- System Information Section -->
<div class="section">
<h2> System-Information</h2>
<div
@@ -207,6 +213,7 @@
</div>
</div>
<!-- License Section -->
<div class="section">
<h2>🔧 Lizenz</h2>
<form id="licenceForm">
@@ -224,6 +231,7 @@
</div>
</div>
<!-- JavaScript Code -->
<script>
let learningStep = 0;
const learningSteps = [