All Tickets
+| ID | +Title | +Requester | +Category | +Status | +Priority | +Created | +Total Time | +Actions | +
|---|
diff --git a/public/admin-script.js b/public/admin-script.js new file mode 100644 index 0000000..0f6b212 --- /dev/null +++ b/public/admin-script.js @@ -0,0 +1,150 @@ +document.addEventListener('DOMContentLoaded', () => { + const ticketsBody = document.getElementById('tickets-body'); + const closedTicketsBody = document.getElementById('closed-tickets-body'); + const searchInput = document.getElementById('search-tickets'); + const statusFilter = document.getElementById('status-filter'); + const priorityFilter = document.getElementById('priority-filter'); + const categoryFilter = document.getElementById('category-filter'); + const statTotal = document.getElementById('total-tickets'); + const statOpen = document.getElementById('open-tickets'); + const statInProgress = document.getElementById('in-progress-tickets'); + const statClosed = document.getElementById('closed-tickets'); + const statTotalTime = document.getElementById('time-tickets'); // Neu: Gesamtzeit Anzeige + + searchInput.addEventListener('input', refreshTickets); + statusFilter.addEventListener('change', refreshTickets); + priorityFilter.addEventListener('change', refreshTickets); + categoryFilter.addEventListener('change', refreshTickets); + + // Helper: Status/Priority zu "Title-Case-With-Dash" + function toTitleCaseWithDash(str) { + return str + .split(' ') + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join('-'); + } + + async function fetchTickets() { + try { + const res = await fetch('/api/tickets'); + return await res.json(); + } catch (err) { + console.error('Error fetching tickets:', err); + return []; + } + } + + async function deleteTicket(id) { + try { + const res = await fetch(`/api/tickets/${id}`, { + method: 'DELETE', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ actor: 'Admin' }) + }); + return await res.json(); + } catch (err) { + console.error('Error deleting ticket:', err); + } + } + + async function refreshTickets() { + const tickets = await fetchTickets(); + renderTickets(tickets); + updateStats(tickets); + } + + function renderTickets(tickets) { + const status = statusFilter.value; + const priority = priorityFilter.value; + const category = categoryFilter.value; + const searchTerm = searchInput.value.toLowerCase(); + + const filtered = tickets.filter(t => + (status === 'all' || t.status === status) && + (priority === 'all' || t.priority === priority) && + (category === 'all' || t.category === category) && + (t.title.toLowerCase().includes(searchTerm) || + t.description.toLowerCase().includes(searchTerm) || + t.requester.toLowerCase().includes(searchTerm)) + ).sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); + + const openRows = []; + const closedRows = []; + + filtered.forEach(ticket => { + const shortTitle = ticket.title.length > 50 ? ticket.title.slice(0, 50) + '...' : ticket.title; + + // Wandle Status und Priority korrekt in Klassen um + const statusClass = toTitleCaseWithDash(ticket.status || 'Unknown'); + const priorityClass = toTitleCaseWithDash(ticket.priority || 'None'); + + const rowHTML = ` +
| ID | +Title | +Requester | +Category | +Status | +Priority | +Created | +Total Time | +Actions | +
|---|
| ID | +Title | +Requester | +Category | +Status | +Priority | +Created | +Total Time | +Actions | +
|---|