Interactive Customer Service Knowledge Base

Interactive Customer Service Knowledge Base

Find answers to common questions and support issues.

Categories

Articles

Welcome to the Knowledge Base

Select an article from the left to view its content here.

No articles found.

`; return; } articlesList.innerHTML = articlesToRender.map(article => `${article.title}` ).join(''); }; const displayArticle = (articleId) => { const article = KB_ARTICLES.find(a => a.id === articleId); if (!article) { initialMessage.classList.remove('hidden'); articleContentWrapper.classList.add('hidden'); activeArticleId = null; return; } activeArticleId = articleId; document.querySelectorAll('.article-link').forEach(link => link.classList.remove('active')); const activeLink = document.querySelector(`.article-link[data-id='${articleId}']`); if(activeLink) activeLink.classList.add('active'); initialMessage.classList.add('hidden'); articleContentWrapper.classList.remove('hidden'); articleTitle.textContent = article.title; articleCategory.textContent = article.category; articleContent.innerHTML = article.content; }; const filterAndRenderArticles = () => { const searchTerm = searchInput.value.toLowerCase(); const activeCategoryBtn = categoriesContainer.querySelector('.category-btn.active'); const activeCategory = activeCategoryBtn ? activeCategoryBtn.dataset.category : 'All'; let filteredArticles = KB_ARTICLES; if (activeCategory !== 'All') filteredArticles = filteredArticles.filter(a => a.category === activeCategory); if (searchTerm) filteredArticles = filteredArticles.filter(a => a.title.toLowerCase().includes(searchTerm) || a.content.toLowerCase().includes(searchTerm)); renderArticles(filteredArticles); }; // --- CRUD & FORM LOGIC --- const resetForm = () => { editingArticleId = null; formHeader.textContent = "Add New Article"; formTitle.value = ''; formCategory.value = ''; formContent.value = ''; cancelBtn.classList.add('hidden'); }; const populateFormForEdit = (articleId) => { const article = KB_ARTICLES.find(a => a.id === articleId); if (article) { editingArticleId = article.id; formHeader.textContent = "Edit Article"; formTitle.value = article.title; formCategory.value = article.category; formContent.value = article.content; cancelBtn.classList.remove('hidden'); } }; const handleSave = () => { const title = formTitle.value.trim(); const category = formCategory.value.trim(); const content = formContent.value.trim(); if (!title || !category || !content) { alert('Please fill all fields.'); return; } if (editingArticleId) { // Update const index = KB_ARTICLES.findIndex(a => a.id === editingArticleId); if (index > -1) { KB_ARTICLES[index] = { ...KB_ARTICLES[index], title, category, content }; } } else { // Create const newId = KB_ARTICLES.length > 0 ? Math.max(...KB_ARTICLES.map(a => a.id)) + 1 : 1; KB_ARTICLES.push({ id: newId, title, category, content }); } resetForm(); renderAll(); // If the updated article was being viewed, refresh its content if(activeArticleId && activeArticleId === editingArticleId) displayArticle(activeArticleId); }; const handleDelete = (articleId) => { if (confirm('Are you sure you want to delete this article?')) { KB_ARTICLES = KB_ARTICLES.filter(a => a.id !== articleId); if (activeArticleId === articleId) { displayArticle(null); // Clear view if deleted article was active } renderAll(); } }; // --- EVENT HANDLERS --- const handleCategoryClick = (e) => { if (e.target.classList.contains('category-btn')) { categoriesContainer.querySelectorAll('.category-btn').forEach(btn => btn.classList.remove('active')); e.target.classList.add('active'); filterAndRenderArticles(); } }; const handleArticleClick = (e) => { e.preventDefault(); const link = e.target.closest('.article-link'); if (link) displayArticle(parseInt(link.dataset.id)); }; const handleManageTableClick = (e) => { const target = e.target; const id = parseInt(target.closest('tr')?.querySelector('.edit-btn, .delete-btn')?.dataset.id); if (target.classList.contains('edit-btn')) populateFormForEdit(id); if (target.classList.contains('delete-btn')) handleDelete(id); }; const generatePDF = () => { if (!activeArticleId) return; const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); pdfContent.querySelector('#pdf-button-container')?.classList.add('hidden'); html2canvas(pdfContent, { scale: 2, useCORS: true }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgWidth = pdfWidth - 20; const imgHeight = (canvas.height * imgWidth) / canvas.width; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); const safeTitle = articleTitle.textContent.replace(/[^a-z0-9]/gi, '_').toLowerCase(); pdf.save(`kb-${safeTitle}.pdf`); pdfContent.querySelector('#pdf-button-container')?.classList.remove('hidden'); }); }; // --- ATTACH LISTENERS --- // Nav prevBtn.addEventListener('click', () => showTab('kb')); nextBtn.addEventListener('click', () => showTab('manage')); tabButtons.kb.addEventListener('click', () => showTab('kb')); tabButtons.manage.addEventListener('click', () => showTab('manage')); // KB View searchInput.addEventListener('input', filterAndRenderArticles); categoriesContainer.addEventListener('click', handleCategoryClick); articlesList.addEventListener('click', handleArticleClick); downloadPdfBtn.addEventListener('click', generatePDF); // Manage View manageTableBody.addEventListener('click', handleManageTableClick); saveBtn.addEventListener('click', handleSave); cancelBtn.addEventListener('click', resetForm); // --- INITIALIZATION --- renderAll(); });
Scroll to Top