/** * Door Status Voting - Frontend JavaScript */ (function() { 'use strict'; document.addEventListener('DOMContentLoaded', function() { initDoorVoting(); }); function initDoorVoting() { const widgets = document.querySelectorAll('.dsv-widget'); widgets.forEach(function(widget) { // Vote Buttons const buttons = widget.querySelectorAll('.dsv-btn'); buttons.forEach(function(btn) { btn.addEventListener('click', function() { handleVote(widget, btn.dataset.vote); }); }); // Remove Vote Button const removeBtn = widget.querySelector('.dsv-remove-vote'); if (removeBtn) { removeBtn.addEventListener('click', function() { handleRemoveVote(widget); }); } }); } function handleVote(widget, vote) { const postId = widget.dataset.postId; const hasVoted = widget.dataset.hasVoted === 'true'; if (hasVoted) return; // Buttons deaktivieren const buttons = widget.querySelectorAll('.dsv-btn'); buttons.forEach(function(btn) { btn.disabled = true; }); // Animation starten widget.classList.add('dsv-animating'); // AJAX Request const formData = new FormData(); formData.append('action', 'dsv_vote'); formData.append('post_id', postId); formData.append('vote', vote); formData.append('nonce', dsvConfig.nonce); fetch(dsvConfig.ajaxUrl, { method: 'POST', body: formData, credentials: 'same-origin' }) .then(function(response) { return response.json(); }) .then(function(data) { if (data.success) { updateWidget(widget, data.data, vote); } else { console.error('Vote error:', data.data?.message); buttons.forEach(function(btn) { btn.disabled = false; }); } }) .catch(function(error) { console.error('Network error:', error); buttons.forEach(function(btn) { btn.disabled = false; }); }) .finally(function() { widget.classList.remove('dsv-animating'); }); } function handleRemoveVote(widget) { const postId = widget.dataset.postId; // Button deaktivieren const removeBtn = widget.querySelector('.dsv-remove-vote'); if (removeBtn) { removeBtn.disabled = true; removeBtn.textContent = '...'; } widget.classList.add('dsv-animating'); const formData = new FormData(); formData.append('action', 'dsv_remove_vote'); formData.append('post_id', postId); formData.append('nonce', dsvConfig.nonce); fetch(dsvConfig.ajaxUrl, { method: 'POST', body: formData, credentials: 'same-origin' }) .then(function(response) { return response.json(); }) .then(function(data) { if (data.success) { resetWidgetToVoting(widget, data.data); } else { console.error('Remove vote error:', data.data?.message); if (removeBtn) { removeBtn.disabled = false; removeBtn.textContent = '✕'; } } }) .catch(function(error) { console.error('Network error:', error); if (removeBtn) { removeBtn.disabled = false; removeBtn.textContent = '✕'; } }) .finally(function() { widget.classList.remove('dsv-animating'); }); } function updateWidget(widget, data, userVote) { // Status aktualisieren widget.dataset.status = data.status; widget.dataset.hasVoted = 'true'; widget.dataset.userVote = userVote; // Badge aktualisieren const badge = widget.querySelector('.dsv-status-badge'); badge.className = 'dsv-status-badge dsv-status-' + data.status; if (data.status === 'open') { badge.innerHTML = '🟢 GEÖFFNET'; } else if (data.status === 'closed') { badge.innerHTML = '🔴 GESCHLOSSEN'; } else { badge.innerHTML = '🟡 UNKLAR'; } // Fortschrittsbalken aktualisieren updateProgressBar(widget, data); // Buttons durch Bestätigung ersetzen const buttonsContainer = widget.querySelector('.dsv-buttons'); buttonsContainer.classList.add('dsv-voted'); const voteClass = userVote === 'open' ? 'dsv-voted-open' : 'dsv-voted-closed'; const voteIcon = userVote === 'open' ? '✓' : '✗'; const voteText = userVote === 'open' ? 'Geöffnet' : 'Geschlossen'; buttonsContainer.innerHTML = '
'; // Event Listener für neuen Remove Button const newRemoveBtn = buttonsContainer.querySelector('.dsv-remove-vote'); newRemoveBtn.addEventListener('click', function() { handleRemoveVote(widget); }); // Total aktualisieren widget.querySelector('.dsv-total').textContent = data.total; // Pulse Animation widget.classList.add('dsv-just-voted'); setTimeout(function() { widget.classList.remove('dsv-just-voted'); }, 500); } function resetWidgetToVoting(widget, data) { // Status aktualisieren widget.dataset.status = data.status; widget.dataset.hasVoted = 'false'; widget.dataset.userVote = ''; // Badge aktualisieren const badge = widget.querySelector('.dsv-status-badge'); badge.className = 'dsv-status-badge dsv-status-' + data.status; if (data.status === 'open') { badge.innerHTML = '🟢 GEÖFFNET'; } else if (data.status === 'closed') { badge.innerHTML = '🔴 GESCHLOSSEN'; } else { badge.innerHTML = '🟡 UNKLAR'; } // Fortschrittsbalken aktualisieren updateProgressBar(widget, data); // Voting Buttons wieder anzeigen const buttonsContainer = widget.querySelector('.dsv-buttons'); buttonsContainer.classList.remove('dsv-voted'); buttonsContainer.innerHTML = '' + ''; // Event Listener für neue Buttons const newButtons = buttonsContainer.querySelectorAll('.dsv-btn'); newButtons.forEach(function(btn) { btn.addEventListener('click', function() { handleVote(widget, btn.dataset.vote); }); }); // Total aktualisieren widget.querySelector('.dsv-total').textContent = data.total; } function updateProgressBar(widget, data) { const progressOpen = widget.querySelector('.dsv-progress-open'); const progressClosed = widget.querySelector('.dsv-progress-closed'); progressOpen.style.width = data.openPercent + '%'; progressClosed.style.width = (100 - data.openPercent) + '%'; // Zähler if (data.openPercent > 15) { progressOpen.innerHTML = '' + data.votes.open + ''; } else { progressOpen.innerHTML = ''; } if ((100 - data.openPercent) > 15) { progressClosed.innerHTML = '' + data.votes.closed + ''; } else { progressClosed.innerHTML = ''; } // Labels widget.querySelector('.dsv-label-open').textContent = 'Geöffnet (' + data.openPercent + '%)'; widget.querySelector('.dsv-label-closed').textContent = 'Geschlossen (' + (100 - data.openPercent) + '%)'; } })();