79 lines
3.0 KiB
JavaScript
79 lines
3.0 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
const ticketForm = document.getElementById('ticketForm');
|
|
const ticketList = document.getElementById('ticketList');
|
|
|
|
const fetchTickets = async () => {
|
|
try {
|
|
const response = await fetch('api/tickets.php');
|
|
const tickets = await response.json();
|
|
renderTickets(tickets);
|
|
} catch (error) {
|
|
console.error('Error fetching tickets:', error);
|
|
}
|
|
};
|
|
|
|
const renderTickets = (tickets) => {
|
|
ticketList.innerHTML = tickets.map(ticket => `
|
|
<tr>
|
|
<td><span class="text-muted">#${ticket.id}</span></td>
|
|
<td class="fw-semibold">${escapeHtml(ticket.title)}</td>
|
|
<td><span class="badge priority-${ticket.priority}">${ticket.priority}</span></td>
|
|
<td><span class="fw-medium status-${ticket.status.replace(' ', '-')}">${ticket.status}</span></td>
|
|
<td class="text-muted">${new Date(ticket.created_at).toLocaleDateString()}</td>
|
|
<td class="text-end">
|
|
<button class="btn btn-sm btn-link text-decoration-none p-0" onclick="viewDetails(${ticket.id})">View</button>
|
|
</td>
|
|
</tr>
|
|
`).join('');
|
|
};
|
|
|
|
const escapeHtml = (text) => {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
};
|
|
|
|
ticketForm.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const formData = new FormData(ticketForm);
|
|
const data = Object.fromEntries(formData.entries());
|
|
|
|
try {
|
|
const response = await fetch('api/tickets.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type: application/json' },
|
|
body: JSON.stringify(data)
|
|
});
|
|
|
|
if (response.ok) {
|
|
ticketForm.reset();
|
|
const modal = bootstrap.Modal.getInstance(document.getElementById('createTicketModal'));
|
|
modal.hide();
|
|
fetchTickets();
|
|
showNotification('Ticket created successfully');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error creating ticket:', error);
|
|
}
|
|
});
|
|
|
|
const showNotification = (message) => {
|
|
// Simple toast or alert
|
|
const toast = document.createElement('div');
|
|
toast.className = 'position-fixed bottom-0 end-0 p-3';
|
|
toast.style.zIndex = '1100';
|
|
toast.innerHTML = `
|
|
<div class="toast show align-items-center text-white bg-dark border-0" role="alert">
|
|
<div class="d-flex">
|
|
<div class="toast-body">${message}</div>
|
|
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
document.body.appendChild(toast);
|
|
setTimeout(() => toast.remove(), 3000);
|
|
};
|
|
|
|
fetchTickets();
|
|
});
|