155 lines
11 KiB
PHP
155 lines
11 KiB
PHP
<?php require_once APP_ROOT . '/app/Views/layouts/header.php'; ?>
|
|
|
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6 gap-4">
|
|
<div>
|
|
<h2 class="text-2xl font-bold text-slate-800 dark:text-white">ประวัติการใช้งานระบบ (Logs)</h2>
|
|
<p class="text-slate-500 dark:text-slate-400 text-sm mt-1">ตรวจสอบประวัติการเข้าใช้งานและการทำรายการต่างๆ ของผู้ใช้</p>
|
|
</div>
|
|
<a href="<?= BASE_URL ?>/users" class="inline-flex items-center justify-center px-4 py-2.5 bg-slate-100 dark:bg-slate-700 hover:bg-slate-200 dark:hover:bg-slate-600 text-slate-700 dark:text-slate-200 text-sm font-medium rounded-xl transition-colors shadow-sm w-full md:w-auto">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-4 h-4 mr-2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3" /></svg>
|
|
กลับไปจัดการผู้ใช้
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="bg-white dark:bg-slate-800 p-4 rounded-xl shadow-sm border border-slate-100 dark:border-slate-700 mb-6">
|
|
<form action="<?= BASE_URL ?>/users/logs" method="GET" class="flex flex-col md:flex-row gap-4">
|
|
<div class="flex-1">
|
|
<label class="block text-xs font-medium text-slate-500 dark:text-slate-400 mb-1">ผู้ใช้งาน</label>
|
|
<select name="user_id" class="block w-full rounded-lg border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-900/50 text-slate-700 dark:text-slate-300 text-sm py-2 px-3 focus:ring-sky-500">
|
|
<option value="">ทั้งหมด</option>
|
|
<?php foreach($users as $u): ?>
|
|
<option value="<?= $u['id'] ?>" <?= ($filters['user_id'] ?? '') == $u['id'] ? 'selected' : '' ?>>
|
|
<?= htmlspecialchars($u['first_name'] . ' ' . $u['last_name'] . ' (' . $u['username'] . ')') ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="flex-1">
|
|
<label class="block text-xs font-medium text-slate-500 dark:text-slate-400 mb-1">ประเภทรายการ</label>
|
|
<select name="action" class="block w-full rounded-lg border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-900/50 text-slate-700 dark:text-slate-300 text-sm py-2 px-3 focus:ring-sky-500">
|
|
<option value="">ทั้งหมด</option>
|
|
<option value="LOGIN" <?= ($filters['action'] ?? '') == 'LOGIN' ? 'selected' : '' ?>>Login</option>
|
|
<option value="CREATE_USER" <?= ($filters['action'] ?? '') == 'CREATE_USER' ? 'selected' : '' ?>>เพิ่มผู้ใช้งาน</option>
|
|
<option value="UPDATE_USER" <?= ($filters['action'] ?? '') == 'UPDATE_USER' ? 'selected' : '' ?>>แก้ไขข้อมูลผู้ใช้</option>
|
|
<option value="TOGGLE_STATUS" <?= ($filters['action'] ?? '') == 'TOGGLE_STATUS' ? 'selected' : '' ?>>เปลี่ยนสถานะสิทธิ์</option>
|
|
<option value="UPDATE_SETTINGS" <?= ($filters['action'] ?? '') == 'UPDATE_SETTINGS' ? 'selected' : '' ?>>อัปเดตการตั้งค่าระบบ</option>
|
|
</select>
|
|
</div>
|
|
<div class="flex-1">
|
|
<label class="block text-xs font-medium text-slate-500 dark:text-slate-400 mb-1">วันที่เริ่มต้น</label>
|
|
<input type="date" name="date_start" value="<?= htmlspecialchars($filters['date_start'] ?? '') ?>" class="block w-full rounded-lg border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-900/50 text-slate-700 dark:text-slate-300 text-sm py-2 px-3 focus:ring-sky-500">
|
|
</div>
|
|
<div class="flex-1">
|
|
<label class="block text-xs font-medium text-slate-500 dark:text-slate-400 mb-1">วันที่สิ้นสุด</label>
|
|
<input type="date" name="date_end" value="<?= htmlspecialchars($filters['date_end'] ?? '') ?>" class="block w-full rounded-lg border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-900/50 text-slate-700 dark:text-slate-300 text-sm py-2 px-3 focus:ring-sky-500">
|
|
</div>
|
|
<div class="flex items-end">
|
|
<button type="submit" class="w-full md:w-auto px-4 py-2 bg-sky-500 hover:bg-sky-600 text-white text-sm font-medium rounded-lg transition-colors shadow-sm">
|
|
ค้นหา
|
|
</button>
|
|
<a href="<?= BASE_URL ?>/users/logs" class="ml-2 px-4 py-2 bg-slate-200 dark:bg-slate-700 hover:bg-slate-300 dark:hover:bg-slate-600 text-slate-700 dark:text-slate-300 text-sm font-medium rounded-lg transition-colors text-center">
|
|
ล้างค่า
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-100 dark:border-slate-700 overflow-hidden">
|
|
<div class="flex justify-end p-4 pb-0">
|
|
<label class="inline-flex items-center cursor-pointer">
|
|
<input type="checkbox" id="togglePrefix" class="w-4 h-4 text-indigo-600 bg-slate-100 border-slate-300 rounded focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:ring-offset-slate-800 focus:ring-2 dark:bg-slate-700 dark:border-slate-600">
|
|
<span class="ml-2 text-sm font-medium text-slate-700 dark:text-slate-300">แสดงคำนำหน้าชื่อ</span>
|
|
</label>
|
|
</div>
|
|
<div class="overflow-x-auto p-4 pt-2">
|
|
<table class="w-full text-left text-sm text-slate-600 dark:text-slate-300">
|
|
<thead class="bg-slate-50 dark:bg-slate-900/50 text-slate-500 dark:text-slate-400 text-xs uppercase font-semibold">
|
|
<tr>
|
|
<th class="px-6 py-4">วัน-เวลา</th>
|
|
<th class="px-6 py-4">ผู้ใช้งาน</th>
|
|
<th class="px-6 py-4">รายการ (Action)</th>
|
|
<th class="px-6 py-4">รายละเอียด</th>
|
|
<th class="px-6 py-4">IP Address</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-100 dark:divide-slate-700">
|
|
<?php if (empty($logs)): ?>
|
|
<tr>
|
|
<td colspan="5" class="px-6 py-8 text-center text-slate-500 dark:text-slate-400">
|
|
ไม่พบข้อมูลประวัติการใช้งานตามเงื่อนไขที่ค้นหา
|
|
</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($logs as $log): ?>
|
|
<tr class="hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
|
|
<td class="px-6 py-4 whitespace-nowrap text-xs text-slate-500 dark:text-slate-400">
|
|
<?= date('d/m/Y H:i:s', strtotime($log['created_at'])) ?>
|
|
</td>
|
|
<td class="px-6 py-4" data-sort="<?= htmlspecialchars(preg_replace('/^(นาย|นางสาว|นาง|ว่าที่ร้อยตรี|น\.ส\.|นพ\.|พญ\.|ดร\.)\s*/u', '', trim($log['first_name']))) ?>">
|
|
<?php
|
|
$rawName = trim($log['first_name']);
|
|
$prefix = '';
|
|
$bodyName = $rawName;
|
|
if (preg_match('/^(นาย|นางสาว|นาง|ว่าที่ร้อยตรี|น\.ส\.|นพ\.|พญ\.|ดร\.)\s*(.*)$/u', $rawName, $matches)) {
|
|
$prefix = $matches[1];
|
|
$bodyName = $matches[2];
|
|
}
|
|
?>
|
|
<?php if ($log['user_id']): ?>
|
|
<div class="font-medium text-slate-800 dark:text-slate-200">
|
|
<span class="name-prefix hidden"><?= htmlspecialchars($prefix) ?></span><?= htmlspecialchars($bodyName . ' ' . $log['last_name']) ?>
|
|
</div>
|
|
<div class="text-xs text-slate-500">@<?= htmlspecialchars($log['username']) ?></div>
|
|
<?php else: ?>
|
|
<div class="font-medium text-sky-600 dark:text-sky-400">ตู้ Kiosk</div>
|
|
<div class="text-xs text-slate-500">Public Access</div>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
<?php
|
|
$actionColors = [
|
|
'LOGIN' => 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400',
|
|
'CREATE_USER' => 'bg-sky-100 text-sky-700 dark:bg-sky-900/30 dark:text-sky-400',
|
|
'UPDATE_USER' => 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400',
|
|
'TOGGLE_STATUS' => 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400',
|
|
'UPDATE_SETTINGS' => 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400',
|
|
'KIOSK_PRINT_SLIP' => 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',
|
|
'KIOSK_PRINT_TAX' => 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400'
|
|
];
|
|
$color = $actionColors[$log['action']] ?? 'bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-300';
|
|
?>
|
|
<span class="inline-flex items-center px-2.5 py-1 rounded-full text-xs font-semibold <?= $color ?>">
|
|
<?= htmlspecialchars($log['action']) ?>
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-slate-600 dark:text-slate-400 max-w-md truncate" title="<?= htmlspecialchars($log['description']) ?>">
|
|
<?= htmlspecialchars($log['description']) ?>
|
|
</td>
|
|
<td class="px-6 py-4 text-xs font-mono text-slate-500">
|
|
<?= htmlspecialchars($log['ip_address']) ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Checkbox toggle prefix
|
|
$('#togglePrefix').on('change', function() {
|
|
if ($(this).is(':checked')) {
|
|
$('.name-prefix').removeClass('hidden');
|
|
} else {
|
|
$('.name-prefix').addClass('hidden');
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php require_once APP_ROOT . '/app/Views/layouts/footer.php'; ?>
|