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();
});