import { fetchTicket, fetchComments, fetchHistory, createComment, logTime, formatDateTime, formatMinutes, getHistoryIcon, escapeHtml, linkify } from './ticket-shared.js'; document.addEventListener('DOMContentLoaded', async () => { const ticketId = new URLSearchParams(window.location.search).get('id'); if (!ticketId) return (window.location.href = '../admin.html'); const statusSelect = document.getElementById('status-select'); const priorityInput = document.getElementById('priority-text'); const categorySelect = document.getElementById('category-select'); const commentForm = document.getElementById('comment-form'); const titleText = document.getElementById('ticket-title-text'); const titleInput = document.getElementById('ticket-title-input'); const descText = document.getElementById('ticket-description-text'); const descInput = document.getElementById('ticket-description-input'); const commentAuthorInput = document.getElementById('comment-author'); const totalTimeDisplay = document.getElementById('total-time'); const timeForm = document.getElementById('time-booking-form'); let originalStatus = '', originalPriority = '', originalTitle = '', originalDesc = '', originalCategory = ''; // Load categories dynamically async function loadCategories() { try { const res = await fetch('/api/categories'); const categories = await res.json(); if (categorySelect) { categorySelect.innerHTML = categories.map(c => `` ).join(''); } } catch (err) { console.error('Failed to load categories:', err); } } async function loadPage() { await loadCategories(); await Promise.all([loadTicketDetails(), loadComments(), loadHistory()]); } async function loadTicketDetails() { const ticket = await fetchTicket(ticketId); if (!ticket) return alert('Ticket not found'); titleText.textContent = ticket.title; descText.textContent = ticket.description; priorityInput.value = ticket.priority; statusSelect.value = ticket.status; categorySelect.value = ticket.category || ''; document.getElementById('ticket-id-val').textContent = ticket.id; document.getElementById('ticket-created').textContent = formatDateTime(ticket.created_at); document.getElementById('ticket-updated').textContent = formatDateTime(ticket.updated_at); totalTimeDisplay.textContent = formatMinutes(typeof ticket.total_time === 'number' ? ticket.total_time : 0); statusSelect.className = 'form-control status-' + (ticket.status || '').toLowerCase().replace(/\s+/g, '-'); originalStatus = ticket.status; originalPriority = ticket.priority; originalTitle = ticket.title; originalDesc = ticket.description; originalCategory = ticket.category || ''; } async function updateTicket({ status, priority, title, description, category, actor = 'Admin' }) { try { const ticket = await fetchTicket(ticketId); const requester = ticket.requester || ''; const res = await fetch(`/api/tickets/${ticketId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status, priority, title, description, category, author: actor, requester }), }); if (!res.ok) throw new Error('Failed to update'); // Webhooks are handled server-side now — no need to send from here alert('Ticket updated successfully'); titleText.textContent = title; descText.textContent = description; await loadPage(); } catch (err) { console.error('Update failed:', err); alert('Error updating ticket'); } } document.getElementById('update-ticket-btn').addEventListener('click', async () => { const isEditingTitle = titleInput.style.display === 'block'; const isEditingDesc = descInput.style.display === 'block'; const newTitle = isEditingTitle ? titleInput.value.trim() : titleText.textContent; const newDesc = isEditingDesc ? descInput.value.trim() : descText.textContent; if (!confirm('Save changes?')) return; await updateTicket({ status: statusSelect.value, priority: priorityInput.value, title: newTitle, description: newDesc, category: categorySelect.value, }); titleInput.style.display = 'none'; titleText.style.display = 'block'; descInput.style.display = 'none'; descText.style.display = 'block'; }); document.getElementById('close-ticket-btn').addEventListener('click', async () => { if (!confirm('Close this ticket?')) return; await updateTicket({ status: 'Closed', priority: priorityInput.value, title: titleText.textContent, description: descText.textContent, category: categorySelect.value, }); }); titleText.addEventListener('dblclick', () => { titleInput.value = titleText.textContent; titleText.style.display = 'none'; titleInput.style.display = 'block'; titleInput.focus(); }); descText.addEventListener('dblclick', () => { descInput.value = descText.textContent; descText.style.display = 'none'; descInput.style.display = 'block'; descInput.focus(); }); // Restore saved author name const savedAuthor = localStorage.getItem('commentAuthor'); if (savedAuthor) commentAuthorInput.value = savedAuthor; async function loadComments() { const comments = await fetchComments(ticketId); const container = document.getElementById('comments-container'); container.innerHTML = comments.map(comment => { const role = comment.role || 'user'; const isAdmin = role === 'admin'; const avatarUrl = isAdmin ? '/assets/admin.jpg' : '/assets/user.jpg'; return `