class UIController { constructor(peerManager, pollManager) { this.peerManager = peerManager; this.pollManager = pollManager; this.initializeEventListeners(); } initializeEventListeners() { // Connection controls document.getElementById('join-btn').addEventListener('click', () => this.handleJoinRoom()); document.getElementById('copy-id-btn').addEventListener('click', () => this.copyPeerId()); // Poll creation document.getElementById('create-poll-btn').addEventListener('click', () => this.handleCreatePoll()); document.getElementById('add-option-btn').addEventListener('click', () => this.addOptionInput()); // Active poll document.getElementById('add-poll-option-btn').addEventListener('click', () => this.showAddOptionModal()); document.getElementById('reset-poll-btn').addEventListener('click', () => this.handleResetPoll()); document.getElementById('new-poll-btn').addEventListener('click', () => this.handleNewPoll()); // Modal controls document.getElementById('close-modal-btn').addEventListener('click', () => this.hideAddOptionModal()); document.getElementById('cancel-modal-btn').addEventListener('click', () => this.hideAddOptionModal()); document.getElementById('save-option-btn').addEventListener('click', () => this.handleAddOptionFromModal()); // Enter key handlers document.getElementById('room-id').addEventListener('keypress', (e) => { if (e.key === 'Enter') this.handleJoinRoom(); }); document.getElementById('poll-question').addEventListener('keypress', (e) => { if (e.key === 'Enter') this.handleCreatePoll(); }); document.getElementById('new-option-input').addEventListener('keypress', (e) => { if (e.key === 'Enter') this.handleAddOptionFromModal(); }); // Close modal on background click document.getElementById('add-option-modal').addEventListener('click', (e) => { if (e.target.id === 'add-option-modal') { this.hideAddOptionModal(); } }); } handleJoinRoom() { const roomIdInput = document.getElementById('room-id'); const peerId = roomIdInput.value.trim(); this.showLoading(true); if (peerId) { // Connect to existing peer (host) this.peerManager.joinRoom(peerId) .then(() => { this.showNotification('Connected to host successfully!', 'success'); this.showPollCreation(); }) .catch(error => { this.showNotification('Failed to connect: ' + error.message, 'error'); console.error('Connect error:', error); }) .finally(() => { this.showLoading(false); }); } else { // Act as host - just show poll creation this.peerManager.createRoom(); this.showNotification('You are the host. Share your Peer ID with others to connect.', 'success'); this.showPollCreation(); this.showLoading(false); } } async copyPeerId() { const peerId = this.peerManager.getPeerId(); if (peerId) { try { await navigator.clipboard.writeText(peerId); this.showNotification('Peer ID copied to clipboard!', 'success'); } catch (error) { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = peerId; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); this.showNotification('Peer ID copied to clipboard!', 'success'); } } } handleCreatePoll() { const questionInput = document.getElementById('poll-question'); const optionInputs = document.querySelectorAll('.option-text'); const options = []; console.log('Question input:', questionInput); console.log('Found option inputs:', optionInputs.length); // Check if question input exists if (!questionInput) { console.error('Question input not found!'); this.showNotification('Error: Question input not found', 'error'); return; } const question = questionInput.value ? questionInput.value.trim() : ''; console.log('Question:', question); optionInputs.forEach((input, index) => { console.log(`Input ${index}:`, input, 'value:', input?.value); if (input && typeof input.value !== 'undefined') { const text = input.value.trim(); if (text) { options.push(text); } } else { console.warn(`Input ${index} is invalid or has no value property`); } }); console.log('Final options:', options); if (!question) { this.showNotification('Please enter a poll question', 'error'); return; } if (options.length < 2) { this.showNotification('Please enter at least 2 options', 'error'); return; } try { this.pollManager.createPoll(question, options); this.showNotification('Poll created successfully!', 'success'); } catch (error) { console.error('Create poll error:', error); this.showNotification('Failed to create poll: ' + error.message, 'error'); } } showAddOptionModal() { const modal = document.getElementById('add-option-modal'); const input = document.getElementById('new-option-input'); modal.classList.remove('hidden'); input.value = ''; input.focus(); } hideAddOptionModal() { const modal = document.getElementById('add-option-modal'); const input = document.getElementById('new-option-input'); modal.classList.add('hidden'); input.value = ''; } handleAddOptionFromModal() { const input = document.getElementById('new-option-input'); const optionText = input.value.trim(); if (!optionText) { this.showNotification('Please enter an option text', 'error'); return; } try { this.pollManager.addOption(optionText); this.hideAddOptionModal(); this.showNotification('Option added successfully!', 'success'); } catch (error) { this.showNotification('Failed to add option: ' + error.message, 'error'); } } handleAddPollOption() { this.showAddOptionModal(); } handleResetPoll() { if (confirm('Are you sure you want to reset all votes?')) { try { this.pollManager.resetPoll(); this.showNotification('Poll reset successfully!', 'success'); } catch (error) { this.showNotification('Failed to reset poll: ' + error.message, 'error'); } } } handleNewPoll() { this.pollManager.createNewPoll(); this.showPollCreation(); this.clearPollForm(); } addOptionInput() { const container = document.getElementById('options-container'); const optionCount = container.children.length; const optionDiv = document.createElement('div'); optionDiv.className = 'option-input'; optionDiv.innerHTML = ` `; container.appendChild(optionDiv); this.updateOptionRemoveButtons(); // Add event listener to new input const newInput = optionDiv.querySelector('.option-text'); newInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') this.handleCreatePoll(); }); // Add event listener to remove button const removeBtn = optionDiv.querySelector('.remove-option-btn'); removeBtn.addEventListener('click', () => { optionDiv.remove(); this.updateOptionRemoveButtons(); this.updateOptionPlaceholders(); }); // Focus on new input newInput.focus(); } updateOptionRemoveButtons() { const optionInputs = document.querySelectorAll('.option-input'); const removeButtons = document.querySelectorAll('.remove-option-btn'); removeButtons.forEach((btn, index) => { if (optionInputs.length <= 2) { btn.classList.add('hidden'); } else { btn.classList.remove('hidden'); } }); } updateOptionPlaceholders() { const optionInputs = document.querySelectorAll('.option-text'); optionInputs.forEach((input, index) => { input.placeholder = `Option ${index + 1}`; }); } clearPollForm() { document.getElementById('poll-question').value = ''; const container = document.getElementById('options-container'); container.innerHTML = `
No polls created yet
'; return; } pollsList.innerHTML = ''; polls.forEach(poll => { const pollDiv = document.createElement('div'); pollDiv.className = 'poll-item'; if (this.pollManager.getCurrentPoll() && this.pollManager.getCurrentPoll().id === poll.id) { pollDiv.classList.add('active'); } const totalVotes = poll.options.reduce((sum, opt) => sum + opt.votes, 0); const createdDate = new Date(poll.createdAt).toLocaleString(); pollDiv.innerHTML = `