Mini Kabibi Habibi
<?php
session_start();
include 'includes/db.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
header("Location: login.php");
exit();
}
$page_title = "Medical Stock Record";
// Options for entries per page
$perPageOptions = [10, 20, 50, 100];
$limit = isset($_GET['limit']) && in_array((int)$_GET['limit'], $perPageOptions) ? (int)$_GET['limit'] : 10;
// Status filter
$filter_status = $_GET['status'] ?? '';
// Pagination
$page = isset($_GET['page']) && is_numeric($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;
// Base query
$sql = "SELECT * FROM medical_supplies";
$params = [];
// Apply status filter
if ($filter_status !== '') {
$all_supplies = $pdo->query("SELECT * FROM medical_supplies")->fetchAll(PDO::FETCH_ASSOC);
$filtered_ids = [];
foreach ($all_supplies as $supply) {
$balance = (int)$supply['balance'];
$expiration = new DateTime($supply['expiration_date']);
$today = new DateTime();
$daysLeft = (int)$today->diff($expiration)->format('%r%a');
$status = '';
if ($balance <= 0) {
$status = 'no_stock';
} elseif ($daysLeft < 0) {
$status = 'expired';
} elseif ($daysLeft <= 30) {
$status = 'expiring';
} else {
$status = 'ok';
}
if ($status === $filter_status) {
$filtered_ids[] = $supply['id'];
}
}
if (empty($filtered_ids)) {
$supplies = [];
$total_records = 0;
$total_pages = 1;
} else {
$placeholders = implode(',', array_fill(0, count($filtered_ids), '?'));
$sql .= " WHERE id IN ($placeholders)";
$params = $filtered_ids;
$count_stmt = $pdo->prepare("SELECT COUNT(*) FROM medical_supplies WHERE id IN ($placeholders)");
$count_stmt->execute($filtered_ids);
$total_records = $count_stmt->fetchColumn();
$total_pages = ceil($total_records / $limit);
$sql .= " ORDER BY date_received DESC LIMIT $limit OFFSET $offset";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$supplies = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
} else {
$total_stmt = $pdo->query("SELECT COUNT(*) FROM medical_supplies");
$total_records = $total_stmt->fetchColumn();
$total_pages = ceil($total_records / $limit);
$stmt = $pdo->prepare("SELECT * FROM medical_supplies ORDER BY date_received DESC LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$supplies = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title><?= htmlspecialchars($page_title) ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<style>
body {
margin: 0;
background-color: #f8f9fa;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
width: 250px;
height: 100vh;
background-color: #2c3e50;
color: white;
overflow-y: auto;
}
.sidebar a {
color: #ccc;
text-decoration: none;
padding: 15px;
display: block;
transition: 0.3s;
}
.sidebar a:hover {
background-color: #34495e;
color: #fff;
}
.main-content {
margin-left: 250px;
padding: 40px;
}
h2.page-title {
font-weight: 600;
margin-bottom: 30px;
}
.table-wrapper {
max-height: 500px;
overflow-y: auto;
border: 1px solid #dee2e6;
background-color: white;
border-radius: 8px;
}
thead th {
position: sticky;
top: 0;
background-color: #343a40;
color: white;
}
.filter-bar {
display: flex;
gap: 20px;
margin-bottom: 20px;
align-items: center;
}
select.form-select {
width: auto;
}
</style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
</head>
<body>
<?php include 'sidebar.php'; ?>
<div class="main-content">
<h2 class="page-title"><?= htmlspecialchars($page_title) ?></h2>
<form method="GET" class="filter-bar">
<!-- Limit Selector -->
<label for="limit" class="mb-0">Show:</label>
<select name="limit" id="limit" class="form-select form-select-sm" onchange="this.form.submit()">
<?php foreach ($perPageOptions as $option): ?>
<option value="<?= $option ?>" <?= $limit === $option ? 'selected' : '' ?>><?= $option ?></option>
<?php endforeach; ?>
</select>
<!-- Status Filter -->
<label for="status" class="mb-0">Status:</label>
<select name="status" id="status" class="form-select form-select-sm" onchange="this.form.submit()">
<option value="">All</option>
<option value="ok" <?= $filter_status === 'ok' ? 'selected' : '' ?>>OK</option>
<option value="expiring" <?= $filter_status === 'expiring' ? 'selected' : '' ?>>Expiring (≤ 30 days)</option>
<option value="expired" <?= $filter_status === 'expired' ? 'selected' : '' ?>>Expired</option>
<option value="no_stock" <?= $filter_status === 'no_stock' ? 'selected' : '' ?>>No Stock</option>
</select>
<input type="hidden" name="page" value="1" />
</form>
<div class="table-wrapper">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Item</th>
<th>Description</th>
<th>Unit</th>
<th>Date Received</th>
<th>Expiration</th>
<th>Status</th>
<th>Quantity</th>
<th>Issued</th>
<th>Balance</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php if (!empty($supplies)): ?>
<?php foreach ($supplies as $supply): ?>
<?php
$today = new DateTime();
$expiration = new DateTime($supply['expiration_date']);
$daysLeft = (int)$today->diff($expiration)->format('%r%a');
$balance = (int)$supply['balance'];
if ($balance <= 0) {
$status = '<span class="badge bg-secondary">No stock</span>';
} elseif ($daysLeft < 0) {
$status = '<span class="badge bg-danger">Expired</span>';
} elseif ($daysLeft <= 30) {
$status = '<span class="badge bg-warning text-dark">Expiring in ' . $daysLeft . ' days</span>';
} else {
$status = '<span class="badge bg-success">OK</span>';
}
?>
<tr>
<td><?= htmlspecialchars($supply['item']) ?></td>
<td><?= htmlspecialchars($supply['description']) ?></td>
<td><?= htmlspecialchars($supply['unit']) ?></td>
<td><?= htmlspecialchars($supply['date_received']) ?></td>
<td><?= htmlspecialchars($supply['expiration_date']) ?></td>
<td><?= $status ?></td>
<td><?= htmlspecialchars($supply['quantity']) ?></td>
<td><?= htmlspecialchars($supply['issued']) ?></td>
<td><?= htmlspecialchars($supply['balance']) ?></td>
<td>
<a href="edit_supply.php?id=<?= $supply['id'] ?>"
class="btn btn-sm btn-outline-primary action-btn me-1"
title="Edit">
<i class="bi bi-pencil"></i>
</a>
<a href="delete_supply.php?id=<?= $supply['id'] ?>"
class="btn btn-sm btn-outline-danger action-btn"
title="Delete"
onclick="return confirm('Are you sure you want to delete this supply?');">
<i class="bi bi-trash"></i>
</a>
</td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<tr>
<td colspan="10" class="text-center">No supply records found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<!-- Pagination -->
<?php if ($total_pages > 1): ?>
<nav class="mt-3">
<ul class="pagination">
<li class="page-item <?= $page <= 1 ? 'disabled' : '' ?>">
<a class="page-link" href="?<?= http_build_query(array_merge($_GET, ['page' => $page - 1])) ?>">« Prev</a>
</li>
<?php for ($i = 1; $i <= $total_pages; $i++): ?>
<li class="page-item <?= $page === $i ? 'active' : '' ?>">
<a class="page-link" href="?<?= http_build_query(array_merge($_GET, ['page' => $i])) ?>"><?= $i ?></a>
</li>
<?php endfor; ?>
<li class="page-item <?= $page >= $total_pages ? 'disabled' : '' ?>">
<a class="page-link" href="?<?= http_build_query(array_merge($_GET, ['page' => $page + 1])) ?>">Next »</a>
</li>
</ul>
</nav>
<?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>