155 lines
6.8 KiB
PHP
155 lines
6.8 KiB
PHP
<?php
|
|
if (session_status() === PHP_SESSION_NONE) session_start();
|
|
if (!isset($_SESSION['user_id'])) {
|
|
header("Location: login.php");
|
|
exit;
|
|
}
|
|
|
|
include 'header.php';
|
|
include 'koneksi.php';
|
|
|
|
function getDeviceName($userAgent) {
|
|
$userAgent = strtolower($userAgent);
|
|
if (strpos($userAgent, 'windows') !== false) return 'Windows PC';
|
|
if (strpos($userAgent, 'macintosh') !== false || strpos($userAgent, 'mac os') !== false) return 'Mac OS PC';
|
|
if (strpos($userAgent, 'android') !== false) return 'Android Device';
|
|
if (strpos($userAgent, 'iphone') !== false || strpos($userAgent, 'ipad') !== false) return 'iOS Device';
|
|
if (strpos($userAgent, 'linux') !== false) return 'Linux PC';
|
|
return 'Unknown Device';
|
|
}
|
|
|
|
function getBrowserName($userAgent) {
|
|
if (strpos($userAgent, 'Chrome') !== false) return 'Google Chrome';
|
|
if (strpos($userAgent, 'Firefox') !== false) return 'Mozilla Firefox';
|
|
if (strpos($userAgent, 'Safari') !== false && strpos($userAgent, 'Chrome') === false) return 'Apple Safari';
|
|
if (strpos($userAgent, 'Edge') !== false) return 'Microsoft Edge';
|
|
if (strpos($userAgent, 'Opera') !== false || strpos($userAgent, 'OPR') !== false) return 'Opera';
|
|
return 'Unknown Browser';
|
|
}
|
|
|
|
$logs = [];
|
|
try {
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS login_history (
|
|
id_log INT AUTO_INCREMENT PRIMARY KEY,
|
|
id_account INT NOT NULL,
|
|
device_info VARCHAR(255),
|
|
ip_address VARCHAR(50),
|
|
login_time DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)");
|
|
|
|
$stmt = $pdo->prepare("SELECT * FROM login_history WHERE id_account = ? ORDER BY login_time DESC");
|
|
$stmt->execute([$_SESSION['user_id']]);
|
|
$logs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
// Graceful fallback
|
|
}
|
|
?>
|
|
<div class="main-panel">
|
|
<div class="content-wrapper">
|
|
<div class="row">
|
|
<div class="col-md-12 grid-margin">
|
|
<div class="row">
|
|
<div class="col-12 col-xl-8 mb-4 mb-xl-0 d-flex align-items-center">
|
|
<a href="dashboard.php" class="btn btn-sm btn-light mr-3 d-flex align-items-center" style="border-radius: 6px; padding: 6px 12px; color: #555; border: 1px solid #e2e8f0; text-decoration: none;">
|
|
<i class="mdi mdi-arrow-left" style="font-size: 14px; margin-right: 4px;"></i> Back
|
|
</a>
|
|
<div>
|
|
<h3 class="font-weight-bold mb-1">Login History</h3>
|
|
<h6 class="font-weight-normal mb-0">System access login history.</h6>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12 grid-margin stretch-card">
|
|
<div class="card" style="border: 1px solid #e2e8f0; border-radius: 10px;">
|
|
<div class="card-body">
|
|
<p class="card-title mb-3">Complete Login History</p>
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-striped" id="authLogTable">
|
|
<thead style="background: #f8f9fa;">
|
|
<tr>
|
|
<th>No</th>
|
|
<th>Login Time</th>
|
|
<th>Device</th>
|
|
<th>Browser</th>
|
|
<th>IP Address</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if(count($logs) > 0): ?>
|
|
<?php $no = 1; foreach($logs as $log):
|
|
$time = strtotime($log['login_time']);
|
|
$formattedDate = date('d F Y', $time);
|
|
$formattedTime = date('H:i:s', $time);
|
|
|
|
$device = getDeviceName($log['device_info']);
|
|
$browser = getBrowserName($log['device_info']);
|
|
?>
|
|
<tr>
|
|
<td style="font-weight: 500;"><?= $no++ ?></td>
|
|
<td>
|
|
<div style="font-weight: 600; color: #212529; font-size: 14px;"><?= $formattedDate ?></div>
|
|
<div style="font-size: 12px; color: #6c757d;"><i class="mdi mdi-clock-outline mr-1"></i><?= $formattedTime ?></div>
|
|
</td>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<?php if(strpos($device, 'Windows') !== false || strpos($device, 'Mac') !== false || strpos($device, 'Linux') !== false): ?>
|
|
<div style="width: 32px; height: 32px; border-radius: 50%; background: #eff6ff; display: flex; align-items: center; justify-content: center; margin-right: 10px;">
|
|
<i class="mdi mdi-laptop" style="font-size: 16px; color: #3b82f6;"></i>
|
|
</div>
|
|
<?php else: ?>
|
|
<div style="width: 32px; height: 32px; border-radius: 50%; background: #f0fdf4; display: flex; align-items: center; justify-content: center; margin-right: 10px;">
|
|
<i class="mdi mdi-cellphone" style="font-size: 16px; color: #10b981;"></i>
|
|
</div>
|
|
<?php endif; ?>
|
|
<span style="font-weight: 500; font-size: 14px; color: #333;"><?= $device ?></span>
|
|
</div>
|
|
</td>
|
|
<td style="color: #555; font-size: 13px;"><?= $browser ?></td>
|
|
<td style="font-family: monospace; color: #4B49AC; font-weight: 600;"><?= htmlspecialchars($log['ip_address']) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr>
|
|
<td colspan="5" class="text-center py-4 text-muted">No login history found.</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php include 'footer.php'; ?>
|
|
<?php include 'copy.php'; ?>
|
|
</div>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
if ($.fn.DataTable.isDataTable('#authLogTable')) {
|
|
$('#authLogTable').DataTable().destroy();
|
|
}
|
|
$('#authLogTable').DataTable({
|
|
"order": [], // Let it follow original SQL order (desc) but allow sorting
|
|
"pageLength": 15,
|
|
"lengthMenu": [10, 15, 25, 50, 100],
|
|
"language": {
|
|
"search": "Search History:",
|
|
"lengthMenu": "Show _MENU_ records per page",
|
|
"info": "Showing _START_ to _END_ of _TOTAL_ total records",
|
|
"paginate": {
|
|
"first": "First",
|
|
"last": "Last",
|
|
"next": "Next",
|
|
"previous": "Previous"
|
|
}
|
|
}
|
|
});
|
|
});
|
|
</script>
|