308 lines
21 KiB
PHP
308 lines
21 KiB
PHP
<?php
|
|
require_once 'includes/db.php';
|
|
require_once 'includes/auth.php';
|
|
requireLogin();
|
|
|
|
// Mock Data to match the screenshot exactly for 100% UI fidelity
|
|
$cases = [
|
|
[
|
|
'id' => '08-2569-0012',
|
|
'date' => '2026-07-15',
|
|
'time' => '09:15',
|
|
'shift' => 'เช้า',
|
|
'type' => 'EMS',
|
|
'cbd' => 'CBD-17',
|
|
'unit' => 'โรงพยาบาลเกาะสมุย',
|
|
'level' => 'ALS',
|
|
'transport' => 'ทางบก',
|
|
'triage' => ['phone' => 'red', 'scene' => 'red', 'er' => 'red'],
|
|
'person' => 'นายสมเกียรติ',
|
|
'person_shift' => 'เช้า',
|
|
'status' => 'ปิดเคส'
|
|
],
|
|
[
|
|
'id' => '08-2569-0013',
|
|
'date' => '2026-07-15',
|
|
'time' => '10:10',
|
|
'shift' => 'เช้า',
|
|
'type' => 'Refer',
|
|
'cbd' => 'CBD-20',
|
|
'unit' => 'โรงพยาบาลเกาะสมุย',
|
|
'level' => 'ALS',
|
|
'transport' => 'ทางน้ำ',
|
|
'triage' => ['phone' => 'red', 'scene' => 'yellow', 'er' => 'red'],
|
|
'person' => 'นายสมเกียรติ',
|
|
'person_shift' => 'เช้า',
|
|
'status' => 'ปรับปรุงข้อมูลแล้ว'
|
|
],
|
|
[
|
|
'id' => '08-2569-0014',
|
|
'date' => '2026-07-15',
|
|
'time' => '17:15',
|
|
'shift' => 'บ่าย',
|
|
'type' => 'EMS',
|
|
'cbd' => 'CBD-01',
|
|
'unit' => 'หน่วยกู้ชีพหน้าเมือง',
|
|
'level' => 'CLS',
|
|
'transport' => 'ทางบก',
|
|
'triage' => ['phone' => 'green', 'scene' => 'green', 'er' => 'green'],
|
|
'person' => 'นางสาวสุดารัตน์',
|
|
'person_shift' => 'บ่าย',
|
|
'status' => 'ค้างปรับปรุงข้อมูล'
|
|
],
|
|
];
|
|
|
|
// Offline Units Mock
|
|
$offline_units = [
|
|
[
|
|
'name' => 'หน่วยกู้ชีพละไม',
|
|
'reason' => 'เหตุผลชำรุด: ยางรถเสื่อมสภาพ/อยู่ระหว่างรออะไหล่ส่งซ่อม',
|
|
'datetime' => '2026-07-15 08:30 น.',
|
|
'user' => 'dispatcher1'
|
|
]
|
|
];
|
|
|
|
// Fetch Active Units from Database
|
|
$stmt = $pdo->query("SELECT id, name, level FROM units WHERE is_active = 1 ORDER BY sort_order ASC, id ASC");
|
|
$activeUnits = $stmt ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];
|
|
|
|
require_once 'includes/header.php';
|
|
?>
|
|
|
|
<div class="space-y-6 animate-fadeIn pb-10">
|
|
<!-- Top Filter Area -->
|
|
<div class="bg-white rounded-2xl p-4 md:p-5 shadow-sm border border-slate-100 flex flex-wrap gap-3 items-center justify-between">
|
|
<div class="flex flex-wrap items-center gap-2.5">
|
|
<div class="relative">
|
|
<i data-lucide="search" class="w-4 h-4 text-slate-400 absolute left-3 top-1/2 -translate-y-1/2"></i>
|
|
<input type="text" id="filter-search" placeholder="ค้นหาเลขสพฉ. / CBD / อาการ..." class="pl-9 pr-3.5 py-1.5 border border-slate-200 focus:border-indigo-500 rounded-xl text-xs outline-none bg-slate-50/50 hover:bg-white focus:bg-white w-48 lg:w-64 font-semibold transition-all">
|
|
</div>
|
|
<select id="filter-unit" class="py-1.5 px-3 border border-slate-200 rounded-xl text-xs font-bold text-slate-700 bg-white focus:ring-1 focus:ring-indigo-500 outline-none">
|
|
<option value="">-- หน่วยปฏิบัติการกู้ชีพทั้งหมด --</option>
|
|
<?php foreach($activeUnits as $u): ?>
|
|
<option value="<?php echo htmlspecialchars($u['name']); ?>"><?php echo htmlspecialchars($u['name']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<select id="filter-status" class="py-1.5 px-3 border border-slate-200 rounded-xl text-xs font-bold text-slate-700 bg-white focus:ring-1 focus:ring-indigo-500 outline-none">
|
|
<option value="">-- สถานะเคสทั้งหมด --</option>
|
|
<option value="ค้างปรับปรุงข้อมูล">❌ ค้างปรับปรุงข้อมูล</option>
|
|
<option value="ปรับปรุงข้อมูลแล้ว">🟡 ปรับปรุงข้อมูลแล้ว</option>
|
|
<option value="ปิดเคส">🟢 ปิดเคส</option>
|
|
</select>
|
|
</div>
|
|
<div class="text-xs font-bold bg-indigo-50 text-indigo-700 px-3.5 py-1.5 rounded-xl border border-indigo-100 self-end md:self-auto flex items-center gap-1.5">
|
|
<i data-lucide="filter" class="w-3.5 h-3.5"></i> <span id="filter-count">พบทั้งหมด <?= count($cases) ?> รายการสอดคล้อง</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Data Table Area -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden">
|
|
<div class="p-4 md:p-5 border-b border-slate-100 bg-slate-50/50 flex flex-col sm:flex-row sm:items-center justify-between gap-3">
|
|
<div>
|
|
<h3 class="text-base font-black text-slate-800">รายการรับเคสปฏิบัติการ ศูนย์นเรนทรอ่าวไทย</h3>
|
|
<p class="text-xs text-slate-500 mt-0.5 font-medium">รวมเคสฉุกเฉินกู้ชีพทุกลำดับ และผู้ประเมินสถานะการพยาบาลรับ-ส่งต่อ</p>
|
|
</div>
|
|
</div>
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-left border-collapse text-xs md:text-sm whitespace-nowrap lg:whitespace-normal">
|
|
<thead>
|
|
<tr class="bg-slate-50 text-slate-600 font-bold border-b border-slate-100">
|
|
<th class="py-3 px-4 uppercase tracking-wider">เลขปฏิบัติการ (สพฉ.)</th>
|
|
<th class="py-3 px-3 uppercase tracking-wider">ประเภทเคส</th>
|
|
<th class="py-3 px-3 uppercase tracking-wider">หน่วยงานกู้ชีพรับเหมา</th>
|
|
<th class="py-3 px-3 text-center uppercase tracking-wider">Triage (Phone/Scene/ER)</th>
|
|
<th class="py-3 px-3 uppercase tracking-wider">ผู้รับผิดชอบกู้ชีพ</th>
|
|
<th class="py-3 px-3 text-center uppercase tracking-wider">สถานะเคส</th>
|
|
<th class="py-3 px-4 text-center uppercase tracking-wider">การดำเนินการ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-100 text-slate-700 font-medium">
|
|
<?php foreach ($cases as $c): ?>
|
|
<tr class="hover:bg-slate-50/50 transition-colors case-row">
|
|
<td class="py-3.5 px-4">
|
|
<div class="font-extrabold text-slate-900 font-mono text-xs case-id"><?= $c['id'] ?></div>
|
|
<div class="text-[10px] text-slate-400 mt-0.5 font-bold">วันที่: <?= $c['date'] ?> | <?= $c['time'] ?> น. (เวร<?= $c['shift'] ?>)</div>
|
|
</td>
|
|
<td class="py-3.5 px-3">
|
|
<div class="flex flex-col gap-1 items-start">
|
|
<?php if($c['type'] === 'EMS'): ?>
|
|
<span class="px-2 py-0.5 rounded text-[10px] font-black tracking-wide border bg-blue-50 text-blue-600 border-blue-200">EMS</span>
|
|
<?php else: ?>
|
|
<span class="px-2 py-0.5 rounded text-[10px] font-black tracking-wide border bg-indigo-50 text-indigo-600 border-indigo-200">Refer</span>
|
|
<?php endif; ?>
|
|
<span class="text-[10px] text-slate-500 font-bold case-cbd"><?= $c['cbd'] ?></span>
|
|
</div>
|
|
</td>
|
|
<td class="py-3.5 px-3">
|
|
<div class="font-extrabold text-slate-800 text-xs case-unit"><?= $c['unit'] ?></div>
|
|
<div class="text-[10px] text-slate-400 mt-0.5 font-semibold">ระดับความพร้อม: <?= $c['level'] ?> | ลำเลียง: <?= $c['transport'] ?></div>
|
|
</td>
|
|
<td class="py-3.5 px-3 text-center">
|
|
<div class="flex items-center justify-center gap-1.5 font-black text-white" style="font-size: 10px;">
|
|
<?php
|
|
$getColor = function($color) {
|
|
if ($color === 'red') return '#e60000';
|
|
if ($color === 'yellow') return '#f59e0b';
|
|
if ($color === 'green') return '#009959';
|
|
return '#94a3b8'; // slate-400
|
|
};
|
|
?>
|
|
<div class="rounded flex items-center justify-center" style="width: 18px; height: 18px; background-color: <?= $getColor($c['triage']['phone']) ?>;" title="Phone Triage">P</div>
|
|
<span class="text-slate-200 font-normal" style="font-size: 10px;">/</span>
|
|
<div class="rounded flex items-center justify-center" style="width: 18px; height: 18px; background-color: <?= $getColor($c['triage']['scene']) ?>;" title="Scene Triage">S</div>
|
|
<span class="text-slate-200 font-normal" style="font-size: 10px;">/</span>
|
|
<div class="rounded flex items-center justify-center" style="width: 18px; height: 18px; background-color: <?= $getColor($c['triage']['er']) ?>;" title="ER Triage">E</div>
|
|
</div>
|
|
</td>
|
|
<td class="py-3.5 px-3">
|
|
<div class="font-extrabold text-slate-800 text-xs"><?= $c['person'] ?></div>
|
|
<div class="text-[10px] text-slate-400 mt-0.5 font-semibold">เวรรอบ: <?= $c['person_shift'] ?></div>
|
|
</td>
|
|
<td class="py-3.5 px-3 text-center case-status">
|
|
<?php if($c['status'] === 'ปิดเคส'): ?>
|
|
<span class="px-2.5 py-1 rounded-full text-[10px] font-bold border bg-emerald-50 text-emerald-600 border-emerald-200">ปิดเคส</span>
|
|
<?php elseif($c['status'] === 'ปรับปรุงข้อมูลแล้ว'): ?>
|
|
<span class="px-2.5 py-1 rounded-full text-[10px] font-bold border bg-amber-50 text-amber-600 border-amber-200">ปรับปรุงข้อมูลแล้ว</span>
|
|
<?php else: ?>
|
|
<span class="px-2.5 py-1 rounded-full text-[10px] font-bold border bg-rose-50 text-rose-600 border-rose-200">ค้างปรับปรุงข้อมูล</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="py-3.5 px-4 text-center">
|
|
<button class="flex items-center justify-center gap-1.5 border border-slate-200 hover:border-indigo-300 text-slate-600 hover:text-indigo-600 hover:bg-indigo-50 font-bold text-[10px] px-3 py-1.5 rounded-xl transition-all mx-auto shadow-sm cursor-pointer">
|
|
<i data-lucide="edit-3" class="w-3.5 h-3.5"></i> แก้ไขข้อมูล
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="bg-slate-50 p-3 rounded-b-2xl border-t border-slate-100 text-[11px] font-bold text-slate-500 flex items-center gap-2">
|
|
<div class="w-6 h-6 rounded-full bg-amber-100 text-amber-600 flex items-center justify-center flex-shrink-0"><i data-lucide="info" class="w-3.5 h-3.5"></i></div>
|
|
เคล็ดลับปฏิบัติการ: ข้อมูลเคสจะถูกนำเข้าสู่ระบบบัญชี "หน้าเคสปฏิบัติการ" โดยอัตโนมัติ เพื่อให้ผู้รับผิดชอบ (Complete) และทีม ER ดำเนินการคัดแยกสี และปิดเคสอย่างละเอียด
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bottom Grids -->
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<!-- Report Readiness Form -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden">
|
|
<div class="p-5 border-b border-slate-100">
|
|
<h3 class="text-sm font-black text-rose-700 flex items-center gap-2">
|
|
<i data-lucide="alert-circle" class="w-5 h-5"></i> บันทึกรายงานระดับสถานะความพร้อมของหน่วยงานกู้ชีพ
|
|
</h3>
|
|
<p class="text-[10px] text-slate-500 mt-1 font-semibold">ระบบจะระงับการจ่ายงานหากหน่วยกู้ภัยในข่ายแจ้งไม่พร้อมปฏิบัติการ เช่น รอส่งซ่อมชั่วคราว</p>
|
|
</div>
|
|
<form class="p-5 space-y-4">
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-600 mb-1.5">เลือกหน่วยปฏิบัติการที่มีปัญหา</label>
|
|
<select class="w-full py-2 px-3 border border-slate-200 rounded-xl text-sm font-semibold text-slate-700 bg-white focus:ring-1 focus:ring-indigo-500 outline-none">
|
|
<option value="">-- เลือกหน่วยงานกู้ชีพ --</option>
|
|
<?php foreach($activeUnits as $u): ?>
|
|
<option value="<?php echo htmlspecialchars($u['id']); ?>"><?php echo htmlspecialchars($u['name'] . ' (' . $u['level'] . ')'); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-600 mb-1.5">คาดการณ์ระยะเวลาไม่พร้อมใช้ (ชั่วโมง)</label>
|
|
<input type="text" placeholder="เช่น 4, 12, 24" class="w-full py-2 px-3 border border-slate-200 rounded-xl text-sm font-semibold text-slate-700 bg-white focus:ring-1 focus:ring-indigo-500 outline-none">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-2">
|
|
<input type="checkbox" id="unknown_time" class="w-4 h-4 text-rose-600 rounded border-slate-300 focus:ring-rose-500">
|
|
<label for="unknown_time" class="text-xs font-bold text-slate-700 cursor-pointer select-none">ยังไม่ทราบเวลาสิ้นสุดกู้คืนความพร้อมแน่นอน</label>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-600 mb-1.5">ระบุเหตุผลขัดข้องความพร้อม</label>
|
|
<input type="text" placeholder="เช่น ยางรถเสื่อมชำรุดชั่วคราว, วิทยุโมบายล์พังควันขึ้น" class="w-full py-2 px-3 border border-slate-200 rounded-xl text-sm font-semibold text-slate-700 bg-white focus:ring-1 focus:ring-indigo-500 outline-none">
|
|
</div>
|
|
|
|
<button type="button" class="w-full bg-rose-600 hover:bg-rose-700 text-white font-black text-sm py-2.5 rounded-xl transition-all shadow-md shadow-rose-200/50 cursor-pointer">
|
|
ส่งแจ้งเตือน "ไม่พร้อมออกปฏิบัติการ" ขึ้น Dashboard EMS
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Offline Units Status -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden flex flex-col">
|
|
<div class="p-5 border-b border-slate-100 flex flex-col sm:flex-row justify-between items-start gap-2">
|
|
<div>
|
|
<h3 class="text-sm font-black text-slate-800">ขบวนกู้ภัยที่ยังไม่พร้อมปฏิบัติการ ณ ปัจจุบัน</h3>
|
|
<p class="text-[10px] text-slate-500 mt-1 font-semibold">อัปเดตแบบ Realtime ไปยัง Dashboard ผู้บริหารและพยาบาลนำส่ง</p>
|
|
</div>
|
|
<span class="bg-rose-100 text-rose-700 text-[10px] font-black px-2.5 py-1 rounded-full whitespace-nowrap self-start sm:self-auto">
|
|
1 หน่วยขัดข้อง
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex-1 p-5 overflow-y-auto min-h-[160px]">
|
|
<?php foreach($offline_units as $ou): ?>
|
|
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 border-b border-slate-50 pb-3 mb-3 last:border-0 last:pb-0 last:mb-0">
|
|
<div>
|
|
<div class="font-black text-slate-800 text-sm"><?= $ou['name'] ?></div>
|
|
<div class="text-[10px] font-bold text-rose-600 mt-1"><?= $ou['reason'] ?></div>
|
|
<div class="text-[10px] text-slate-400 mt-0.5 font-semibold">บันทึกเมื่อ: <?= $ou['datetime'] ?> | โดย: <?= $ou['user'] ?></div>
|
|
</div>
|
|
<button class="bg-emerald-50 hover:bg-emerald-100 text-emerald-600 border border-emerald-200 font-bold text-[10px] px-3 py-1.5 rounded-xl transition-all whitespace-nowrap self-end sm:self-auto cursor-pointer">
|
|
กลับคืนพร้อมปฏิบัติ
|
|
</button>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
|
|
<div class="bg-slate-50/50 p-4 border-t border-slate-100 text-[10px] font-bold text-slate-600 flex items-start gap-2">
|
|
<span class="text-amber-500 text-sm mt-0.5">⚠️</span>
|
|
<span>แจ้งฝ่ายนำรถ: หากปัญหาซ่อมบำรุงในรถพยาบาลได้รับการแก้ไขแล้ว กรุณากดปุ่ม "กลับคืนพร้อมปฏิบัติ" เพื่อล้างสถานะ Dashboard</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php require_once 'includes/footer.php'; ?>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const filterSearch = document.getElementById('filter-search');
|
|
const filterUnit = document.getElementById('filter-unit');
|
|
const filterStatus = document.getElementById('filter-status');
|
|
const filterCount = document.getElementById('filter-count');
|
|
const caseRows = document.querySelectorAll('.case-row');
|
|
|
|
function filterCases() {
|
|
const searchTerm = filterSearch.value.toLowerCase();
|
|
const unitTerm = filterUnit.value.toLowerCase();
|
|
const statusTerm = filterStatus.value.toLowerCase();
|
|
|
|
let visibleCount = 0;
|
|
|
|
caseRows.forEach(row => {
|
|
const idText = row.querySelector('.case-id').innerText.toLowerCase();
|
|
const cbdText = row.querySelector('.case-cbd').innerText.toLowerCase();
|
|
const unitText = row.querySelector('.case-unit').innerText.toLowerCase();
|
|
const statusText = row.querySelector('.case-status').innerText.toLowerCase();
|
|
|
|
// Match conditions
|
|
const matchesSearch = searchTerm === '' || idText.includes(searchTerm) || cbdText.includes(searchTerm);
|
|
const matchesUnit = unitTerm === '' || unitText.includes(unitTerm);
|
|
const matchesStatus = statusTerm === '' || statusText.includes(statusTerm);
|
|
|
|
if (matchesSearch && matchesUnit && matchesStatus) {
|
|
row.style.display = '';
|
|
visibleCount++;
|
|
} else {
|
|
row.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
filterCount.innerText = `พบทั้งหมด ${visibleCount} รายการสอดคล้อง`;
|
|
}
|
|
|
|
filterSearch.addEventListener('input', filterCases);
|
|
filterUnit.addEventListener('change', filterCases);
|
|
filterStatus.addEventListener('change', filterCases);
|
|
});
|
|
</script>
|