198 lines
10 KiB
PHP
198 lines
10 KiB
PHP
<?php
|
|
// views/search.php
|
|
require_once("../core/auth.php");
|
|
require_once("../config/db.php");
|
|
require_once("../core/utils.php");
|
|
|
|
$current_user = $_SESSION['account'] ?? '';
|
|
$can_search_by_name = can_search_name($current_user);
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="th">
|
|
<head>
|
|
<?php require_once("../components/head.php"); ?>
|
|
<meta name="csrf-token" content="<?php echo generate_csrf_token(); ?>">
|
|
<!-- jQuery & DataTables -->
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
|
|
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
|
|
<style>
|
|
/* Custom CSS to make DataTables look good with Tailwind */
|
|
.dataTables_wrapper .dataTables_length select, .dataTables_wrapper .dataTables_filter input {
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 0.5rem;
|
|
padding: 0.25rem 0.5rem;
|
|
outline: none;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.dataTables_wrapper .dataTables_length select:focus, .dataTables_wrapper .dataTables_filter input:focus {
|
|
border-color: #10b981;
|
|
box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
|
|
}
|
|
.dataTables_wrapper .dataTables_paginate .paginate_button {
|
|
border-radius: 0.5rem !important;
|
|
padding: 0.25rem 0.75rem !important;
|
|
margin: 0 0.125rem !important;
|
|
border: 1px solid transparent !important;
|
|
}
|
|
.dataTables_wrapper .dataTables_paginate .paginate_button.current {
|
|
background: #10b981 !important;
|
|
color: white !important;
|
|
border: none !important;
|
|
}
|
|
.dataTables_wrapper .dataTables_paginate .paginate_button:hover:not(.current) {
|
|
background: #f1f5f9 !important;
|
|
color: #334155 !important;
|
|
}
|
|
table.dataTable.no-footer {
|
|
border-bottom: 1px solid #f1f5f9;
|
|
}
|
|
table.dataTable thead th {
|
|
border-bottom: 1px solid #f1f5f9;
|
|
}
|
|
.dt-center {
|
|
text-align: center;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gradient-to-br from-emerald-50 to-emerald-100 text-slate-800 font-sans antialiased min-h-screen flex">
|
|
|
|
<?php require_once("../components/layout_sidebar.php"); ?>
|
|
|
|
<main class="flex-1 flex flex-col min-w-0">
|
|
<?php require_once("../components/layout_topbar.php"); ?>
|
|
|
|
<div class="p-4 md:p-8 lg:p-10 flex-1 overflow-y-auto">
|
|
<div class="max-w-5xl mx-auto">
|
|
<div class="glass-card p-5 md:p-8 animate-enter">
|
|
<div class="mb-8">
|
|
<h2 class="text-2xl font-bold flex items-center gap-3 text-slate-800">
|
|
<svg class="w-8 h-8 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
|
|
ค้นหาเวชระเบียนผู้รับบริการ
|
|
</h2>
|
|
<p class="text-slate-500 mt-2">กรุณาเลือกประเภทการค้นหา และระบุข้อมูลที่ต้องการ</p>
|
|
</div>
|
|
|
|
<form id="searchForm" class="flex flex-wrap gap-4 items-end mb-8">
|
|
<div class="min-w-[200px]">
|
|
<label class="block text-sm font-medium text-slate-700 mb-2">ประเภทการค้นหา</label>
|
|
<select id="searchType" class="form-input appearance-none bg-white">
|
|
<option value="hn">เลขที่เวชระเบียน (HN)</option>
|
|
<option value="cid">เลขบัตรประชาชน (CID)</option>
|
|
<option value="passport">เลขพาสปอร์ต (Passport)</option>
|
|
<?php if($can_search_by_name): ?>
|
|
<option value="name">ชื่อ - สกุล</option>
|
|
<?php endif; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="flex-1 min-w-[250px]">
|
|
<label class="block text-sm font-medium text-slate-700 mb-2">ระบุข้อมูลค้นหา</label>
|
|
<input type="text" id="searchQuery" class="form-input" placeholder="พิมพ์คำค้นหาที่นี่..." required>
|
|
</div>
|
|
|
|
<button type="submit" class="btn-primary w-full sm:w-auto ripple-wrapper h-[46px] px-8 sm:mb-[2px]">
|
|
ค้นหา
|
|
</button>
|
|
</form>
|
|
|
|
<div class="overflow-x-auto bg-white/50 rounded-2xl border border-white/60 p-4">
|
|
<table id="searchResultTable" class="w-full text-left border-collapse">
|
|
<thead>
|
|
<tr>
|
|
<th class="table-header w-20 text-center">ลำดับ</th>
|
|
<th class="table-header w-40 text-center">HN</th>
|
|
<th class="table-header text-center">ชื่อ - สกุล</th>
|
|
<th class="table-header w-48 text-center">เลขประจำตัว</th>
|
|
<th class="table-header w-32 !text-center">จัดการ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="resultBody">
|
|
<tr>
|
|
<td colspan="5" class="py-16 text-center">
|
|
<div class="flex flex-col items-center justify-center text-slate-400">
|
|
<svg class="w-12 h-12 mb-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16l2.879-2.879m0 0a3 3 0 104.243-4.242 3 3 0 00-4.243 4.242zM21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
|
<span>ผลการค้นหาจะแสดงที่นี่</span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php require_once("../components/layout_footer.php"); ?>
|
|
</main>
|
|
|
|
<script src="../assets/js/micro-interactions.js"></script>
|
|
<script>
|
|
// Change placeholder dynamically based on search type
|
|
document.getElementById('searchType').addEventListener('change', function(e) {
|
|
const input = document.getElementById('searchQuery');
|
|
if (e.target.value === 'name') {
|
|
input.placeholder = "พิมพ์ชื่อ หรือ ชื่อ สกุลเว้นวรรค (เช่น สมชาย หรือ สมชาย ใจดี)...";
|
|
} else {
|
|
input.placeholder = "พิมพ์คำค้นหาที่นี่...";
|
|
}
|
|
});
|
|
|
|
document.getElementById('searchForm').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
const type = document.getElementById('searchType').value;
|
|
const query = document.getElementById('searchQuery').value;
|
|
const resultBody = document.getElementById('resultBody');
|
|
|
|
resultBody.innerHTML = '<tr><td colspan="5" class="py-16 text-center text-emerald-600 font-medium animate-pulse">กำลังค้นหาข้อมูล...</td></tr>';
|
|
|
|
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
|
|
|
|
fetch('../core/search_action.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: `type=${encodeURIComponent(type)}&query=${encodeURIComponent(query)}&csrf_token=${encodeURIComponent(csrfToken)}`
|
|
})
|
|
.then(response => response.text())
|
|
.then(html => {
|
|
// Destroy existing DataTable if it exists
|
|
if ($.fn.DataTable.isDataTable('#searchResultTable')) {
|
|
$('#searchResultTable').DataTable().destroy();
|
|
}
|
|
|
|
resultBody.innerHTML = html;
|
|
|
|
// Only initialize DataTable if there are results (not showing error message)
|
|
if (html.indexOf('py-16 text-center') === -1) {
|
|
let dt = $('#searchResultTable').DataTable({
|
|
"pageLength": 10,
|
|
"lengthChange": false,
|
|
"language": {
|
|
"url": "//cdn.datatables.net/plug-ins/1.13.6/i18n/th.json"
|
|
},
|
|
"columnDefs": [
|
|
{ "className": "dt-center", "targets": "_all" },
|
|
{ "searchable": false, "orderable": false, "targets": [0, 4] }
|
|
],
|
|
"order": [[ 2, "asc" ]] // Sort by Name A-Z by default (column index 2)
|
|
});
|
|
|
|
// Re-calculate sequence numbers on sort or filter
|
|
dt.on('order.dt search.dt', function () {
|
|
let i = 1;
|
|
dt.cells(null, 0, { search: 'applied', order: 'applied' }).every(function (cell) {
|
|
this.data(i++);
|
|
});
|
|
}).draw();
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
resultBody.innerHTML = '<tr><td colspan="5" class="py-16 text-center text-red-500 font-medium">เกิดข้อผิดพลาดในการเชื่อมต่อ</td></tr>';
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|