Online Real-Time Student Participation Tracker

Online Real-Time Student Participation Tracker

Session Time

00:00:00

Total Participation: ${totalParticipation}

`; studentTrackerGrid.insertAdjacentHTML('beforeend', card); }); } /** * Renders the summary table. */ function renderSummary() { if (!summaryTableBody) return; summaryTableBody.innerHTML = ''; students.forEach(student => { const total = student.questions + student.comments; const row = ` ${student.name} ${student.questions} ${student.comments} ${total} `; summaryTableBody.insertAdjacentHTML('beforeend', row); }); if (students.length === 0) { summaryTableBody.innerHTML = `No students configured.`; } } /** * Increments a student's participation count. * @param {number} studentId - The ID of the student. * @param {'questions' | 'comments'} type - The type of participation. */ window.incrementParticipation = function(studentId, type) { const student = students.find(s => s.id === studentId); if (student && sessionActive) { student[type]++; renderTracker(); renderSummary(); } else if (!sessionActive) { alert("Please start the session to track participation."); } }; // --- Session Timer Functions --- function startTimer() { if (sessionActive) return; sessionActive = true; timerInterval = setInterval(() => { elapsedSeconds++; updateTimerDisplay(); }, 1000); toggleSessionButtons(true); } function stopTimer() { sessionActive = false; clearInterval(timerInterval); toggleSessionButtons(false); } function resetSession() { stopTimer(); elapsedSeconds = 0; updateTimerDisplay(); students.forEach(s => { s.questions = 0; s.comments = 0; }); renderTracker(); renderSummary(); } function updateTimerDisplay() { const hours = Math.floor(elapsedSeconds / 3600).toString().padStart(2, '0'); const minutes = Math.floor((elapsedSeconds % 3600) / 60).toString().padStart(2, '0'); const seconds = (elapsedSeconds % 60).toString().padStart(2, '0'); timerDisplay.textContent = `${hours}:${minutes}:${seconds}`; } function toggleSessionButtons(isActive) { if(startBtn) startBtn.disabled = isActive; if(stopBtn) stopBtn.disabled = !isActive; if(startBtn) startBtn.classList.toggle('opacity-50', isActive); if(stopBtn) stopBtn.classList.toggle('opacity-50', !isActive); } // --- Tab Navigation --- window.changeTab = function(tabNumber) { currentTab = tabNumber; updateTabVisibility(); }; window.navigateTabs = function(direction) { if (direction === 'next' && currentTab < totalTabs) currentTab++; else if (direction === 'prev' && currentTab > 1) currentTab--; updateTabVisibility(); }; function updateTabVisibility() { Object.values(tabContents).forEach(content => content.classList.add('hidden')); Object.values(tabButtons).forEach(button => button.classList.remove('active')); if (tabContents[currentTab]) tabContents[currentTab].classList.remove('hidden'); if (tabButtons[currentTab]) tabButtons[currentTab].classList.add('active'); updateNavButtons(); } function updateNavButtons() { if (prevBtn) prevBtn.disabled = currentTab === 1; if (nextBtn) nextBtn.disabled = currentTab === totalTabs; if (prevBtn) prevBtn.classList.toggle('opacity-50', currentTab === 1); if (nextBtn) nextBtn.classList.toggle('opacity-50', currentTab === totalTabs); } // --- PDF Generation --- window.downloadPDF = async function() { const { jsPDF } = window.jspdf; const contentArea = document.getElementById('pdf-content-area'); if (!contentArea) { alert("Error: Could not find content to generate PDF."); return; } try { const canvas = await html2canvas(contentArea, { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgProps = pdf.getImageProperties(imgData); const imgHeight = (imgProps.height * pdfWidth) / imgProps.width; let heightLeft = imgHeight; let position = 15; // Initial top margin pdf.setFont("helvetica", "bold"); pdf.setFontSize(16); pdf.text("Student Participation Summary", pdfWidth / 2, 10, { align: 'center' }); pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight); heightLeft -= pdfHeight; while (heightLeft >= 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight); heightLeft -= pdfHeight; } pdf.save('Participation_Summary.pdf'); } catch (error) { console.error("Error generating PDF:", error); alert("An error occurred while generating the PDF."); } }; // --- EVENT LISTENERS --- if(startBtn) startBtn.addEventListener('click', startTimer); if(stopBtn) stopBtn.addEventListener('click', stopTimer); if(resetBtn) resetBtn.addEventListener('click', resetSession); // --- INITIALIZE THE TOOL --- initialize(); });
Scroll to Top