export async function fetchTicket(id) { const res = await fetch(`/api/tickets/${id}`); if (!res.ok) return null; return res.json(); } export async function fetchComments(id) { const res = await fetch(`/api/tickets/${id}/comments`); if (!res.ok) return []; return res.json(); } export async function fetchHistory(id) { const res = await fetch(`/api/tickets/${id}/history`); if (!res.ok) return []; return res.json(); } export async function logTime(id, timeLog) { const res = await fetch(`/api/tickets/${id}/time`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(timeLog), }); return res.json(); } export async function updateTicket(id, data) { const res = await fetch(`/api/tickets/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); return res.json(); } export async function createComment(id, comment) { const res = await fetch(`/api/tickets/${id}/comments`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(comment), }); return res.json(); } // XSS protection — escape HTML entities before inserting into innerHTML export function escapeHtml(str) { if (!str) return ''; const div = document.createElement('div'); div.textContent = str; return div.innerHTML; } // Convert URLs in text to clickable links (applied AFTER escaping) export function linkify(text) { const escaped = escapeHtml(text); const urlPattern = /(\bhttps?:\/\/[^\s<]+)/g; return escaped.replace(urlPattern, '$1'); } export function formatDateTime(date) { if (!date) return 'n/a'; const safeDate = date.includes('T') ? date : date.replace(' ', 'T'); const parsed = new Date(safeDate + 'Z'); if (isNaN(parsed.getTime())) return 'n/a'; return parsed.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', }); } export function formatMinutes(mins) { if (typeof mins !== 'number' || isNaN(mins)) return '0 Min.'; const hours = Math.floor(mins / 60); const minutes = mins % 60; if (hours > 0 && minutes > 0) return `${hours} Std. ${minutes} Min.`; if (hours > 0) return `${hours} Std.`; return `${minutes} Min.`; } export function getHistoryIcon(action) { const icons = { 'Ticket Created': 'plus-circle', 'Status Changed': 'sync-alt', 'Priority Changed': 'exclamation-circle', 'Comment Added': 'comment', 'Ticket Deleted': 'trash-alt', 'Category Changed': 'tags', 'Time Logged': 'clock', }; return icons[action] || 'history'; }