date drop added

This commit is contained in:
odzugkoev
2026-03-10 20:36:25 -04:00
parent 50f4501cdd
commit 1b40187ade
6 changed files with 305 additions and 24 deletions

View File

@@ -1,6 +1,9 @@
// Dashboard functionality
let currentFilter = 'all';
let currentDateFilter = 'today';
let customDateStart = '';
let customDateEnd = '';
let currentOrderIdForCancel = null;
let pendingStatusChange = {
orderId: null,
@@ -118,6 +121,7 @@ function refreshAbandonedCallCount() {
// Initialize dashboard
document.addEventListener('DOMContentLoaded', function() {
setupFilterButtons();
setupDateFilter();
audioNotification.init();
refreshOrders();
refreshAbandonedCallCount();
@@ -136,19 +140,135 @@ function setupFilterButtons() {
filterButtons.forEach(button => {
button.addEventListener('click', function() {
// Remove active class from all buttons
filterButtons.forEach(btn => btn.classList.remove('active'));
// Add active class to clicked button
this.classList.add('active');
// Update filter and refresh
currentFilter = this.dataset.filter;
refreshOrders();
});
});
}
function setupDateFilter() {
const select = document.getElementById('dateFilterSelect');
const customPanel = document.getElementById('dateFilterCustom');
const applyBtn = document.getElementById('dateFilterApply');
const fromInput = document.getElementById('dateFilterFrom');
const toInput = document.getElementById('dateFilterTo');
if (!select || !customPanel || !applyBtn || !fromInput || !toInput) return;
// Set default dates on the pickers to today
const todayStr = formatDateForInput(new Date());
fromInput.value = todayStr;
toInput.value = todayStr;
select.addEventListener('change', function() {
const val = this.value;
currentDateFilter = val;
if (val === 'custom') {
customPanel.style.display = 'flex';
// Entering custom mode should immediately reflect the currently selected dates
// (defaults to today on first use). Further changes require pressing Apply.
if (fromInput.value && toInput.value) {
customDateStart = fromInput.value;
customDateEnd = toInput.value;
}
refreshOrders();
} else {
customPanel.style.display = 'none';
refreshOrders();
}
updateStatsTotalLabel();
});
applyBtn.addEventListener('click', function() {
if (!fromInput.value || !toInput.value) {
showToast('Please select both start and end dates', 'error');
return;
}
if (fromInput.value > toInput.value) {
showToast('Start date must be before end date', 'error');
return;
}
customDateStart = fromInput.value;
customDateEnd = toInput.value;
refreshOrders();
updateStatsTotalLabel();
});
// Allow pressing Enter in date inputs to apply
fromInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') applyBtn.click(); });
toInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') applyBtn.click(); });
}
function getDateRangeParams() {
const now = new Date();
switch (currentDateFilter) {
case 'today': {
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
return { startDate: Math.floor(start.getTime() / 1000), endDate: Math.floor(end.getTime() / 1000) };
}
case 'yesterday': {
const yd = new Date(now);
yd.setDate(yd.getDate() - 1);
const start = new Date(yd.getFullYear(), yd.getMonth(), yd.getDate(), 0, 0, 0);
const end = new Date(yd.getFullYear(), yd.getMonth(), yd.getDate(), 23, 59, 59, 999);
return { startDate: Math.floor(start.getTime() / 1000), endDate: Math.floor(end.getTime() / 1000) };
}
case 'last7': {
const start = new Date(now);
start.setDate(start.getDate() - 6);
start.setHours(0, 0, 0, 0);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
return { startDate: Math.floor(start.getTime() / 1000), endDate: Math.floor(end.getTime() / 1000) };
}
case 'last30': {
const start = new Date(now);
start.setDate(start.getDate() - 29);
start.setHours(0, 0, 0, 0);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999);
return { startDate: Math.floor(start.getTime() / 1000), endDate: Math.floor(end.getTime() / 1000) };
}
case 'all':
// Use a minimal unix start date to represent "all time" without relying on server defaults.
return { startDate: 1 };
case 'custom': {
if (!customDateStart || !customDateEnd) return {};
const start = new Date(customDateStart + 'T00:00:00');
const end = new Date(customDateEnd + 'T23:59:59');
return { startDate: Math.floor(start.getTime() / 1000), endDate: Math.floor(end.getTime() / 1000) };
}
default:
return {};
}
}
function formatDateForInput(date) {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, '0');
const d = String(date.getDate()).padStart(2, '0');
return y + '-' + m + '-' + d;
}
function updateStatsTotalLabel() {
const label = document.getElementById('stat-total-label');
if (!label) return;
const labels = {
today: 'Total Today',
yesterday: 'Total Yesterday',
last7: 'Total (7 Days)',
last30: 'Total (30 Days)',
all: 'Total (All Time)',
custom: 'Total (Custom)'
};
label.textContent = labels[currentDateFilter] || 'Total';
}
function refreshOrders() {
const syncButton = document.getElementById('syncButton');
const syncText = syncButton ? syncButton.querySelector('.sync-text') : null;
@@ -161,8 +281,15 @@ function refreshOrders() {
}
}
const statusParam = currentFilter === 'all' ? '' : currentFilter;
const url = '/api/orders' + (statusParam ? '?status=' + statusParam : '');
const params = new URLSearchParams();
if (currentFilter !== 'all') {
params.set('status', currentFilter);
}
const dateRange = getDateRangeParams();
if (dateRange.startDate) params.set('startDate', dateRange.startDate);
if (dateRange.endDate) params.set('endDate', dateRange.endDate);
const qs = params.toString();
const url = '/api/orders' + (qs ? '?' + qs : '');
fetch(url)
.then(response => response.json())