Updated features

This commit is contained in:
Sayan Das 2026-04-17 11:13:04 +05:30
parent c0e01c6dae
commit d5f406f45d
6 changed files with 68 additions and 7 deletions

View File

@ -48,6 +48,7 @@ $routes->get('admin/doctors/data', 'Admin::getDoctors');
$routes->get('admin/patients/data', 'Admin::getPatients'); $routes->get('admin/patients/data', 'Admin::getPatients');
$routes->get('/admin/activity-log', 'ActivityLog::index'); $routes->get('/admin/activity-log', 'ActivityLog::index');
$routes->get('/admin/activity/analytics', 'ActivityLog::analytics'); $routes->get('/admin/activity/analytics', 'ActivityLog::analytics');
$routes->post('/admin/activity-log/clear', 'ActivityLog::clear');
// $routes->post('/admin/activity-log/datatable', 'ActivityLog::datatable'); // $routes->post('/admin/activity-log/datatable', 'ActivityLog::datatable');
// $routes->get('/admin/activity-log/summary', 'ActivityLog::getSummary'); // $routes->get('/admin/activity-log/summary', 'ActivityLog::getSummary');
// $routes->get('/admin/activity-log/critical', 'ActivityLog::getCritical'); // $routes->get('/admin/activity-log/critical', 'ActivityLog::getCritical');

View File

@ -34,9 +34,15 @@ class ActivityLog extends BaseController
// Get filtered logs // Get filtered logs
$logs = $activityModel->getFilteredLogs($filters, 200); $logs = $activityModel->getFilteredLogs($filters, 200);
// Debug: Check database connection and count
$db = \Config\Database::connect();
$totalInDb = $db->table('activity_logs')->countAll();
log_message('debug', 'Activity logs in database: ' . $totalInDb . ', retrieved: ' . count($logs));
return view('admin/activity_log', [ return view('admin/activity_log', [
'logs' => $logs, 'logs' => $logs,
'totalLogs' => count($logs), 'totalLogs' => count($logs),
'totalInDb' => $totalInDb,
'actionSummary' => $activityModel->getActionSummary(), 'actionSummary' => $activityModel->getActionSummary(),
'roleSummary' => $activityModel->getRoleSummary(), 'roleSummary' => $activityModel->getRoleSummary(),
'filters' => [ 'filters' => [
@ -67,6 +73,24 @@ class ActivityLog extends BaseController
]); ]);
} }
public function clear()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
if ($this->request->getMethod() === 'post') {
$activityModel = new ActivityLogModel();
if ($activityModel->clearAll()) {
return redirect()->to(base_url('admin/activity-log'))->with('success', 'All activity logs have been cleared.');
} else {
return redirect()->to(base_url('admin/activity-log'))->with('error', 'Failed to clear activity logs.');
}
}
return redirect()->to(base_url('admin/activity-log'));
}
public function analytics() public function analytics()
{ {
if ($r = $this->requireRole('admin')) { if ($r = $this->requireRole('admin')) {

View File

@ -96,7 +96,10 @@ class Auth extends BaseController
]); ]);
$logModel = new ActivityLogModel(); $logModel = new ActivityLogModel();
$logModel->log('login', "User logged in as {$user['role']}", 'user', (int) $user['id']); $result = $logModel->log('login', "User logged in as {$user['role']}", 'user', (int) $user['id']);
if (!$result) {
log_message('error', 'Failed to log login activity for user ' . $user['id']);
}
if ($user['role'] === 'admin') { if ($user['role'] === 'admin') {
return redirect()->to(site_url('admin/dashboard')); return redirect()->to(site_url('admin/dashboard'));

View File

@ -52,7 +52,7 @@ class ActivityLogModel extends Model
$validTargetTypes = ['admin', 'doctor', 'patient']; $validTargetTypes = ['admin', 'doctor', 'patient'];
$targetUserType = in_array($targetType, $validTargetTypes, true) ? $targetType : null; $targetUserType = in_array($targetType, $validTargetTypes, true) ? $targetType : null;
return (bool) $this->insert([ $data = [
'ip' => $ipAddress, 'ip' => $ipAddress,
'action' => $action, 'action' => $action,
'description' => $description, 'description' => $description,
@ -62,7 +62,18 @@ class ActivityLogModel extends Model
'target_user_type' => $targetUserType, 'target_user_type' => $targetUserType,
'activity_page' => $request->getPath(), 'activity_page' => $request->getPath(),
'activity_at' => date('Y-m-d H:i:s'), 'activity_at' => date('Y-m-d H:i:s'),
]); ];
try {
$result = $this->insert($data);
if (!$result) {
log_message('error', 'Failed to insert activity log: ' . json_encode($data) . ' - Errors: ' . json_encode($this->errors()));
}
return (bool) $result;
} catch (\Exception $e) {
log_message('error', 'Exception in ActivityLogModel::log: ' . $e->getMessage());
return false;
}
} }
public function getFilteredLogs(array $filters = [], int $limit = 200): array public function getFilteredLogs(array $filters = [], int $limit = 200): array
@ -200,4 +211,9 @@ class ActivityLogModel extends Model
->orderBy('activity_at', 'DESC') ->orderBy('activity_at', 'DESC')
->findAll($limit); ->findAll($limit);
} }
public function clearAll(): bool
{
return $this->truncate();
}
} }

View File

@ -78,16 +78,16 @@ function formatLabel($label) {
<p class="stat-label">Total Actions</p> <p class="stat-label">Total Actions</p>
</div> </div>
</div> </div>
<div class="col-md-3"> <!-- <div class="col-md-3">
<div class="stat-card green"> <div class="stat-card green">
<p class="stat-value"><?= count($summary['by_action'] ?? []) ?></p> <p class="stat-value"><?= count($summary['by_action'] ?? []) ?></p>
<p class="stat-label">Action Types</p> <p class="stat-label">Action Types</p>
</div> </div>
</div> </div> -->
<div class="col-md-3"> <div class="col-md-3">
<div class="stat-card blue"> <div class="stat-card blue">
<p class="stat-value"><?= count($summary['by_role'] ?? []) ?></p> <p class="stat-value"><?= count($summary['by_role'] ?? []) ?></p>
<p class="stat-label">Active Roles</p> <p class="stat-label">Activity Roles</p>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

View File

@ -118,6 +118,20 @@
</header> </header>
<main class="ov-content"> <main class="ov-content">
<!-- Flash Messages -->
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle me-2"></i><?= esc(session()->getFlashdata('success')) ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i><?= esc(session()->getFlashdata('error')) ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<!-- Search & Filter Section --> <!-- Search & Filter Section -->
<div class="ov-panel mb-4"> <div class="ov-panel mb-4">
<div class="ov-panel__header"> <div class="ov-panel__header">
@ -194,7 +208,7 @@
</div> </div>
<div> <div>
<div class="ov-stat__label">Total Entries</div> <div class="ov-stat__label">Total Entries</div>
<p class="ov-stat__value"><?= esc($totalLogs) ?></p> <p class="ov-stat__value"><?= esc($totalLogs) ?> (DB: <?= esc($totalInDb) ?>)</p>
</div> </div>
</div> </div>
</div> </div>
@ -230,6 +244,9 @@
</div> </div>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<a href="<?= base_url('admin/activity/analytics') ?>" class="btn btn-sm btn-outline-secondary">View Analytics</a> <a href="<?= base_url('admin/activity/analytics') ?>" class="btn btn-sm btn-outline-secondary">View Analytics</a>
<form method="post" action="<?= base_url('admin/activity-log/clear') ?>" style="display: inline;" onsubmit="return confirm('Are you sure you want to clear all activity logs? This action cannot be undone.')">
<button type="submit" class="btn btn-sm btn-outline-danger">Clear Log</button>
</form>
</div> </div>
</div> </div>
<div class="ov-panel__body p-0"> <div class="ov-panel__body p-0">