Files
presensi/app/Views/dashboard/devices.php
2026-03-05 14:37:36 +07:00

115 lines
5.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="space-y-6">
<h1 class="text-xl font-semibold">Device Absen</h1>
<p class="text-gray-600 dark:text-gray-400 text-sm">Daftar perangkat absensi dan status online. Koordinat presensi diatur terpusat di <a href="<?= base_url('dashboard/presence-settings') ?>" class="text-primary hover:underline">Pengaturan Presensi</a>.</p>
<div id="devices-loading" class="rounded-2xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-12 text-center text-gray-500 dark:text-gray-400">
Loading…
</div>
<div id="devices-error" class="hidden rounded-2xl border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-900/20 p-6 text-red-700 dark:text-red-300"></div>
<div id="devices-content" class="hidden rounded-2xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 shadow-sm overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-left">
<thead class="bg-gray-50 dark:bg-gray-700/50 text-sm text-gray-600 dark:text-gray-400">
<tr>
<th class="px-6 py-3 font-medium">Device Code</th>
<th class="px-6 py-3 font-medium">Device Name</th>
<th class="px-6 py-3 font-medium">Active</th>
<th class="px-6 py-3 font-medium">Last Seen</th>
<th class="px-6 py-3 font-medium">Status</th>
<th class="px-6 py-3 font-medium">Zona</th>
</tr>
</thead>
<tbody id="devices-tbody" class="divide-y divide-gray-200 dark:divide-gray-700"></tbody>
</table>
</div>
</div>
</div>
<script>
(function() {
var baseUrl = '<?= base_url() ?>'.replace(/\/$/, '');
var apiUrl = baseUrl + '/api/dashboard/devices';
var loading = document.getElementById('devices-loading');
var errorEl = document.getElementById('devices-error');
var content = document.getElementById('devices-content');
var tbody = document.getElementById('devices-tbody');
var currentDevices = [];
function showLoading() {
loading.classList.remove('hidden');
errorEl.classList.add('hidden');
content.classList.add('hidden');
}
function showError(msg) {
loading.classList.add('hidden');
content.classList.add('hidden');
errorEl.classList.remove('hidden');
errorEl.textContent = msg;
}
function showContent() {
loading.classList.add('hidden');
errorEl.classList.add('hidden');
content.classList.remove('hidden');
}
function escapeHtml(str) {
if (str == null) return '';
var div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}
function loadDevices() {
showLoading();
fetch(apiUrl, { method: 'GET', credentials: 'same-origin', headers: { 'X-Requested-With': 'XMLHttpRequest' } })
.then(function(res) { return res.json().then(function(j) { return { ok: res.ok, data: j }; }); })
.then(function(r) {
if (!r.ok) {
showError(r.data && r.data.message ? r.data.message : 'Failed to load devices');
return;
}
var list = r.data && r.data.data ? r.data.data : r.data;
if (!Array.isArray(list)) {
showError('Invalid response');
return;
}
currentDevices = list;
tbody.innerHTML = '';
list.forEach(function(row) {
var tr = document.createElement('tr');
tr.className = 'hover:bg-gray-50 dark:hover:bg-gray-700/30';
var activeText = row.is_active ? 'Yes' : 'No';
var activeClass = row.is_active ? 'text-green-600 dark:text-green-400' : 'text-gray-500 dark:text-gray-400';
var lastSeen = row.last_seen_at ? escapeHtml(row.last_seen_at) : '';
var status = (row.online_status || 'offline').toLowerCase();
var statusClass = status === 'online'
? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400'
: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-400';
var statusLabel = status === 'online' ? 'Online' : 'Offline';
var zoneText = 'Terpusat (zona sekolah)';
tr.innerHTML =
'<td class="px-6 py-3 font-medium">' + escapeHtml(row.device_code) + '</td>' +
'<td class="px-6 py-3 text-gray-600 dark:text-gray-400">' + escapeHtml(row.device_name) + '</td>' +
'<td class="px-6 py-3 ' + activeClass + '">' + escapeHtml(activeText) + '</td>' +
'<td class="px-6 py-3 text-gray-600 dark:text-gray-400">' + lastSeen + '</td>' +
'<td class="px-6 py-3"><span class="inline-flex px-2.5 py-0.5 rounded-full text-xs font-medium ' + statusClass + '">' + escapeHtml(statusLabel) + '</span></td>' +
'<td class="px-6 py-3 text-gray-600 dark:text-gray-400 text-xs">' + escapeHtml(zoneText) + '</td>';
tbody.appendChild(tr);
});
showContent();
})
.catch(function() {
showError('Network error');
});
}
// Init
loadDevices();
})();
</script>