Online Anonymous Employee Feedback Collector

Online Anonymous Employee Feedback Collector

Submit Your Feedback Anonymously

Your identity will not be recorded. Please be constructive and respectful.

No feedback matching your criteria.

'; return; } display.innerHTML = filteredFeedback.map(fb => { const category = feedbackCategories.find(c => c.id === fb.categoryId); return `
${category ? category.name : 'Uncategorized'} Submitted: ${fb.submissionDate}

${fb.message}

`; }).join(''); } function renderCategoryList() { const list = document.getElementById('categoryList'); if(!list) return; list.innerHTML = feedbackCategories.map(cat => `
  • ${cat.name}
  • `).join(''); } // --- EVENT HANDLERS & LOGIC --- window.changeTab = (tabName) => { currentTab = tabName; Object.keys(tabElements).forEach(key => { tabElements[key].classList.toggle('hidden', key !== tabName); tabButtons[key].classList.toggle('active', key === tabName); }); updateNavButtons(); }; window.navigateTabs = (direction) => { const currentIndex = tabs.indexOf(currentTab); let nextIndex; if (direction === 'next') { nextIndex = (currentIndex + 1) % tabs.length; } else { nextIndex = (currentIndex - 1 + tabs.length) % tabs.length; } changeTab(tabs[nextIndex]); }; const updateNavButtons = () => { const currentIndex = tabs.indexOf(currentTab); prevButton.classList.toggle('invisible', currentIndex === 0); nextButton.classList.toggle('invisible', currentIndex === tabs.length - 1); }; if (feedbackForm) { feedbackForm.addEventListener('submit', (e) => { e.preventDefault(); const categoryId = parseInt(document.getElementById('feedbackCategory').value); const message = document.getElementById('feedbackMessage').value.trim(); if (!categoryId || !message) { alert('Please select a category and write a message.'); return; } const newId = feedbackSubmissions.length > 0 ? Math.max(...feedbackSubmissions.map(fb => fb.id)) + 1 : 1; const submissionDate = new Date().toISOString().split('T')[0]; feedbackSubmissions.push({ id: newId, categoryId, message, submissionDate }); alert('Thank you! Your feedback has been submitted successfully.'); feedbackForm.reset(); renderFeedback(); // Update dashboard in the background }); } if (addCategoryForm) { addCategoryForm.addEventListener('submit', (e) => { e.preventDefault(); const input = document.getElementById('newCategoryName'); const newName = input.value.trim(); if (newName) { const newId = feedbackCategories.length > 0 ? Math.max(...feedbackCategories.map(c => c.id)) + 1 : 1; feedbackCategories.push({ id: newId, name: newName }); populateCategoryDropdowns(); renderCategoryList(); input.value = ''; alert('Category added successfully!'); } }); } window.deleteCategory = (id) => { if (confirm('Are you sure you want to delete this category? All associated feedback will be uncategorized.')) { feedbackCategories = feedbackCategories.filter(c => c.id !== id); // Optionally handle feedback associated with the deleted category feedbackSubmissions.forEach(fb => { if (fb.categoryId === id) { fb.categoryId = null; // Or re-assign to a default 'Uncategorized' category } }); populateCategoryDropdowns(); renderCategoryList(); renderFeedback(); } }; // --- PDF DOWNLOAD FUNCTIONALITY --- window.downloadPDF = async function() { if (typeof window.jspdf === 'undefined' || typeof Chart === 'undefined') { alert("Required libraries for PDF generation are not loaded."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'pt', 'a4'); const filteredData = feedbackSubmissions.filter(fb => { const categoryFilter = document.getElementById('categoryFilter').value; return !categoryFilter || fb.categoryId == categoryFilter; }); const categoryCounts = feedbackCategories.reduce((acc, cat) => { acc[cat.name] = 0; return acc; }, {}); filteredData.forEach(fb => { const category = feedbackCategories.find(c => c.id === fb.categoryId); if (category && categoryCounts.hasOwnProperty(category.name)) { categoryCounts[category.name]++; } }); const canvas = document.createElement('canvas'); canvas.width = 450; canvas.height = 225; new Chart(canvas.getContext('2d'), { type: 'bar', data: { labels: Object.keys(categoryCounts), datasets: [{ label: '# of Submissions', data: Object.values(categoryCounts), backgroundColor: ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899'], }] }, options: { indexAxis: 'y', responsive: false, animation: false, plugins: { legend: { display: false } } } }); await new Promise(resolve => setTimeout(resolve, 500)); const chartImage = canvas.toDataURL('image/png'); const pageWidth = doc.internal.pageSize.getWidth(); const pageHeight = doc.internal.pageSize.getHeight(); doc.setFillColor(41, 128, 185); doc.rect(0, 0, pageWidth, 60, 'F'); doc.setFontSize(20); doc.setTextColor(255); doc.setFont('helvetica', 'bold'); doc.text('Anonymous Employee Feedback Report', 30, 38); doc.setFontSize(14); doc.setTextColor(50); doc.text('Feedback Summary', 30, 90); doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.text(`Total Submissions in Report: ${filteredData.length}`, 30, 110); doc.text(`Report Date: ${new Date().toLocaleString('en-US')}`, 30, 125); doc.addImage(chartImage, 'PNG', 30, 150, 535, 267); doc.addPage(); let y = 40; feedbackCategories.forEach(category => { const categoryFeedback = filteredData.filter(fb => fb.categoryId === category.id); if (categoryFeedback.length === 0) return; if (y > 40) y += 20; // Add space between sections doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text(category.name, 30, y); y += 15; categoryFeedback.forEach(fb => { doc.setFontSize(9); doc.setFont('helvetica', 'normal'); doc.setTextColor(100); doc.text(`Submitted: ${fb.submissionDate}`, 30, y); y += 12; doc.setTextColor(0); const splitMessage = doc.splitTextToSize(fb.message, pageWidth - 60); if (y + (splitMessage.length * 12) > pageHeight - 40) { doc.addPage(); y = 40; } doc.text(splitMessage, 30, y); y += (splitMessage.length * 12) + 10; doc.setDrawColor(200); doc.line(30, y, pageWidth - 30, y); y += 15; }); }); const pageCount = doc.internal.getNumberOfPages(); for(let i = 1; i <= pageCount; i++) { doc.setPage(i); doc.setFontSize(8); doc.setTextColor(150); doc.text(`Page ${i} of ${pageCount}`, pageWidth / 2, pageHeight - 20, { align: 'center' }); } doc.save('Employee_Feedback_Report.pdf'); }; // --- INITIALIZE THE APP --- initializeApp(); });
    Scroll to Top