Online Remote Exam Proctoring Tool

Remote Exam Proctoring Tool

Proctoring Dashboard

Live Student Monitoring

Select a student from the Dashboard to begin monitoring.

Proctoring Configuration

Allowed Applications & Websites

Export Proctoring Report

Monitor a student session to generate a report for export.

${e.time} ${e.msg}

`).join(''); // Show export option exportPlaceholder.classList.add('hidden'); exportContent.classList.remove('hidden'); reportStudentName.textContent = student.name; } // --- EVENT HANDLERS & LOGIC --- window.monitorStudent = (studentId) => { renderMonitoringView(studentId); changeTab(null, 'monitoring'); } function addWhitelistItem() { const item = whitelistInput.value.trim(); if (item && !whitelistedItems.includes(item)) { whitelistedItems.push(item); renderWhitelist(); whitelistInput.value = ''; } } window.removeWhitelistItem = (index) => { whitelistedItems.splice(index, 1); renderWhitelist(); } function addEventToLog(studentId, msg, level = 'warning') { const student = students.find(s => s.id === studentId); if(student) { const time = new Date().toLocaleTimeString('en-US', { hour12: false }); student.events.push({ time, msg }); if(level === 'danger') student.status = 'danger'; else if(level === 'warning' && student.status !== 'danger') student.status = 'warning'; if(monitoredStudentId === studentId) { renderMonitoringView(studentId); } renderStudentGrid(); } } flagBtn.addEventListener('click', () => { if(monitoredStudentId) { addEventToLog(monitoredStudentId, 'Proctor manually flagged session for review.', 'warning'); } }); endSessionBtn.addEventListener('click', () => { if(monitoredStudentId && confirm('Are you sure you want to end this session? This action cannot be undone.')) { addEventToLog(monitoredStudentId, 'Proctor manually ended the session.', 'danger'); // In a real app, this would also terminate the student's exam access. } }); function downloadPDF() { const student = students.find(s => s.id === monitoredStudentId); if (!student) { alert('No student session is being monitored.'); return; } const pdfContentEl = document.getElementById('pdf-content'); // Create the report content dynamically pdfContentEl.innerHTML = `

Proctoring Report


Student: ${student.name}

ID: ${student.id}

Date: ${new Date().toLocaleDateString()}

Event Log

${student.events.map(e => ` `).join('')}
Time Event Description
${e.time} ${e.msg}
`; const { jsPDF } = window.jspdf; html2canvas(pdfContentEl, { scale: 2 }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgProps = pdf.getImageProperties(imgData); const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); pdf.save(`Proctoring_Report_${student.name.replace(/\s/g, '_')}.pdf`); }); } // --- TAB NAVIGATION --- window.changeTab = function(evt, tabName) { document.querySelectorAll(".tab-content").forEach(tc => tc.classList.remove('active')); document.querySelectorAll(".tab-button").forEach(tb => tb.classList.remove('active')); document.getElementById(tabName).classList.add('active'); const button = evt ? evt.currentTarget : document.querySelector(`.tab-button[onclick*="'${tabName}'"]`); if(button) button.classList.add('active'); currentTab = tabName; updateNavButtons(); } function updateNavButtons() { const currentIndex = tabs.indexOf(currentTab); prevBtn.disabled = currentIndex === 0; nextBtn.disabled = currentIndex === tabs.length - 1; prevBtn.classList.toggle('opacity-50', prevBtn.disabled); nextBtn.classList.toggle('opacity-50', nextBtn.disabled); } window.navigateTabs = function(direction) { const currentIndex = tabs.indexOf(currentTab); let newIndex; if (direction === 'next' && currentIndex < tabs.length - 1) newIndex = currentIndex + 1; else if (direction === 'prev' && currentIndex > 0) newIndex = currentIndex - 1; if (newIndex !== undefined) changeTab(null, tabs[newIndex]); } // --- INITIALIZATION --- addWhitelistBtn.addEventListener('click', addWhitelistItem); downloadPdfBtn.addEventListener('click', downloadPDF); renderStudentGrid(); renderWhitelist(); updateNavButtons(); });
Scroll to Top