Customer Support Ticketing System

Customer Support Ticketing System

Manage and track customer support requests efficiently.

Current Tickets

Ticket ID Customer Subject Priority Status Created

${openTickets}

In Progress

${inProgressTickets}

Closed

${closedTickets}

`; // 2. Render Tickets Table const tableBody = document.getElementById('tickets-table-body'); const filteredTickets = tickets.filter(t => (statusFilter === 'all' || t.status === statusFilter) && (priorityFilter === 'all' || t.priority === priorityFilter) ); tableBody.innerHTML = ''; if (filteredTickets.length === 0) { tableBody.innerHTML = `No tickets match the current filters.`; return; } filteredTickets.forEach(ticket => { const row = document.createElement('tr'); row.className = 'text-sm text-gray-700'; row.innerHTML = ` TICKET-${ticket.id.toString().padStart(4, '0')} ${ticket.customer} ${ticket.subject} ${ticket.created} `; tableBody.appendChild(row); }); }; // --- EVENT HANDLERS --- const handleNavClick = (isNext) => { showTab(isNext ? 'config' : 'dashboard'); }; const handleCreateTicket = () => { const name = document.getElementById('customer-name').value.trim(); const email = document.getElementById('customer-email').value.trim(); const subject = document.getElementById('ticket-subject').value.trim(); const description = document.getElementById('ticket-description').value.trim(); const priority = document.getElementById('ticket-priority').value; if (!name || !email || !subject || !description) { alert('Please fill out all fields to create a ticket.'); return; } const newId = tickets.length > 0 ? Math.max(...tickets.map(t => t.id)) + 1 : 1; const newTicket = { id: newId, customer: name, email: email, subject: subject, description: description, priority: priority, status: 'Open', created: new Date().toISOString().split('T')[0] }; tickets.unshift(newTicket); // Add to the top of the list document.getElementById('customer-name').value = ''; document.getElementById('customer-email').value = ''; document.getElementById('ticket-subject').value = ''; document.getElementById('ticket-description').value = ''; showTab('dashboard'); renderDashboard(); }; const handleTableUpdate = (e) => { const target = e.target; if (target.tagName !== 'SELECT' || !target.dataset.id) return; const ticketId = parseInt(target.dataset.id); const field = target.dataset.field; const value = target.value; const ticket = tickets.find(t => t.id === ticketId); if (ticket) { ticket[field] = value; renderDashboard(); // Re-render to update counts and potentially re-filter } }; const generatePDF = () => { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); if (!pdfContent) return; // Temporarily hide filter elements for a clean PDF const filters = pdfContent.querySelector('.no-print'); if (filters) filters.style.display = 'none'; // Temporarily disable dropdowns for a clean PDF const selects = pdfContent.querySelectorAll('select'); selects.forEach(s => s.style.appearance = 'none'); html2canvas(pdfContent, { scale: 2, useCORS: true }).then(canvas => { // Restore visibility after capture if (filters) filters.style.display = 'flex'; selects.forEach(s => s.style.appearance = 'auto'); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'l', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgWidth = pdfWidth - 20; const imgHeight = (canvas.height * imgWidth) / canvas.width; pdf.setFontSize(22); pdf.setFont('helvetica', 'bold'); pdf.text('Customer Support Ticket Report', pdfWidth / 2, 15, { align: 'center' }); pdf.addImage(imgData, 'PNG', 10, 25, imgWidth, imgHeight); pdf.save('customer-support-tickets.pdf'); }).catch(err => { console.error("Error generating PDF:", err); if (filters) filters.style.display = 'flex'; // Restore on error too selects.forEach(s => s.style.appearance = 'auto'); }); }; // --- ATTACH LISTENERS --- prevBtn.addEventListener('click', () => handleNavClick(false)); nextBtn.addEventListener('click', () => handleNavClick(true)); tabButtons.dashboard.addEventListener('click', () => showTab('dashboard')); tabButtons.config.addEventListener('click', () => showTab('config')); createTicketBtn.addEventListener('click', handleCreateTicket); downloadPdfBtn.addEventListener('click', generatePDF); // Listen for changes on filter dropdowns and the main table document.getElementById('filter-status').addEventListener('change', renderDashboard); document.getElementById('filter-priority').addEventListener('change', renderDashboard); document.getElementById('tickets-table-body').addEventListener('change', handleTableUpdate); // --- INITIAL RENDER --- renderDashboard(); });
Scroll to Top