Fehlerbehebung beim Timelock, Neues Feature Keyholder finden

This commit is contained in:
2026-03-26 22:45:37 +01:00
parent 03118d339a
commit 0baf667ee7
47 changed files with 5326 additions and 2172 deletions

View File

@@ -678,6 +678,29 @@
</div>
</div>
<!-- Temp-Öffnung-Modal (CARD / TASK / etc.) -->
<div class="hygiene-modal-backdrop" id="tempOpeningModal">
<div class="hygiene-modal-box">
<div class="hygiene-modal-icon">🔓</div>
<h3>Lock geöffnet</h3>
<!-- Phase 1: Code anzeigen -->
<div id="tempPhase1" style="width:100%;display:flex;flex-direction:column;align-items:center;gap:0.75rem;">
<p style="margin:0;font-size:0.88rem;color:var(--color-muted);">Dein aktueller Entsperrcode:</p>
<div class="hygiene-unlock-code" id="tempOpeningCode"></div>
<button class="btn-draw-ok" style="margin-top:0.25rem;" onclick="endTempOpeningFlow()">🔒 Öffnung beenden</button>
</div>
<!-- Phase 2: Neuer Code (nur UNLOCK_CODE) -->
<div id="tempPhase2" style="display:none;width:100%;flex-direction:column;align-items:center;gap:0.75rem;">
<p id="tempPhase2Hint" style="margin:0;font-size:0.88rem;color:var(--color-muted);">Dein neuer Code zum Abschließen:</p>
<div class="hygiene-unlock-code" id="tempNewCode"></div>
<div id="tempScrambleCountdown" style="display:none;font-size:0.82rem;color:var(--color-muted);font-family:monospace;"></div>
<button class="btn-draw-ok" id="tempPhase2Btn" onclick="startTempScramble()">OK</button>
</div>
</div>
</div>
<!-- Karte-Ziehen-Modal -->
<div class="draw-modal-backdrop" id="drawModal">
<div class="draw-modal-box">
@@ -811,6 +834,7 @@
renderNextCardPanel(lock);
renderHygienePanel(lock);
renderVerificationPanel(lock);
renderTempOpeningPanel(lock);
renderCardsPanel(lock);
if (lock.keyholderRequestedUnlock) {
@@ -1508,6 +1532,111 @@
}, 1000);
}
// ── Temp-Öffnung (CARD / TASK / etc.) ──
function renderTempOpeningPanel(lock) {
if (lock.tempOpeningActive) {
document.getElementById('tempOpeningCode').textContent = lock.tempOpeningUnlockCode || '';
document.getElementById('tempPhase1').style.display = '';
document.getElementById('tempPhase2').style.display = 'none';
document.querySelector('#tempOpeningModal h3').textContent = 'Lock geöffnet';
document.getElementById('tempOpeningModal').classList.add('open');
} else {
document.getElementById('tempOpeningModal').classList.remove('open');
}
}
async function endTempOpeningFlow() {
const isTtlock = _currentLock && _currentLock.controllType === 'TTLOCK';
const isTrust = _currentLock && _currentLock.controllType === 'TRUST';
if (isTtlock) {
document.getElementById('tempOpeningModal').classList.remove('open');
document.getElementById('ttlLoadingModal').classList.add('open');
}
const res = await fetch('/keyholder/cardlock/' + lockId + '/hygiene/end', { method: 'POST' });
if (isTtlock) {
document.getElementById('ttlLoadingModal').classList.remove('open');
if (!res.ok) { alert('Fehler beim Beenden der Öffnung.'); return; }
loadLock();
return;
}
if (!res.ok) { alert('Fehler beim Beenden der Öffnung.'); return; }
const data = await res.json();
if (isTrust || !data.newUnlockCode) {
document.getElementById('tempOpeningModal').classList.remove('open');
loadLock();
return;
}
// UNLOCK_CODE: neuen Code anzeigen
document.getElementById('tempPhase1').style.display = 'none';
document.getElementById('tempPhase2').style.display = 'flex';
document.getElementById('tempNewCode').textContent = data.newUnlockCode;
document.getElementById('tempPhase2Hint').style.display = '';
document.getElementById('tempPhase2Btn').textContent = 'OK';
document.getElementById('tempPhase2Btn').onclick = startTempScramble;
document.getElementById('tempScrambleCountdown').style.display = 'none';
document.querySelector('#tempOpeningModal h3').textContent = 'Lock geöffnet';
}
function closeTempOpeningModal() {
document.getElementById('tempOpeningModal').classList.remove('open');
if (tempScrambleTimer) { clearInterval(tempScrambleTimer); tempScrambleTimer = null; }
if (tempScrambleCd) { clearInterval(tempScrambleCd); tempScrambleCd = null; }
loadLock();
}
let tempScrambleTimer = null;
let tempScrambleCd = null;
function startTempScramble() {
const codeEl = document.getElementById('tempNewCode');
const hintEl = document.getElementById('tempPhase2Hint');
const cdEl = document.getElementById('tempScrambleCountdown');
const btnEl = document.getElementById('tempPhase2Btn');
const realCode = codeEl.textContent;
const len = realCode.length;
const DURATION = 3 * 60;
let remaining = DURATION;
let stopped = false;
function randomCode() {
return Array.from({ length: len }, () => Math.floor(Math.random() * 10)).join('');
}
function finish() {
stopped = true;
clearInterval(tempScrambleTimer); tempScrambleTimer = null;
clearInterval(tempScrambleCd); tempScrambleCd = null;
closeTempOpeningModal();
}
hintEl.style.display = 'none';
cdEl.style.display = '';
document.querySelector('#tempOpeningModal h3').textContent = 'Nun vergessen wir den Code…';
btnEl.textContent = 'Abbrechen';
btnEl.onclick = finish;
function updateCd() {
const m = Math.floor(remaining / 60);
const s = remaining % 60;
cdEl.textContent = `${m}:${String(s).padStart(2,'0')}`;
}
updateCd();
tempScrambleTimer = setInterval(() => { if (!stopped) codeEl.textContent = randomCode(); }, 1000);
tempScrambleCd = setInterval(() => {
if (stopped) return;
remaining--;
updateCd();
if (remaining <= 0) finish();
}, 1000);
}
// ── Lock beenden ──
function lockBeendenFragen() {
document.getElementById('warnModalUnlockCode').textContent = _currentLock ? (_currentLock.unlockCode || '') : '';