116 lines
4.1 KiB
PHP
116 lines
4.1 KiB
PHP
<?php
|
|
require 'auth.php';
|
|
requireLogin();
|
|
?>
|
|
|
|
<?php include 'header.php'; ?>
|
|
|
|
<!-- DataTables CSS -->
|
|
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
|
|
|
|
<div class="container mt-4">
|
|
<h2><?= htmlspecialchars($translations['signal_log_live'] ?? 'Signal Log') ?></h2>
|
|
|
|
<!-- Auto-refresh toggle button -->
|
|
<button id="toggleRefreshBtn" class="btn btn-sm btn-primary mb-3">⏸️ Auto-Refresh: OFF</button>
|
|
|
|
<table id="signal-log-table" class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th><?= htmlspecialchars($translations['timestamp'] ?? 'Timestamp') ?></th>
|
|
<th><?= htmlspecialchars($translations['account'] ?? 'Account') ?></th>
|
|
<th><?= htmlspecialchars($translations['event'] ?? 'Event') ?></th>
|
|
<th><?= htmlspecialchars($translations['zone'] ?? 'Zone') ?></th>
|
|
<th><?= htmlspecialchars($translations['text'] ?? 'Text') ?></th>
|
|
<th><?= htmlspecialchars($translations['image'] ?? 'Image') ?></th>
|
|
<th><?= htmlspecialchars($translations['source_ip'] ?? 'Source IP') ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="signal-log-body">
|
|
<!-- Filled dynamically -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Image Preview Modal -->
|
|
<div class="modal fade" id="imageModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title"><?= htmlspecialchars($translations['image_preview'] ?? 'Image Preview') ?></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="<?= htmlspecialchars($translations['close'] ?? 'Close') ?>"></button>
|
|
</div>
|
|
<div class="modal-body text-center">
|
|
<img src="" alt="<?= htmlspecialchars($translations['image'] ?? 'Image') ?>" class="img-fluid" id="modalImage" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- DataTables JS -->
|
|
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
|
|
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
|
|
|
|
<script>
|
|
let dataTable = null;
|
|
let autoRefresh = false;
|
|
let refreshInterval = null;
|
|
|
|
function fetchSignals() {
|
|
fetch('get_signals.php?_ts=' + new Date().getTime())
|
|
.then(response => response.text())
|
|
.then(data => {
|
|
const tbody = document.getElementById('signal-log-body');
|
|
|
|
// Destroy existing DataTable instance before updating HTML
|
|
if (dataTable) {
|
|
dataTable.destroy();
|
|
}
|
|
|
|
tbody.innerHTML = data;
|
|
|
|
// Re-initialize DataTable
|
|
dataTable = new DataTable('#signal-log-table', {
|
|
paging: true,
|
|
searching: true,
|
|
ordering: true,
|
|
order: [[0, 'desc']],
|
|
lengthMenu: [ [50, 100, 200], [50, 100, 200] ]
|
|
});
|
|
})
|
|
.catch(err => console.error('Fetch error:', err));
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
fetchSignals();
|
|
|
|
const toggleBtn = document.getElementById('toggleRefreshBtn');
|
|
|
|
toggleBtn.addEventListener('click', () => {
|
|
autoRefresh = !autoRefresh;
|
|
toggleBtn.innerHTML = autoRefresh ? '🔄 Auto-Refresh: ON' : '⏸️ Auto-Refresh: OFF';
|
|
|
|
if (autoRefresh) {
|
|
fetchSignals();
|
|
refreshInterval = setInterval(fetchSignals, 2000);
|
|
} else {
|
|
clearInterval(refreshInterval);
|
|
refreshInterval = null;
|
|
}
|
|
});
|
|
|
|
// Delegate image modal opening for dynamically loaded buttons
|
|
document.body.addEventListener('click', e => {
|
|
if (e.target.classList.contains('openImageModalBtn')) {
|
|
const imgSrc = e.target.getAttribute('data-image');
|
|
document.getElementById('modalImage').src = imgSrc;
|
|
|
|
const myModal = new bootstrap.Modal(document.getElementById('imageModal'));
|
|
myModal.show();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php include 'footer.php'; ?>
|