MOST RESOLVED
${topResolved.name}
${topResolved.ticketsResolved}
`;
}
function renderCharts(data) {
const labels = data.map(d => d.name);
resolvedChart.data = { labels, datasets: [{ label: 'Tickets Resolved', data: data.map(d => d.ticketsResolved), backgroundColor: '#007bff' }]};
csatChart.data = { labels, datasets: [{ label: 'Average CSAT', data: data.map(d => d.avgCsat), backgroundColor: '#28a745' }]};
resolvedChart.update();
csatChart.update();
}
function renderTicketTable() {
const tableBody = document.getElementById('ticket-table-body');
tableBody.innerHTML = '';
tickets.forEach(ticket => {
const agent = AGENTS.find(a => a.id === ticket.agentId);
const status = ticket.resolvedDate ? 'Resolved' : 'Open';
tableBody.innerHTML += `
| ${ticket.id} |
${ticket.customer} |
${agent ? agent.name : 'Unassigned'} |
${status} |
${ticket.csatScore || 'N/A'} |
${status === 'Open' ? '' : ''}
|
`;
});
}
// --- MODAL & CRUD ---
function openTicketModal(ticketId = null) {
const form = document.getElementById('ticket-form');
form.reset();
document.getElementById('modal-title').textContent = ticketId ? 'Edit Ticket' : 'Add New Ticket';
document.getElementById('ticket-id').value = ticketId || '';
if (ticketId) {
const ticket = tickets.find(t => t.id === ticketId);
if (ticket) {
document.getElementById('ticket-customer').value = ticket.customer;
document.getElementById('ticket-issue').value = ticket.issue;
document.getElementById('ticket-agent').value = ticket.agentId;
document.getElementById('ticket-status').value = ticket.resolvedDate ? 'Resolved' : 'Open';
document.getElementById('ticket-csat').value = ticket.csatScore || '';
document.getElementById('ticket-fcr').value = ticket.wasFCR.toString();
}
}
ticketModal.style.display = 'block';
}
function handleFormSubmit(e) {
e.preventDefault();
const id = parseInt(document.getElementById('ticket-id').value);
const now = new Date();
const ticketData = {
customer: document.getElementById('ticket-customer').value,
issue: document.getElementById('ticket-issue').value,
agentId: parseInt(document.getElementById('ticket-agent').value),
resolvedDate: document.getElementById('ticket-status').value === 'Resolved' ? now : null,
csatScore: parseInt(document.getElementById('ticket-csat').value) || null,
wasFCR: document.getElementById('ticket-fcr').value === 'true',
};
if (id) {
const index = tickets.findIndex(t => t.id === id);
tickets[index] = { ...tickets[index], ...ticketData };
} else {
const newId = tickets.length > 0 ? Math.max(...tickets.map(t => t.id)) + 1 : 1;
tickets.push({ id: newId, createdDate: now, ...ticketData });
}
ticketModal.style.display = 'none';
render();
}
// --- EVENT HANDLERS ---
function attachEventListeners() {
timeFilterEl.addEventListener('change', render);
document.getElementById('add-ticket-btn').addEventListener('click', () => openTicketModal());
document.getElementById('modal-cancel-btn').addEventListener('click', () => ticketModal.style.display = 'none');
document.getElementById('ticket-form').addEventListener('submit', handleFormSubmit);
document.getElementById('download-pdf-btn').addEventListener('click', generatePdf);
document.getElementById('ticket-table-body').addEventListener('click', e => {
const ticketId = parseInt(e.target.closest('tr')?.dataset.ticketId);
if (!ticketId) return;
if (e.target.classList.contains('edit-btn')) {
openTicketModal(ticketId);
} else if (e.target.classList.contains('delete-btn')) {
if (confirm(`Are you sure you want to delete ticket ${ticketId}?`)) {
tickets = tickets.filter(t => t.id !== ticketId);
render();
}
} else if (e.target.classList.contains('resolve-btn')) {
const index = tickets.findIndex(t => t.id === ticketId);
tickets[index].resolvedDate = new Date();
render();
}
});
tabButtons.forEach((button, index) => button.addEventListener('click', () => {
activeTabIndex = index;
tabButtons.forEach(btn => btn.classList.remove('active'));
tabPanes.forEach(pane => pane.classList.remove('active'));
button.classList.add('active');
document.getElementById(`tab-pane-${index}`).classList.add('active');
}));
}
// --- PDF ---
function generatePdf() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFontSize(18);
doc.text(`Agent Performance Report`, 14, 22);
if (activeTabIndex === 0) {
doc.autoTable({ startY: 30, html: document.querySelector('.apd-leaderboard') });
} else {
doc.autoTable({ startY: 30, html: document.getElementById('ticket-table-body').parentElement });
}
doc.save(`Agent_Performance_Report.pdf`);
}
initialize();
});