/**
* Admin Panel - Support Tickets Logic (Premium Refactor)
*/
let allTickets = [];
let filteredTickets = [];
let activeTicketId = null;
async function updateTicketBadges() {
try {
const res = await fetch('/api/admin/tickets');
const tickets = await res.json();
const openCount = tickets.filter(t => t.status === 'open').length;
const badge = document.getElementById('open-tkt-badge');
const navBadge = document.getElementById('open-ticket-count');
if (badge) {
badge.innerText = `${openCount} Open`;
badge.style.display = 'inline-block';
}
if (navBadge) {
navBadge.innerText = openCount;
navBadge.style.display = openCount > 0 ? 'inline-block' : 'none';
}
} catch (e) {}
}
async function loadTickets() {
const container = document.getElementById('ticket-items');
if (!container) return;
container.innerHTML = `
Loading Tickets...
`;
try {
const res = await fetch('/api/admin/tickets');
allTickets = await res.json();
applyTicketSearch(); // This will render the list
updateTicketBadges();
} catch (err) {
container.innerHTML = 'Error loading tickets.
';
}
}
function applyTicketSearch() {
const searchInput = document.getElementById('tkt-search');
const searchTerm = searchInput ? searchInput.value.toLowerCase().trim() : '';
filteredTickets = allTickets.filter(t => {
const searchable = `${t.ticket_number} ${t.user_name} ${t.subject} ${t.status}`.toLowerCase();
return searchable.includes(searchTerm);
});
renderTicketList(filteredTickets);
}
function filterTkts(status, btn) {
// UI Update for Filter Buttons
document.querySelectorAll('.s-filter-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
// Filtering Logic
if (status === 'all') {
filteredTickets = allTickets;
} else {
filteredTickets = allTickets.filter(t => t.status === status);
}
renderTicketList(filteredTickets);
}
function renderTicketList(tickets) {
const container = document.getElementById('ticket-items');
if(!container) return;
if (tickets.length === 0) {
container.innerHTML = `
`;
return;
}
container.innerHTML = tickets.map(t => {
const isActive = activeTicketId === t.id ? 'active' : '';
const initial = (t.user_name || 'U').charAt(0).toUpperCase();
const priorityColor = t.priority === 'high' ? '#ef4444' : (t.priority === 'medium' ? '#f59e0b' : '#3b82f6');
return `
#${escapeHtml(t.ticket_number)}
${escapeHtml(t.date.split(',')[0])}
${initial}
${escapeHtml(t.user_name)}
${escapeHtml(t.subject)}
${t.status.toUpperCase()}
${t.category.toUpperCase()}
`;
}).join('');
}
async function selectTicket(id) {
activeTicketId = id;
renderTicketList(filteredTickets); // Update active class
const workspace = document.getElementById('ticket-detail-col');
if(!workspace) return;
workspace.innerHTML = `
`;
try {
const res = await fetch(`/api/admin/tickets/${id}`);
const t = await res.json();
workspace.innerHTML = `
${escapeHtml(t.subject)}
${escapeHtml(t.user_name)}
${escapeHtml(t.user_phone)}
${escapeHtml(t.ticket_number)}
${t.messages.map(m => `
${escapeHtml(m.message)}
${escapeHtml(m.time)}
`).join('')}
`;
// Auto-scroll to bottom
const chat = document.getElementById('chat-window');
if(chat) chat.scrollTop = chat.scrollHeight;
} catch (err) {
workspace.innerHTML = 'Failed to load ticket details.
';
}
}
async function sendReply(id) {
const textInput = document.getElementById('admin-reply-text');
if(!textInput) return;
const text = textInput.value.trim();
if (!text) return;
const sendBtn = document.querySelector('.send-reply-btn');
if (sendBtn) {
sendBtn.innerHTML = ' Sending...';
sendBtn.disabled = true;
}
try {
const res = await fetch(`/api/admin/tickets/${id}/reply`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: text })
});
if (res.ok) {
selectTicket(id); // Reload chat
}
} catch (e) {
alert('Error sending reply.');
}
}
async function updateStatus(id, status) {
try {
const res = await fetch(`/api/admin/tickets/${id}/status`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: status })
});
if (res.ok) {
loadTickets(); // Refresh sidebar list
selectTicket(id); // Refresh workspace view
}
} catch (e) {}
}
function escapeHtml(value) {
return String(value)
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"')
.replaceAll("'", ''');
}