🔧 Update: Enhanced error handling and logging across various modules

**Änderungen:**
-  app.py: Hinzugefügt, um CSRF-Fehler zu behandeln
-  models.py: Fehlerprotokollierung bei der Suche nach Gastanfragen per OTP
-  api.py: Fehlerprotokollierung beim Markieren von Benachrichtigungen als gelesen
-  calendar.py: Fallback-Daten zurückgeben, wenn keine Kalenderereignisse vorhanden sind
-  guest.py: Status-Check-Seite für Gäste aktualisiert
-  hardware_integration.py: Debugging-Informationen für erweiterte Geräteinformationen hinzugefügt
-  tapo_status_manager.py: Rückgabewert für Statusabfrage hinzugefügt

**Ergebnis:**
- Verbesserte Fehlerbehandlung und Protokollierung für eine robustere Anwendung
- Bessere Nachverfolgbarkeit von Fehlern und Systemverhalten

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-06-15 22:45:20 +02:00
parent 7e156099d5
commit 956c24d8ca
552 changed files with 11252 additions and 2424 deletions

View File

@ -94,26 +94,13 @@
6-stelliger Zugangscode <span class="text-red-500">*</span>
</label>
<!-- Code-Input mit einzelnen Feldern -->
<div class="flex justify-center gap-3 mb-6">
<input type="text" id="code1" maxlength="1"
class="code-input w-12 h-12 text-center text-xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300"
oninput="moveToNext(this, 'code2')" onkeydown="handleBackspace(event, this, null)">
<input type="text" id="code2" maxlength="1"
class="code-input w-12 h-12 text-center text-xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300"
oninput="moveToNext(this, 'code3')" onkeydown="handleBackspace(event, this, 'code1')">
<input type="text" id="code3" maxlength="1"
class="code-input w-12 h-12 text-center text-xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300"
oninput="moveToNext(this, 'code4')" onkeydown="handleBackspace(event, this, 'code2')">
<input type="text" id="code4" maxlength="1"
class="code-input w-12 h-12 text-center text-xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300"
oninput="moveToNext(this, 'code5')" onkeydown="handleBackspace(event, this, 'code3')">
<input type="text" id="code5" maxlength="1"
class="code-input w-12 h-12 text-center text-xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300"
oninput="moveToNext(this, 'code6')" onkeydown="handleBackspace(event, this, 'code4')">
<input type="text" id="code6" maxlength="1"
class="code-input w-12 h-12 text-center text-xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300"
oninput="moveToNext(this, null)" onkeydown="handleBackspace(event, this, 'code5')">
<!-- Einzelnes Code-Input-Feld -->
<div class="flex justify-center mb-6">
<input type="text" id="codeInput" maxlength="6"
class="w-48 h-16 text-center text-2xl font-bold border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-800 text-slate-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all duration-300 uppercase tracking-widest"
placeholder="ABC123"
autocomplete="off"
spellcheck="false">
</div>
<div class="text-center">
@ -171,64 +158,41 @@
</div>
<script>
// Code-Eingabe-Logik
function moveToNext(current, nextId) {
const value = current.value.toUpperCase();
// Nur alphanumerische Zeichen erlauben
if (!/^[A-Z0-9]$/.test(value)) {
current.value = '';
return;
}
current.value = value;
current.classList.add('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
// Zum nächsten Feld wechseln
if (nextId && value) {
document.getElementById(nextId).focus();
}
// Prüfen ob alle Felder ausgefüllt sind
checkFormComplete();
}
function handleBackspace(event, current, prevId) {
if (event.key === 'Backspace') {
if (current.value === '' && prevId) {
event.preventDefault();
const prevField = document.getElementById(prevId);
prevField.focus();
prevField.value = '';
prevField.classList.remove('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
} else if (current.value !== '') {
current.classList.remove('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
}
}
}
// Code-Eingabe-Logik für 6-stelligen Code
function checkFormComplete() {
const inputs = ['code1', 'code2', 'code3', 'code4', 'code5', 'code6'];
const allFilled = inputs.every(id => document.getElementById(id).value !== '');
const codeInput = document.getElementById('codeInput');
const code = codeInput.value.trim();
const isComplete = code.length === 6 && /^[A-Z0-9]{6}$/.test(code);
const submitBtn = document.getElementById('submitBtn');
submitBtn.disabled = !allFilled;
submitBtn.disabled = !isComplete;
// Visuelles Feedback
if (code.length > 0) {
if (isComplete) {
codeInput.classList.add('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
codeInput.classList.remove('border-red-500', 'bg-red-50', 'dark:bg-red-900/20');
} else {
codeInput.classList.add('border-red-500', 'bg-red-50', 'dark:bg-red-900/20');
codeInput.classList.remove('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
}
} else {
codeInput.classList.remove('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
codeInput.classList.remove('border-red-500', 'bg-red-50', 'dark:bg-red-900/20');
}
}
function getCodeValue() {
const inputs = ['code1', 'code2', 'code3', 'code4', 'code5', 'code6'];
return inputs.map(id => document.getElementById(id).value).join('');
return document.getElementById('codeInput').value.trim().toUpperCase();
}
function clearCode() {
const inputs = ['code1', 'code2', 'code3', 'code4', 'code5', 'code6'];
inputs.forEach(id => {
const input = document.getElementById(id);
input.value = '';
input.classList.remove('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
});
const codeInput = document.getElementById('codeInput');
codeInput.value = '';
codeInput.classList.remove('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
codeInput.classList.remove('border-red-500', 'bg-red-50', 'dark:bg-red-900/20');
checkFormComplete();
document.getElementById('code1').focus();
codeInput.focus();
}
function showSuccess(message, details) {
@ -253,9 +217,31 @@ function showError(message, details) {
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('codeForm');
const submitBtn = document.getElementById('submitBtn');
const codeInput = document.getElementById('codeInput');
// Erstes Feld fokussieren
document.getElementById('code1').focus();
// Code-Input fokussieren
codeInput.focus();
// Input-Event-Listener für Echtzeit-Validierung
codeInput.addEventListener('input', function(e) {
// Nur alphanumerische Zeichen erlauben und zu Großbuchstaben konvertieren
let value = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, '');
// Maximal 6 Zeichen
if (value.length > 6) {
value = value.substring(0, 6);
}
e.target.value = value;
checkFormComplete();
});
// Enter-Taste für Submit
codeInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !submitBtn.disabled) {
form.dispatchEvent(new Event('submit'));
}
});
form.addEventListener('submit', async function(e) {
e.preventDefault();
@ -322,24 +308,13 @@ document.addEventListener('DOMContentLoaded', function() {
});
// Paste-Handler für kompletten Code
document.addEventListener('paste', function(e) {
const target = e.target;
if (target.classList.contains('code-input')) {
e.preventDefault();
const paste = (e.clipboardData || window.clipboardData).getData('text').toUpperCase();
if (paste.length === 6 && /^[A-Z0-9]+$/.test(paste)) {
const inputs = ['code1', 'code2', 'code3', 'code4', 'code5', 'code6'];
inputs.forEach((id, index) => {
const input = document.getElementById(id);
input.value = paste[index] || '';
if (input.value) {
input.classList.add('border-green-500', 'bg-green-50', 'dark:bg-green-900/20');
}
});
checkFormComplete();
document.getElementById('code6').focus();
}
codeInput.addEventListener('paste', function(e) {
e.preventDefault();
const paste = (e.clipboardData || window.clipboardData).getData('text').toUpperCase().replace(/[^A-Z0-9]/g, '');
if (paste.length <= 6) {
codeInput.value = paste;
checkFormComplete();
}
});
});