abdullahalioo's picture
Upload 9 files
b8dbc9f verified
// Main JavaScript functionality for Ticket Collection System
document.addEventListener('DOMContentLoaded', function() {
initializeAdmin();
});
// Initialize admin dashboard functionality
function initializeAdmin() {
if (window.location.pathname === '/admin') {
initializeTableFeatures();
initializeSearch();
initializeFilters();
updateLastUpdated();
}
}
// Initialize table sorting and filtering features
function initializeTableFeatures() {
const table = document.getElementById('ticketsTable');
if (!table) return;
// Store original table data for filtering
window.originalTableData = Array.from(table.querySelectorAll('tbody tr'));
updateShowingCount();
}
// Table sorting functionality
let sortDirection = {};
function sortTable(columnIndex) {
const table = document.getElementById('ticketsTable');
const tbody = table.querySelector('tbody');
const rows = Array.from(tbody.querySelectorAll('tr'));
// Determine sort direction
const currentDir = sortDirection[columnIndex] || 'asc';
const newDir = currentDir === 'asc' ? 'desc' : 'asc';
sortDirection[columnIndex] = newDir;
// Update sort icons
updateSortIcons(columnIndex, newDir);
// Sort rows
rows.sort((a, b) => {
const aText = a.cells[columnIndex].textContent.trim();
const bText = b.cells[columnIndex].textContent.trim();
// Handle numeric columns
if (columnIndex === 3) { // Tickets column
const aNum = parseInt(aText) || 0;
const bNum = parseInt(bText) || 0;
return newDir === 'asc' ? aNum - bNum : bNum - aNum;
}
// Handle date columns
if (columnIndex === 7) { // Timestamp column
const aDate = new Date(aText);
const bDate = new Date(bText);
return newDir === 'asc' ? aDate - bDate : bDate - aDate;
}
// Handle text columns
const comparison = aText.localeCompare(bText);
return newDir === 'asc' ? comparison : -comparison;
});
// Rebuild table
rows.forEach(row => tbody.appendChild(row));
updateShowingCount();
}
// Update sort direction icons
function updateSortIcons(activeColumn, direction) {
const headers = document.querySelectorAll('#ticketsTable thead th');
headers.forEach((header, index) => {
const icon = header.querySelector('i.fa-sort, i.fa-sort-up, i.fa-sort-down');
if (icon) {
if (index === activeColumn) {
icon.className = direction === 'asc' ? 'fas fa-sort-up' : 'fas fa-sort-down';
} else {
icon.className = 'fas fa-sort';
}
}
});
}
// Search functionality
function initializeSearch() {
const searchInput = document.getElementById('searchInput');
if (!searchInput) return;
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
filterTable();
});
}
// Filter functionality
function initializeFilters() {
const countryFilter = document.getElementById('countryFilter');
if (!countryFilter) return;
countryFilter.addEventListener('change', function() {
filterTable();
});
}
// Combined filter and search function
function filterTable() {
if (!window.originalTableData) return;
const searchTerm = document.getElementById('searchInput')?.value.toLowerCase() || '';
const countryFilter = document.getElementById('countryFilter')?.value || '';
const tbody = document.querySelector('#ticketsTable tbody');
// Clear current table
tbody.innerHTML = '';
let visibleCount = 0;
window.originalTableData.forEach(row => {
const rowText = row.textContent.toLowerCase();
const countryCell = row.cells[5].textContent.trim();
const matchesSearch = searchTerm === '' || rowText.includes(searchTerm);
const matchesCountry = countryFilter === '' || countryCell === countryFilter;
if (matchesSearch && matchesCountry) {
tbody.appendChild(row.cloneNode(true));
visibleCount++;
}
});
// Update showing count
document.getElementById('showingCount').textContent = visibleCount;
// Show empty state if no results
if (visibleCount === 0) {
showEmptySearchResults();
}
}
// Show empty search results
function showEmptySearchResults() {
const tbody = document.querySelector('#ticketsTable tbody');
const emptyRow = document.createElement('tr');
emptyRow.innerHTML = `
<td colspan="9" class="text-center py-4">
<i class="fas fa-search fa-2x text-muted mb-2"></i>
<p class="text-muted mb-0">No tickets match your search criteria</p>
</td>
`;
tbody.appendChild(emptyRow);
}
// Update showing count
function updateShowingCount() {
const tbody = document.querySelector('#ticketsTable tbody');
if (!tbody) return;
const visibleRows = tbody.querySelectorAll('tr').length;
const showingElement = document.getElementById('showingCount');
if (showingElement) {
showingElement.textContent = visibleRows;
}
}
// Refresh data function
function refreshData() {
const refreshBtn = document.querySelector('button[onclick="refreshData()"]');
if (refreshBtn) {
refreshBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Refreshing...';
refreshBtn.disabled = true;
}
// Simulate refresh delay
setTimeout(() => {
location.reload();
}, 500);
}
// Export visible data function
function exportVisible() {
const table = document.getElementById('ticketsTable');
if (!table) return;
const visibleRows = Array.from(table.querySelectorAll('tbody tr'));
if (visibleRows.length === 0) {
alert('No data to export');
return;
}
// Create CSV content
let csvContent = 'Email,Phone,Name,Tickets,Ticket Number,Country,Region,Timestamp\n';
visibleRows.forEach(row => {
const cells = Array.from(row.cells).slice(0, 8); // Exclude actions column
const rowData = cells.map(cell => {
let text = cell.textContent.trim();
// Clean up badge text
if (cell.querySelector('.badge')) {
text = cell.querySelector('.badge').textContent.trim();
}
// Clean up code text
if (cell.querySelector('code')) {
text = cell.querySelector('code').textContent.trim();
}
// Escape quotes and commas
if (text.includes(',') || text.includes('"')) {
text = '"' + text.replace(/"/g, '""') + '"';
}
return text;
});
csvContent += rowData.join(',') + '\n';
});
// Download CSV
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
if (link.download !== undefined) {
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', `ticket_data_filtered_${new Date().toISOString().split('T')[0]}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
// Update last updated timestamp
function updateLastUpdated() {
const element = document.getElementById('lastUpdated');
if (element) {
const now = new Date();
element.textContent = now.toISOString().slice(0, 19).replace('T', ' ');
}
}
// Utility function to show notifications
function showNotification(message, type = 'info') {
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(alertDiv);
// Auto-remove after 5 seconds
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.parentNode.removeChild(alertDiv);
}
}, 5000);
}
// Handle form submissions with loading states
document.addEventListener('submit', function(e) {
const form = e.target;
if (form.tagName === 'FORM') {
const submitBtn = form.querySelector('button[type="submit"]');
if (submitBtn) {
submitBtn.disabled = true;
const originalHtml = submitBtn.innerHTML;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Processing...';
// Re-enable after 3 seconds (fallback)
setTimeout(() => {
submitBtn.disabled = false;
submitBtn.innerHTML = originalHtml;
}, 3000);
}
}
});
// Add keyboard shortcuts
document.addEventListener('keydown', function(e) {
// Ctrl+R or F5 for refresh
if ((e.ctrlKey && e.key === 'r') || e.key === 'F5') {
if (window.location.pathname === '/admin') {
e.preventDefault();
refreshData();
}
}
// Ctrl+F for search focus
if (e.ctrlKey && e.key === 'f') {
const searchInput = document.getElementById('searchInput');
if (searchInput) {
e.preventDefault();
searchInput.focus();
searchInput.select();
}
}
// Escape to clear search
if (e.key === 'Escape') {
const searchInput = document.getElementById('searchInput');
if (searchInput && searchInput.value) {
searchInput.value = '';
filterTable();
}
}
});
// Add smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});