version 2.1

This commit is contained in:
Flatlogic Bot 2025-11-25 08:26:31 +00:00
parent c8d83e1d5c
commit fea1dbbb79
6 changed files with 553 additions and 156 deletions

View File

@ -1,124 +1,271 @@
/* assets/css/custom.css */
:root {
--primary-color: #6a5acd; /* SlateBlue */
--primary-color-dark: #483d8b; /* DarkSlateBlue */
--secondary-color: #f0f8ff; /* AliceBlue */
--text-color: #333;
--text-color-light: #777;
--border-color: #e6e6fa; /* Lavender */
--sidebar-bg: #ffffff;
--sidebar-link-color: #555;
--sidebar-link-hover-bg: #f0f0f0;
--sidebar-link-active-color: #ffffff;
--sidebar-link-active-bg: var(--primary-color);
--card-bg: #ffffff;
--card-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
--font-family: 'Poppins', sans-serif;
}
body {
font-family: 'Poppins', sans-serif;
background-color: #F8F9FA;
color: #212529;
font-family: var(--font-family);
background-color: var(--secondary-color);
color: var(--text-color);
font-size: 15px;
background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23dcdcdc' fill-opacity='0.3'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
}
.page-wrapper {
display: flex;
}
.sidebar {
background-color: #2c3e50;
width: 260px;
background-color: var(--sidebar-bg);
height: 100vh;
position: sticky;
top: 0;
border-right: 1px solid var(--border-color);
padding: 1.5rem 1rem;
display: flex;
flex-direction: column;
box-shadow: 0 0 15px rgba(0,0,0,0.05);
}
.sidebar-header {
margin-bottom: 2rem;
}
.sidebar-brand {
display: flex;
align-items: center;
font-size: 1.5rem;
font-weight: 600;
color: var(--primary-color);
text-decoration: none;
}
.sidebar-brand .bi {
font-size: 2rem;
margin-right: 0.5rem;
}
.sidebar-nav {
flex-grow: 1;
}
.sidebar .nav-link {
color: rgba(255, 255, 255, 0.7);
color: var(--sidebar-link-color);
border-radius: 0.5rem;
margin-bottom: 0.5rem;
display: flex;
align-items: center;
padding: 0.75rem 1rem;
transition: background-color 0.2s, color 0.2s;
}
.sidebar .nav-link:hover {
color: #ffffff;
background-color: rgba(255, 255, 255, 0.1);
color: var(--primary-color);
background-color: var(--sidebar-link-hover-bg);
}
.sidebar .nav-link.active {
color: #ffffff;
background-color: #4A90E2;
color: var(--sidebar-link-active-color);
background-color: var(--sidebar-link-active-bg);
box-shadow: 0 2px 5px rgba(106, 90, 205, 0.3);
}
.sidebar .nav-link .bi {
font-size: 1.2rem;
margin-right: 1rem;
width: 20px;
text-align: center;
}
.sidebar hr {
border-color: rgba(255, 255, 255, 0.2);
.sidebar-footer {
margin-top: auto;
}
.main-content {
background-color: #F8F9FA;
flex-grow: 1;
padding: 2rem;
}
.btn-primary-custom {
background-color: #4A90E2;
border-color: #4A90E2;
color: #ffffff;
padding: 0.75rem 1.25rem;
border-radius: 0.5rem;
font-weight: 600;
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
.header {
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--border-color);
}
.btn-primary-custom:hover {
background-color: #357ABD;
border-color: #357ABD;
color: #ffffff;
.header-title {
font-size: 2.2rem;
font-weight: 700;
margin: 0;
}
.card {
.header-subtitle {
font-size: 1rem;
color: var(--text-color-light);
}
.content-card, .card {
background-color: var(--card-bg);
border-radius: 0.75rem;
box-shadow: var(--card-shadow);
border: none;
border-radius: 0.5rem;
box-shadow: 0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15) !important;
margin-bottom: 2rem;
}
.card .card-header {
background-color: #fff;
border-bottom: 1px solid #e3e6f0;
padding: 1rem 1.25rem;
.card-header {
background-color: transparent;
border-bottom: 1px solid var(--border-color);
padding: 1.5rem;
display: flex;
align-items: center;
}
.card .card-body {
.card-title-text, .card-header .m-0 {
font-size: 1.2rem;
font-weight: 600;
margin: 0;
color: var(--primary-color);
}
.card-body {
padding: 1.5rem;
}
.border-left-primary {
border-left: 0.25rem solid #4A90E2 !important;
.table {
border-collapse: collapse;
width: 100%;
}
.text-primary {
color: #4A90E2 !important;
.table thead th {
border-bottom: 2px solid var(--border-color);
font-weight: 600;
color: var(--text-color-light);
padding: 1rem 1.5rem;
text-align: left;
}
.border-left-success {
border-left: 0.25rem solid #1cc88a !important;
.table tbody tr {
border-bottom: 1px solid var(--border-color);
transition: background-color 0.2s;
}
.text-success {
color: #1cc88a !important;
.table tbody tr:last-child {
border-bottom: none;
}
.border-left-info {
border-left: 0.25rem solid #36b9cc !important;
.table tbody tr:hover {
background-color: #f9f9f9;
}
.text-info {
color: #36b9cc !important;
.table td, .table th {
padding: 1rem 1.5rem;
vertical-align: middle;
}
.text-gray-300 {
color: #dddfeb !important;
.table a {
color: var(--primary-color);
text-decoration: none;
font-weight: 600;
}
.text-gray-800 {
color: #5a5c69 !important;
.table a:hover {
text-decoration: underline;
}
.font-weight-bold {
font-weight: 700 !important;
.badge.bg-success-soft {
background-color: rgba(28, 200, 138, 0.1);
color: #1cc88a;
}
.text-xs {
font-size: .7rem;
.badge.bg-warning-soft {
background-color: rgba(246, 194, 62, 0.1);
color: #f6c23e;
}
.badge.bg-info-soft {
background-color: rgba(54, 185, 204, 0.1);
color: #36b9cc;
}
.btn {
border-radius: 0.5rem;
padding: 0.6rem 1.2rem;
font-weight: 600;
transition: all 0.2s;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.btn-primary, .btn-primary-custom {
background-color: var(--primary-color);
border-color: var(--primary-color);
color: white;
}
.btn-primary:hover, .btn-primary-custom:hover {
background-color: var(--primary-color-dark);
border-color: var(--primary-color-dark);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.form-control, .form-select {
border-radius: 0.5rem;
padding: 0.75rem 1rem;
border: 1px solid var(--border-color);
transition: border-color 0.2s, box-shadow 0.2s;
}
.form-control:focus, .form-select:focus {
box-shadow: 0 0 0 0.25rem rgba(74, 144, 226, 0.25);
border-color: #4A90E2;
box-shadow: 0 0 0 0.25rem rgba(106, 90, 205, 0.15);
border-color: var(--primary-color);
}
.modal-content {
border-radius: 0.75rem;
border: none;
box-shadow: 0 8px 24px rgba(0,0,0,0.1);
}
.search-container {
position: relative;
width: 100%;
max-width: 400px;
}
.search-results {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 1000;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 0 0 5px 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
display: none;
}
.search-results a {
display: block;
padding: 10px;
text-decoration: none;
color: #333;
border-bottom: 1px solid #eee;
}
.search-results a:hover {
background-color: #f5f5f5;
}
.search-results a:last-child {
border-bottom: none;
}

View File

@ -50,6 +50,7 @@ try {
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
@ -82,11 +83,11 @@ try {
</nav>
<div class="sidebar-footer">
<div class="dropdown">
<a href="#" class="d-flex align-items-center text-white text-decoration-none dropdown-toggle" id="dropdownUser1" data-bs-toggle="dropdown" aria-expanded="false">
<a href="#" class="d-flex align-items-center dropdown-toggle" id="dropdownUser1" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle me-2"></i>
<strong><?php echo htmlspecialchars($_SESSION['username']); ?></strong>
</a>
<ul class="dropdown-menu dropdown-menu-dark text-small shadow" aria-labelledby="dropdownUser1">
<ul class="dropdown-menu text-small shadow" aria-labelledby="dropdownUser1">
<li><a class="dropdown-item" href="logout.php">Sign out</a></li>
</ul>
</div>
@ -95,20 +96,25 @@ try {
<!-- Main Content -->
<main class="main-content">
<div class="container-fluid">
<div class="header">
<div class="header d-flex justify-content-between align-items-center">
<div>
<h1 class="header-title">Doctor's Dashboard</h1>
<p class="header-subtitle">Welcome, Dr. <?php echo htmlspecialchars($doctor['username'] ?? 'Doctor'); ?>!</p>
<p class="header-subtitle mb-0">Welcome, Dr. <?php echo htmlspecialchars($doctor['username'] ?? 'Doctor'); ?>!</p>
</div>
<div class="search-container">
<input type="text" id="patientSearch" class="form-control" placeholder="Search Patient by Name or ID...">
<div id="searchResults" class="search-results"></div>
</div>
</div>
<!-- Today's Patients -->
<div class="card content-card">
<div class="content-card">
<div class="card-header">
<h5 class="card-title-text"><i class="bi bi-list-ul me-2"></i>Today's Appointments</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<table class="table">
<thead>
<tr>
<th>Patient ID</th>
@ -166,7 +172,6 @@ try {
</div>
</div>
</div>
</div>
</main>
</div>
@ -399,6 +404,51 @@ function updatePatientStatus(visitId, status, notes = null, service = null, cost
alert('An unexpected error occurred.');
});
}
document.getElementById('patientSearch').addEventListener('input', function() {
const searchTerm = this.value;
const resultsContainer = document.getElementById('searchResults');
if (searchTerm.length < 2) {
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
return;
}
fetch(`search_patient.php?term=${encodeURIComponent(searchTerm)}`)
.then(response => response.json())
.then(data => {
resultsContainer.innerHTML = '';
if (data.length > 0) {
data.forEach(patient => {
const patientLink = document.createElement('a');
patientLink.href = `patient_profile.php?id=${patient.id}`;
patientLink.textContent = `${patient.patient_name} (${patient.patient_id})`;
resultsContainer.appendChild(patientLink);
});
resultsContainer.style.display = 'block';
} else {
resultsContainer.innerHTML = '<a href="#" class="disabled">No patients found</a>';
resultsContainer.style.display = 'block';
}
})
.catch(error => {
console.error('Error:', error);
resultsContainer.innerHTML = '<a href="#" class="disabled">Search error</a>';
resultsContainer.style.display = 'block';
});
});
// Hide results when clicking outside
document.addEventListener('click', function(e) {
const searchContainer = document.querySelector('.search-container');
if (searchContainer && !searchContainer.contains(e.target)) {
const resultsContainer = document.getElementById('searchResults');
if (resultsContainer) {
resultsContainer.style.display = 'none';
}
}
});
</script>
</body>
</html>

View File

@ -42,6 +42,38 @@ $pending_tests = $pending_tests_stmt->fetchAll(PDO::FETCH_ASSOC);
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
<style>
.search-container {
position: relative;
width: 100%;
max-width: 400px;
}
.search-results {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 1000;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 0 0 5px 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
display: none;
}
.search-results a {
display: block;
padding: 10px;
text-decoration: none;
color: #333;
border-bottom: 1px solid #eee;
}
.search-results a:hover {
background-color: #f5f5f5;
}
.search-results a:last-child {
border-bottom: none;
}
</style>
</head>
<body>
@ -89,6 +121,10 @@ $pending_tests = $pending_tests_stmt->fetchAll(PDO::FETCH_ASSOC);
<main class="main-content">
<header class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0 text-gray-800">Pending Lab & Imaging Reports</h1>
<div class="search-container">
<input type="text" id="patientSearch" class="form-control" placeholder="Search Patient by Name or ID...">
<div id="searchResults" class="search-results"></div>
</div>
</header>
<div class="card shadow-sm">
@ -194,6 +230,51 @@ document.addEventListener('submit', function(e) {
});
}
});
document.getElementById('patientSearch').addEventListener('input', function() {
const searchTerm = this.value;
const resultsContainer = document.getElementById('searchResults');
if (searchTerm.length < 2) {
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
return;
}
fetch(`search_patient.php?term=${encodeURIComponent(searchTerm)}`)
.then(response => response.json())
.then(data => {
resultsContainer.innerHTML = '';
if (data.length > 0) {
data.forEach(patient => {
const patientLink = document.createElement('a');
patientLink.href = `patient_profile.php?id=${patient.id}`;
patientLink.textContent = `${patient.patient_name} (${patient.patient_id})`;
resultsContainer.appendChild(patientLink);
});
resultsContainer.style.display = 'block';
} else {
resultsContainer.innerHTML = '<a href="#" class="disabled">No patients found</a>';
resultsContainer.style.display = 'block';
}
})
.catch(error => {
console.error('Error:', error);
resultsContainer.innerHTML = '<a href="#" class="disabled">Search error</a>';
resultsContainer.style.display = 'block';
});
});
// Hide results when clicking outside
document.addEventListener('click', function(e) {
const searchContainer = document.querySelector('.search-container');
if (searchContainer && !searchContainer.contains(e.target)) {
const resultsContainer = document.getElementById('searchResults');
if (resultsContainer) {
resultsContainer.style.display = 'none';
}
}
});
</script>
</body>
</html>

View File

@ -36,6 +36,38 @@ $pending_prescriptions = $pending_prescriptions_stmt->fetchAll(PDO::FETCH_ASSOC)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
<style>
.search-container {
position: relative;
width: 100%;
max-width: 400px;
}
.search-results {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 1000;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 0 0 5px 5px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
display: none;
}
.search-results a {
display: block;
padding: 10px;
text-decoration: none;
color: #333;
border-bottom: 1px solid #eee;
}
.search-results a:hover {
background-color: #f5f5f5;
}
.search-results a:last-child {
border-bottom: none;
}
</style>
</head>
<body>
@ -83,6 +115,10 @@ $pending_prescriptions = $pending_prescriptions_stmt->fetchAll(PDO::FETCH_ASSOC)
<main class="main-content">
<header class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0 text-gray-800">Pharmacy - Pending Prescriptions</h1>
<div class="search-container">
<input type="text" id="patientSearch" class="form-control" placeholder="Search Patient by Name or ID...">
<div id="searchResults" class="search-results"></div>
</div>
</header>
<div class="card shadow-sm">
@ -160,6 +196,51 @@ document.addEventListener('click', function(e) {
});
}
});
document.getElementById('patientSearch').addEventListener('input', function() {
const searchTerm = this.value;
const resultsContainer = document.getElementById('searchResults');
if (searchTerm.length < 2) {
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
return;
}
fetch(`search_patient.php?term=${encodeURIComponent(searchTerm)}`)
.then(response => response.json())
.then(data => {
resultsContainer.innerHTML = '';
if (data.length > 0) {
data.forEach(patient => {
const patientLink = document.createElement('a');
patientLink.href = `patient_profile.php?id=${patient.id}`;
patientLink.textContent = `${patient.patient_name} (${patient.patient_id})`;
resultsContainer.appendChild(patientLink);
});
resultsContainer.style.display = 'block';
} else {
resultsContainer.innerHTML = '<a href="#" class="disabled">No patients found</a>';
resultsContainer.style.display = 'block';
}
})
.catch(error => {
console.error('Error:', error);
resultsContainer.innerHTML = '<a href="#" class="disabled">Search error</a>';
resultsContainer.style.display = 'block';
});
});
// Hide results when clicking outside
document.addEventListener('click', function(e) {
const searchContainer = document.querySelector('.search-container');
if (searchContainer && !searchContainer.contains(e.target)) {
const resultsContainer = document.getElementById('searchResults');
if (resultsContainer) {
resultsContainer.style.display = 'none';
}
}
});
</script>
</body>
</html>

View File

@ -23,6 +23,7 @@ $total_revenue = $pdo->query("SELECT SUM(total_fee) FROM patients WHERE status =
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css">
</head>
<body>
@ -76,6 +77,10 @@ $total_revenue = $pdo->query("SELECT SUM(total_fee) FROM patients WHERE status =
<div class="main-content flex-grow-1 p-4">
<header class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0 text-gray-800">Receptionist Dashboard</h1>
<div class="search-container">
<input type="text" id="patientSearch" class="form-control" placeholder="Search Patient by Name or ID...">
<div id="searchResults" class="search-results"></div>
</div>
<a href="patient_register.php" class="btn btn-primary-custom">
<i class="bi bi-person-plus-fill me-2"></i>
Register New Patient
@ -136,20 +141,7 @@ $total_revenue = $pdo->query("SELECT SUM(total_fee) FROM patients WHERE status =
</div>
</div>
<!-- Patient Search -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Find a Patient</h6>
</div>
<div class="card-body">
<form action="reception.php" method="GET" class="d-flex">
<input type="text" class="form-control me-2" name="search_query" placeholder="Enter Patient Name or ID..." value="<?php echo isset($_GET['search_query']) ? htmlspecialchars($_GET['search_query']) : ''; ?>">
<button type="submit" class="btn btn-primary-custom">
<i class="bi bi-search"></i> Search
</button>
</form>
</div>
</div>
<!-- Patient List -->
<div class="card shadow">
@ -164,39 +156,26 @@ $total_revenue = $pdo->query("SELECT SUM(total_fee) FROM patients WHERE status =
<th>Patient ID</th>
<th>Patient Name</th>
<th>Phone Number</th>
<th>Assigned Doctor</th>
<th>Status</th>
<th>Date</th>
<th>Registration Date</th>
</tr>
</thead>
<tbody>
<?php
$search_query = isset($_GET['search_query']) ? trim($_GET['search_query']) : '';
$sql = "SELECT p.*, d.doctor_name FROM patients p LEFT JOIN doctors d ON p.doctor_id = d.id";
$params = [];
if (!empty($search_query)) {
$sql .= " WHERE p.patient_name LIKE ? OR p.patient_id LIKE ?";
$params = ["%$search_query%", "%$search_query%"];
}
$sql .= " ORDER BY p.created_at DESC LIMIT 10";
$sql = "SELECT * FROM patients ORDER BY created_at DESC LIMIT 10";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$stmt->execute();
if ($stmt->rowCount() > 0) {
while ($row = $stmt->fetch()) {
echo "<tr>";
echo "<td><a href='patient_profile.php?id=" . $row['id'] . "'>" . htmlspecialchars($row['patient_id']) . "</a></td>";
echo "<td><a href='patient_profile.php?id=" . $row['id'] . "'>" . htmlspecialchars($row['patient_name']) . "</a></td>";
echo "<td>" . htmlspecialchars($row['phone_number']) . "</td>";
echo "<td>" . htmlspecialchars($row['doctor_name'] ?? 'N/A') . "</td>";
echo "<td><span class='badge bg-secondary'>" . htmlspecialchars($row['status']) . "</span></td>";
echo "<td>" . htmlspecialchars($row['phone']) . "</td>";
echo "<td>" . date("Y-m-d H:i", strtotime($row['created_at'])) . "</td>";
echo "</tr>";
}
} else {
echo '<tr><td colspan="6" class="text-center">No patients found.</td></tr>';
echo '<tr><td colspan="4" class="text-center">No patients found.</td></tr>';
}
?>
</tbody>
@ -209,5 +188,51 @@ $total_revenue = $pdo->query("SELECT SUM(total_fee) FROM patients WHERE status =
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.getElementById('patientSearch').addEventListener('input', function() {
const searchTerm = this.value;
const resultsContainer = document.getElementById('searchResults');
if (searchTerm.length < 2) {
resultsContainer.innerHTML = '';
resultsContainer.style.display = 'none';
return;
}
fetch(`search_patient.php?term=${encodeURIComponent(searchTerm)}`)
.then(response => response.json())
.then(data => {
resultsContainer.innerHTML = '';
if (data.length > 0) {
data.forEach(patient => {
const patientLink = document.createElement('a');
patientLink.href = `patient_profile.php?id=${patient.id}`;
patientLink.textContent = `${patient.patient_name} (${patient.patient_id})`;
resultsContainer.appendChild(patientLink);
});
resultsContainer.style.display = 'block';
} else {
resultsContainer.innerHTML = '<a href="#" class="disabled">No patients found</a>';
resultsContainer.style.display = 'block';
}
})
.catch(error => {
console.error('Error:', error);
resultsContainer.innerHTML = '<a href="#" class="disabled">Search error</a>';
resultsContainer.style.display = 'block';
});
});
// Hide results when clicking outside
document.addEventListener('click', function(e) {
const searchContainer = document.querySelector('.search-container');
if (searchContainer && !searchContainer.contains(e.target)) {
const resultsContainer = document.getElementById('searchResults');
if (resultsContainer) {
resultsContainer.style.display = 'none';
}
}
});
</script>
</body>
</html>

13
search_patient.php Normal file
View File

@ -0,0 +1,13 @@
<?php
require_once 'db/config.php';
if (isset($_GET['term'])) {
$term = $_GET['term'];
$pdo = db();
$stmt = $pdo->prepare('SELECT id, patient_id, patient_name FROM patients WHERE patient_name LIKE :term OR patient_id LIKE :term LIMIT 10');
$stmt->execute(['term' => '%' . $term . '%']);
$patients = $stmt->fetchAll(PDO::FETCH_ASSOC);
header('Content-Type: application/json');
echo json_encode($patients);
}
?>