@@ -749,10 +767,10 @@
} else {
// Search within results
echo "
-
";
-
+
// Bulk action buttons
echo "
0 selecionados
";
-
+
echo "
@@ -780,7 +798,7 @@
";
-
+
foreach ($pedidosArray as $pedido) {
// Get room name
$stmt2 = $db->prepare("SELECT nome FROM salas WHERE id=?");
@@ -789,7 +807,7 @@
$salaResult = $stmt2->get_result()->fetch_assoc();
$salaextenso = $salaResult ? $salaResult['nome'] : 'N/A';
$stmt2->close();
-
+
// Get requisitor name
$stmt2 = $db->prepare("SELECT nome FROM cache WHERE id=?");
$stmt2->bind_param("s", $pedido['requisitor']);
@@ -797,7 +815,7 @@
$reqResult = $stmt2->get_result()->fetch_assoc();
$requisitorextenso = $reqResult ? $reqResult['nome'] : 'N/A';
$stmt2->close();
-
+
// Get time slot
$stmt2 = $db->prepare("SELECT horashumanos FROM tempos WHERE id=?");
$stmt2->bind_param("s", $pedido['tempo']);
@@ -805,36 +823,36 @@
$tempoResult = $stmt2->get_result()->fetch_assoc();
$horastempo = $tempoResult ? $tempoResult['horashumanos'] : 'N/A';
$stmt2->close();
-
+
$tempoEnc = urlencode($pedido['tempo']);
$dataEnc = urlencode($pedido['data']);
$salaEnc = urlencode($pedido['sala']);
-
+
// Format date nicely
$dataFormatted = date('d/m/Y', strtotime($pedido['data']));
$isToday = ($pedido['data'] == date('Y-m-d'));
$isPast = (strtotime($pedido['data']) < strtotime(date('Y-m-d')));
-
+
$rowClass = "";
if ($isPast && $pedido['aprovado'] == 0) {
$rowClass = "table-danger";
} elseif ($isToday) {
$rowClass = "table-warning";
}
-
- echo "";
-
+
// Checkbox column
echo "| ";
- echo "";
echo " | ";
-
+
// Date column
echo "";
echo "" . htmlspecialchars($dataFormatted, ENT_QUOTES, 'UTF-8') . "";
@@ -844,13 +862,13 @@
echo " Passado";
}
echo " | ";
-
+
// Time column
echo "" . htmlspecialchars($horastempo, ENT_QUOTES, 'UTF-8') . " | ";
-
+
// Room column
echo "" . htmlspecialchars($salaextenso, ENT_QUOTES, 'UTF-8') . " | ";
-
+
// Requisitor column
echo "";
echo "";
@@ -858,35 +876,35 @@
echo "";
echo htmlspecialchars($requisitorextenso, ENT_QUOTES, 'UTF-8');
echo " | ";
-
+
// Motivo column
$motivoTruncated = strlen($pedido['motivo']) > 50 ? substr($pedido['motivo'], 0, 50) . '...' : $pedido['motivo'];
echo "" . htmlspecialchars($motivoTruncated, ENT_QUOTES, 'UTF-8') . " | ";
-
+
// Actions column
echo "";
echo "";
-
- echo " ";
- echo " ";
- echo "
👁
";
echo " ";
echo " | ";
-
+
echo "
";
}
-
+
echo "
";
}
} else {
@@ -897,12 +915,12 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
$pendingArray[] = $p;
}
$totalPending = count($pendingArray);
-
+
echo "
";
echo "
Todos os Pedidos Pendentes
";
echo "{$totalPending} pedido(s)";
echo "";
-
+
if ($totalPending == 0) {
echo "
@@ -913,10 +931,10 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
";
} else {
echo "
-
";
-
+
// Bulk action buttons
echo "
0 selecionados
";
-
+
echo "
@@ -944,7 +962,7 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
";
-
+
foreach ($pendingArray as $pedido) {
$stmt2 = $db->prepare("SELECT nome FROM salas WHERE id=?");
$stmt2->bind_param("s", $pedido['sala']);
@@ -952,49 +970,49 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
$salaResult = $stmt2->get_result()->fetch_assoc();
$salaextenso = $salaResult ? $salaResult['nome'] : 'N/A';
$stmt2->close();
-
+
$stmt2 = $db->prepare("SELECT nome FROM cache WHERE id=?");
$stmt2->bind_param("s", $pedido['requisitor']);
$stmt2->execute();
$reqResult = $stmt2->get_result()->fetch_assoc();
$requisitorextenso = $reqResult ? $reqResult['nome'] : 'N/A';
$stmt2->close();
-
+
$stmt2 = $db->prepare("SELECT horashumanos FROM tempos WHERE id=?");
$stmt2->bind_param("s", $pedido['tempo']);
$stmt2->execute();
$tempoResult = $stmt2->get_result()->fetch_assoc();
$horastempo = $tempoResult ? $tempoResult['horashumanos'] : 'N/A';
$stmt2->close();
-
+
$tempoEnc = urlencode($pedido['tempo']);
$dataEnc = urlencode($pedido['data']);
$salaEnc = urlencode($pedido['sala']);
-
+
$dataFormatted = date('d/m/Y', strtotime($pedido['data']));
$isToday = ($pedido['data'] == date('Y-m-d'));
$isPast = (strtotime($pedido['data']) < strtotime(date('Y-m-d')));
-
+
$rowClass = "";
if ($isPast) {
$rowClass = "table-danger";
} elseif ($isToday) {
$rowClass = "table-warning";
}
-
- echo "";
-
+
// Checkbox column
echo "| ";
- echo "";
echo " | ";
-
+
echo "" . htmlspecialchars($dataFormatted, ENT_QUOTES, 'UTF-8') . "";
if ($isToday) {
echo " Hoje";
@@ -1002,33 +1020,33 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
echo " Passado";
}
echo " | ";
-
+
echo "" . htmlspecialchars($horastempo, ENT_QUOTES, 'UTF-8') . " | ";
echo "" . htmlspecialchars($salaextenso, ENT_QUOTES, 'UTF-8') . " | ";
-
+
echo "";
echo "";
echo strtoupper(substr($requisitorextenso, 0, 1));
echo "";
echo htmlspecialchars($requisitorextenso, ENT_QUOTES, 'UTF-8');
echo " | ";
-
+
$motivoTruncated = strlen($pedido['motivo']) > 50 ? substr($pedido['motivo'], 0, 50) . '...' : $pedido['motivo'];
echo "" . htmlspecialchars($motivoTruncated, ENT_QUOTES, 'UTF-8') . " | ";
-
+
echo "";
echo "";
- echo " ";
- echo " ";
- echo "
👁
";
@@ -1036,11 +1054,12 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
echo " | ";
echo "
";
}
-
+
echo "
";
}
}
?>
+
@@ -1064,29 +1083,23 @@ class='btn btn-outline-secondary btn-sm action-btn' title='Ver Detalhes' target=
function filterTable() {
const searchInput = document.getElementById('tableSearch');
if (!searchInput) return;
-
- const filter = searchInput.value.toLowerCase();
- const table = document.getElementById('pedidosTable');
- if (!table) return;
-
- const rows = table.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
-
- for (let i = 0; i < rows.length; i++) {
- const searchData = rows[i].getAttribute('data-search');
- if (searchData && searchData.includes(filter)) {
- rows[i].style.display = '';
- } else {
- rows[i].style.display = 'none';
- }
- }
+
+ pedidosState.search = searchInput.value.trim();
+ clearTimeout(pedidosState.searchTimer);
+ pedidosState.searchTimer = setTimeout(function() {
+ loadPedidos(true);
+ }, 250);
}
function confirmAction(action, tempo, data, sala, salaNome, dataFormatted, horasNome) {
+ salaNome = decodeURIComponent(salaNome);
+ dataFormatted = decodeURIComponent(dataFormatted);
+ horasNome = decodeURIComponent(horasNome);
const modal = new bootstrap.Modal(document.getElementById('confirmModal'));
const modalHeader = document.getElementById('modalHeader');
const modalBody = document.getElementById('modalBody');
const confirmBtn = document.getElementById('confirmBtn');
-
+
if (action === 'aprovar') {
modalHeader.className = 'modal-header bg-success text-white';
modalBody.innerHTML = `
@@ -1103,8 +1116,15 @@ function confirmAction(action, tempo, data, sala, salaNome, dataFormatted, horas
`;
confirmBtn.className = 'btn btn-success';
confirmBtn.textContent = 'Aprovar Reserva';
- confirmBtn.onclick = function() {
- window.location.href = `/admin/pedidos.php?subaction=aprovar&tempo=${tempo}&data=${data}&sala=${sala}`;
+ confirmBtn.onclick = async function() {
+ try {
+ const result = await submitPedidosAction('aprovar', [{ sala: decodeURIComponent(sala), tempo: decodeURIComponent(tempo), data: decodeURIComponent(data) }]);
+ bootstrap.Modal.getInstance(document.getElementById('confirmModal')).hide();
+ showPedidosActionResult(result);
+ loadPedidos(true);
+ } catch (error) {
+ window.location.href = `/admin/pedidos.php?subaction=aprovar&tempo=${tempo}&data=${data}&sala=${sala}`;
+ }
};
} else {
modalHeader.className = 'modal-header bg-danger text-white';
@@ -1124,11 +1144,18 @@ function confirmAction(action, tempo, data, sala, salaNome, dataFormatted, horas
`;
confirmBtn.className = 'btn btn-danger';
confirmBtn.textContent = 'Rejeitar Reserva';
- confirmBtn.onclick = function() {
- window.location.href = `/admin/pedidos.php?subaction=rejeitar&tempo=${tempo}&data=${data}&sala=${sala}`;
+ confirmBtn.onclick = async function() {
+ try {
+ const result = await submitPedidosAction('rejeitar', [{ sala: decodeURIComponent(sala), tempo: decodeURIComponent(tempo), data: decodeURIComponent(data) }]);
+ bootstrap.Modal.getInstance(document.getElementById('confirmModal')).hide();
+ showPedidosActionResult(result);
+ loadPedidos(true);
+ } catch (error) {
+ window.location.href = `/admin/pedidos.php?subaction=rejeitar&tempo=${tempo}&data=${data}&sala=${sala}`;
+ }
};
}
-
+
modal.show();
}
@@ -1136,7 +1163,7 @@ function filterUsersModal() {
const searchInput = document.getElementById('userSearchInput');
const filter = searchInput.value.toLowerCase();
const userItems = document.querySelectorAll('.user-item');
-
+
userItems.forEach(function(item) {
const name = item.getAttribute('data-user-name').toLowerCase();
const email = item.getAttribute('data-user-email').toLowerCase();
@@ -1151,57 +1178,284 @@ function filterUsersModal() {
function selectUser(element) {
const userId = element.getAttribute('data-user-id');
const userName = element.getAttribute('data-user-name');
-
+
document.getElementById('requisitor').value = userId;
document.getElementById('selectedUserDisplay').value = userName;
-
+
// Close the modal
const modal = bootstrap.Modal.getInstance(document.getElementById('userSelectModal'));
modal.hide();
-
- // Submit the form
- document.getElementById('filterForm').submit();
+
+ loadPedidos(true);
}
function clearUserSelection() {
document.getElementById('requisitor').value = '';
document.getElementById('selectedUserDisplay').value = '';
- document.getElementById('filterForm').submit();
+ loadPedidos(true);
+}
+
+
+const pedidosState = {
+ page: 1,
+ hasMore: true,
+ loading: false,
+ initialized: false,
+ search: '',
+ searchTimer: null,
+ requestController: null,
+ requestId: 0
+};
+
+function escapeHtml(value) {
+ return String(value ?? '').replace(/[&<>'"]/g, char => ({
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ "'": ''',
+ '"': '"'
+ }[char]));
+}
+
+function getFilterParams() {
+ const form = document.getElementById('filterForm');
+ const params = new URLSearchParams(new FormData(form));
+ params.delete('csrf_token');
+ if (pedidosState.search !== '') {
+ params.set('q', pedidosState.search);
+ }
+ return params;
+}
+
+function updatePedidosStats(stats) {
+ if (!stats) return;
+
+ document.getElementById('statPendentes').textContent = stats.pendentes;
+ document.getElementById('statAprovadas').textContent = stats.aprovadas;
+ document.getElementById('statHoje').textContent = stats.hoje;
+ document.getElementById('statPendentesBadge').classList.toggle('d-none', Number(stats.pendentes) <= 0);
+ document.getElementById('statHojeBadge').classList.toggle('d-none', Number(stats.hoje) <= 0);
+}
+
+function showPedidosActionResult(result) {
+ const errors = Array.isArray(result.emailErrors) ? result.emailErrors : [];
+ const warning = errors.length
+ ? `
Aviso: Alguns emails não foram enviados.
${errors.map(error => `- ${escapeHtml(error)}
`).join('')}
`
+ : '';
+
+ document.getElementById('pedidosAlerts').innerHTML = `
+
+ ${escapeHtml(result.message)} ${Number(result.processed || 0)} processada(s), ${Number(result.failed || 0)} falhada(s).
+ ${warning}
+
+
+ `;
+}
+
+function showPedidosSkeleton() {
+ const results = document.getElementById('pedidosResults');
+ if (!results) return;
+
+ let rows = '';
+ for (let i = 0; i < 5; i++) {
+ rows += `
|
`;
+ }
+
+ results.innerHTML = `
+
+
A carregar pedidos...
+ ...
+
+
+ `;
+}
+
+function renderPedidoRow(pedido) {
+ const rowClass = pedido.is_past ? 'table-danger' : (pedido.is_today ? 'table-warning' : '');
+ const sala = encodeURIComponent(pedido.sala);
+ const tempo = encodeURIComponent(pedido.tempo);
+ const data = encodeURIComponent(pedido.data);
+ const salaNome = encodeURIComponent(pedido.sala_nome);
+ const dataFormatada = encodeURIComponent(pedido.data_formatada);
+ const tempoNome = encodeURIComponent(pedido.tempo_nome);
+ const motivo = pedido.motivo || '';
+ const motivoCurto = motivo.length > 50 ? motivo.substring(0, 50) + '...' : motivo;
+ const inicial = (pedido.requisitor_nome || 'N').substring(0, 1).toUpperCase();
+ const search = `${pedido.sala_nome} ${pedido.requisitor_nome} ${motivo} ${pedido.data}`.toLowerCase();
+
+ return `
+
+ |
+ ${escapeHtml(pedido.data_formatada)} ${pedido.is_today ? 'Hoje' : ''} ${pedido.is_past ? 'Passado' : ''} |
+ ${escapeHtml(pedido.tempo_nome)} |
+ ${escapeHtml(pedido.sala_nome)} |
+ ${escapeHtml(inicial)}${escapeHtml(pedido.requisitor_nome)} |
+ ${escapeHtml(motivoCurto)} |
+ |
+
`;
+}
+
+function renderPedidos(data, append) {
+ const results = document.getElementById('pedidosResults');
+ if (!results) return;
+
+ const focusedSearch = document.activeElement && document.activeElement.id === 'tableSearch';
+ const searchSelectionStart = focusedSearch ? document.activeElement.selectionStart : null;
+ const searchSelectionEnd = focusedSearch ? document.activeElement.selectionEnd : null;
+ const showTools = data.total > 0 || pedidosState.search !== '';
+
+ if (!append) {
+ updatePedidosAsyncHeader(data);
+ results.innerHTML = `
+
+
+
+ `;
+ }
+
+ if (data.total === 0) {
+ const emptyDescription = pedidosState.search !== ''
+ ? 'Não existem pedidos pendentes que correspondam à pesquisa atual.'
+ : 'Não existem pedidos pendentes para os filtros selecionados.';
+ document.getElementById('pedidosEmpty').innerHTML = `
📭
Nenhum pedido encontrado
${emptyDescription}
`;
+ restoreSearchFocus(focusedSearch, searchSelectionStart, searchSelectionEnd);
+ updatePedidosStats(data.stats);
+ return;
+ }
+
+ const tbody = document.querySelector('#pedidosTable tbody');
+ tbody.insertAdjacentHTML('beforeend', data.pedidos.map(renderPedidoRow).join(''));
+ updateBulkButtons();
+ updatePedidosStats(data.stats);
+ if (window.twemoji) twemoji.parse(results, { folder: 'svg', ext: '.svg' });
+ restoreSearchFocus(focusedSearch, searchSelectionStart, searchSelectionEnd);
+}
+
+function updatePedidosAsyncHeader(data) {
+ const header = document.getElementById('pedidosAsyncHeader');
+ if (!header) return;
+
+ document.getElementById('pedidosAsyncTitle').textContent = data.title;
+ document.getElementById('pedidosAsyncCount').textContent = data.total + ' resultado(s)';
+}
+
+function restoreSearchFocus(shouldFocus, selectionStart, selectionEnd) {
+ if (!shouldFocus) return;
+
+ const searchInput = document.getElementById('tableSearch');
+ if (!searchInput) return;
+
+ searchInput.focus({ preventScroll: true });
+ if (selectionStart !== null && selectionEnd !== null) {
+ searchInput.setSelectionRange(selectionStart, selectionEnd);
+ }
+}
+
+async function loadPedidos(reset = false) {
+ if (!reset && (pedidosState.loading || !pedidosState.hasMore)) return;
+ if (reset && pedidosState.requestController) {
+ pedidosState.requestController.abort();
+ }
+
+ const requestId = ++pedidosState.requestId;
+ const controller = new AbortController();
+ pedidosState.requestController = controller;
+ pedidosState.loading = true;
+ if (reset) {
+ pedidosState.page = 1;
+ pedidosState.hasMore = true;
+ if (!document.activeElement || document.activeElement.id !== 'tableSearch') {
+ showPedidosSkeleton();
+ } else {
+ document.getElementById('pedidosLoadingMore')?.classList.remove('d-none');
+ }
+ } else {
+ document.getElementById('pedidosLoadingMore')?.classList.remove('d-none');
+ }
+
+ try {
+ const params = getFilterParams();
+ params.set('page', pedidosState.page);
+ const response = await fetch('/admin/api/pedidos_list.php?' + params.toString(), {
+ headers: { 'Accept': 'application/json' },
+ signal: controller.signal
+ });
+ const data = await response.json();
+ if (!response.ok) throw new Error(data.error || 'Erro ao carregar pedidos.');
+ if (requestId !== pedidosState.requestId) return;
+ renderPedidos(data, !reset);
+ pedidosState.hasMore = data.hasMore;
+ pedidosState.page += 1;
+ } catch (error) {
+ if (error.name === 'AbortError') return;
+ document.getElementById('pedidosAlerts').innerHTML = `
${escapeHtml(error.message)}
`;
+ } finally {
+ if (requestId !== pedidosState.requestId) return;
+ pedidosState.loading = false;
+ pedidosState.requestController = null;
+ document.getElementById('pedidosLoadingMore')?.classList.add('d-none');
+ setTimeout(maybeLoadMore, 0);
+ }
+}
+
+async function submitPedidosAction(action, reservations) {
+ const formData = new FormData();
+ formData.append('action', action === 'bulk_approve' ? 'aprovar' : action === 'bulk_reject' ? 'rejeitar' : action);
+ formData.append('reservations', JSON.stringify(reservations));
+ formData.append('csrf_token', document.getElementById('global-csrf-token')?.value || '');
+
+ const response = await fetch('/admin/api/pedidos_action.php', { method: 'POST', body: formData, headers: { 'Accept': 'application/json' } });
+ const data = await response.json();
+ if (!response.ok) throw new Error(data.error || 'Erro ao processar pedido.');
+ return data;
}
// Bulk action functions
function toggleSelectAll() {
const selectAllCheckbox = document.getElementById('selectAll');
const checkboxes = document.querySelectorAll('.row-checkbox');
-
+
checkboxes.forEach(checkbox => {
// Only toggle visible checkboxes
if (checkbox.closest('tr').style.display !== 'none') {
checkbox.checked = selectAllCheckbox.checked;
}
});
-
+
updateBulkButtons();
}
function updateBulkButtons() {
const checkboxes = document.querySelectorAll('.row-checkbox:checked');
const count = checkboxes.length;
-
+
const approveBtn = document.getElementById('bulkApproveBtn');
const rejectBtn = document.getElementById('bulkRejectBtn');
const countSpan = document.getElementById('selectedCount');
-
+
if (approveBtn && rejectBtn && countSpan) {
approveBtn.disabled = count === 0;
rejectBtn.disabled = count === 0;
countSpan.textContent = count + ' selecionado' + (count !== 1 ? 's' : '');
}
-
+
// Update select all checkbox state
const selectAllCheckbox = document.getElementById('selectAll');
if (selectAllCheckbox) {
- const visibleCheckboxes = Array.from(document.querySelectorAll('.row-checkbox')).filter(cb =>
+ const visibleCheckboxes = Array.from(document.querySelectorAll('.row-checkbox')).filter(cb =>
cb.closest('tr').style.display !== 'none'
);
const checkedVisibleCheckboxes = visibleCheckboxes.filter(cb => cb.checked);
@@ -1216,10 +1470,10 @@ function bulkApprove() {
alert('Por favor, selecione pelo menos uma reserva.');
return;
}
-
+
const reservations = [];
let summary = '
';
-
+
checkboxes.forEach(checkbox => {
const sala = checkbox.getAttribute('data-sala');
const tempo = checkbox.getAttribute('data-tempo');
@@ -1227,23 +1481,23 @@ function bulkApprove() {
const salaName = checkbox.getAttribute('data-salaname');
const dataFormatted = checkbox.getAttribute('data-dataformatted');
const horasName = checkbox.getAttribute('data-horasname');
-
+
reservations.push({
sala: decodeURIComponent(sala),
tempo: decodeURIComponent(tempo),
data: decodeURIComponent(data)
});
-
- summary += `- ${salaName} - ${dataFormatted} às ${horasName}
`;
+
+ summary += `- ${escapeHtml(salaName)} - ${escapeHtml(dataFormatted)} às ${escapeHtml(horasName)}
`;
});
-
+
summary += '
';
-
+
const modal = new bootstrap.Modal(document.getElementById('confirmModal'));
const modalHeader = document.getElementById('modalHeader');
const modalBody = document.getElementById('modalBody');
const confirmBtn = document.getElementById('confirmBtn');
-
+
modalHeader.className = 'modal-header bg-success text-white';
modalBody.innerHTML = `
@@ -1260,7 +1514,7 @@ function bulkApprove() {
confirmBtn.onclick = function() {
submitBulkAction('bulk_approve', reservations);
};
-
+
modal.show();
}
@@ -1270,10 +1524,10 @@ function bulkReject() {
alert('Por favor, selecione pelo menos uma reserva.');
return;
}
-
+
const reservations = [];
let summary = '
';
-
+
checkboxes.forEach(checkbox => {
const sala = checkbox.getAttribute('data-sala');
const tempo = checkbox.getAttribute('data-tempo');
@@ -1281,23 +1535,23 @@ function bulkReject() {
const salaName = checkbox.getAttribute('data-salaname');
const dataFormatted = checkbox.getAttribute('data-dataformatted');
const horasName = checkbox.getAttribute('data-horasname');
-
+
reservations.push({
sala: decodeURIComponent(sala),
tempo: decodeURIComponent(tempo),
data: decodeURIComponent(data)
});
-
- summary += `- ${salaName} - ${dataFormatted} às ${horasName}
`;
+
+ summary += `- ${escapeHtml(salaName)} - ${escapeHtml(dataFormatted)} às ${escapeHtml(horasName)}
`;
});
-
+
summary += '
';
-
+
const modal = new bootstrap.Modal(document.getElementById('confirmModal'));
const modalHeader = document.getElementById('modalHeader');
const modalBody = document.getElementById('modalBody');
const confirmBtn = document.getElementById('confirmBtn');
-
+
modalHeader.className = 'modal-header bg-danger text-white';
modalBody.innerHTML = `
@@ -1316,38 +1570,87 @@ function bulkReject() {
confirmBtn.onclick = function() {
submitBulkAction('bulk_reject', reservations);
};
-
+
modal.show();
}
-function submitBulkAction(action, reservations) {
- const form = document.createElement('form');
- form.method = 'POST';
- form.action = '/admin/pedidos.php?subaction=' + action;
-
- const input = document.createElement('input');
- input.type = 'hidden';
- input.name = 'reservations';
- input.value = JSON.stringify(reservations);
-
- form.appendChild(input);
-
- const tokenSource = document.getElementById('global-csrf-token');
- const csrfToken = tokenSource ? tokenSource.value : '';
- if (csrfToken) {
- const csrfInput = document.createElement('input');
- csrfInput.type = 'hidden';
- csrfInput.name = 'csrf_token';
- csrfInput.value = csrfToken;
- form.appendChild(csrfInput);
+async function submitBulkAction(action, reservations) {
+ try {
+ const result = await submitPedidosAction(action, reservations);
+ bootstrap.Modal.getInstance(document.getElementById('confirmModal')).hide();
+ showPedidosActionResult(result);
+ loadPedidos(true);
+ } catch (error) {
+ const form = document.createElement('form');
+ form.method = 'POST';
+ form.action = '/admin/pedidos.php?subaction=' + action;
+
+ const input = document.createElement('input');
+ input.type = 'hidden';
+ input.name = 'reservations';
+ input.value = JSON.stringify(reservations);
+ form.appendChild(input);
+
+ const tokenSource = document.getElementById('global-csrf-token');
+ const csrfToken = tokenSource ? tokenSource.value : '';
+ if (csrfToken) {
+ const csrfInput = document.createElement('input');
+ csrfInput.type = 'hidden';
+ csrfInput.name = 'csrf_token';
+ csrfInput.value = csrfToken;
+ form.appendChild(csrfInput);
+ }
+
+ document.body.appendChild(form);
+ form.submit();
}
+}
- document.body.appendChild(form);
- form.submit();
+function maybeLoadMore() {
+ if (pedidosState.loading || !pedidosState.hasMore) return;
+ if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight - 300) {
+ loadPedidos(false);
+ }
}
// Initialize Twemoji to parse all emojis on the page
document.addEventListener('DOMContentLoaded', function() {
+ const filterForm = document.getElementById('filterForm');
+ if (filterForm) {
+ filterForm.addEventListener('submit', function(event) {
+ event.preventDefault();
+ loadPedidos(true);
+ });
+ filterForm.querySelectorAll('select, input[type="hidden"]').forEach(function(input) {
+ input.addEventListener('change', function() { loadPedidos(true); });
+ });
+ }
+
+ document.getElementById('pedidosResults')?.addEventListener('click', function(event) {
+ const button = event.target.closest('.pedido-action');
+ if (!button) return;
+
+ confirmAction(
+ button.getAttribute('data-action'),
+ button.getAttribute('data-tempo'),
+ button.getAttribute('data-data'),
+ button.getAttribute('data-sala'),
+ button.getAttribute('data-salaname'),
+ button.getAttribute('data-dataformatted'),
+ button.getAttribute('data-horasname')
+ );
+ });
+
+ window.addEventListener('scroll', function() {
+ maybeLoadMore();
+ });
+
+ const hasServerAction = new URLSearchParams(window.location.search).has('subaction');
+ if (!hasServerAction) {
+ document.getElementById('pedidosAsyncHeader')?.classList.remove('d-none');
+ loadPedidos(true);
+ }
+
twemoji.parse(document.body, {
folder: 'svg',
ext: '.svg'