Files
2026-09-16 23:20:08 +07:00

597 lines
33 KiB
PHP

<?php
// views/jobs/staff.php
?>
<div class="mb-6 flex justify-between items-center">
<div>
<h2 class="text-2xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-emerald-600 to-teal-400 dark:from-emerald-400 dark:to-teal-200">งานของฉัน</h2>
<p class="text-slate-500 dark:text-slate-400 text-sm">รายการงานเปลที่คุณได้รับมอบหมาย</p>
</div>
<button onclick="openMapModal()" class="bg-white/80 dark:bg-slate-800/80 hover:bg-white dark:hover:bg-slate-700 border border-slate-200 dark:border-slate-700 shadow-sm text-slate-700 dark:text-slate-300 px-4 py-2 rounded-xl text-sm font-medium transition-all backdrop-blur-sm">
<i class="fa-solid fa-map-location-dot text-emerald-500 mr-2"></i> แผนผังตึก
</button>
</div>
<div id="jobContainer">
<div class="glass-card p-8 text-center text-slate-500 flex flex-col items-center justify-center min-h-[300px]">
<i class="fa-solid fa-spinner fa-spin text-4xl mb-4 text-emerald-500"></i>
<p>กำลังตรวจสอบงาน...</p>
</div>
</div>
<!-- Signature & QR Modal (Tailwind version) -->
<div id="signatureModal" class="fixed inset-0 z-[100] hidden">
<!-- Backdrop -->
<div class="fixed inset-0 bg-slate-900/60 backdrop-blur-sm transition-opacity"></div>
<!-- Modal Content -->
<div class="fixed inset-0 z-10 overflow-y-auto">
<div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<div class="relative transform overflow-hidden rounded-2xl bg-white dark:bg-slate-800 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg border border-slate-200 dark:border-slate-700">
<div class="bg-emerald-600 px-4 py-3 sm:px-6 flex justify-between items-center">
<h3 class="text-base font-semibold leading-6 text-white">ยืนยันการส่งผู้ป่วย</h3>
<button type="button" class="text-white hover:text-emerald-100 close-modal">
<i class="fa-solid fa-xmark text-xl"></i>
</button>
</div>
<div class="px-4 pb-4 pt-5 sm:p-6 sm:pb-4 text-center">
<h6 class="text-sm font-medium text-slate-700 dark:text-slate-300 mb-3">แสกน QR Code เพื่อดูประวัติ</h6>
<div id="qrcode" class="mb-4 flex justify-center bg-white p-2 rounded-lg inline-block mx-auto"></div>
<div class="mt-4 pt-4 border-t border-slate-200 dark:border-slate-700">
<h6 class="text-sm font-medium text-slate-700 dark:text-slate-300 mb-3">ลายเซ็นพยาบาลผู้รับ (Digital Signature)</h6>
<div class="bg-slate-50 dark:bg-slate-900 rounded-xl p-1 border border-slate-200 dark:border-slate-700">
<canvas id="signature-pad" class="w-full h-48 rounded-lg cursor-crosshair touch-none"></canvas>
</div>
</div>
</div>
<div class="bg-slate-50 dark:bg-slate-700/50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<button type="button" class="inline-flex w-full justify-center rounded-xl bg-emerald-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-emerald-500 sm:ml-3 sm:w-auto transition-colors" id="saveSignature">
บันทึกและปิดงาน
</button>
<button type="button" class="mt-3 inline-flex w-full justify-center rounded-xl bg-white dark:bg-slate-800 px-3 py-2 text-sm font-semibold text-slate-900 dark:text-slate-200 shadow-sm ring-1 ring-inset ring-slate-300 dark:ring-slate-600 hover:bg-slate-50 dark:hover:bg-slate-700 sm:mt-0 sm:w-auto transition-colors" id="clearSignature">
ล้างลายเซ็น
</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/signature_pad@4.1.5/dist/signature_pad.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
let currentJob = null;
let signaturePad = null;
let qrGeneratedFor = null;
const modal = document.getElementById('signatureModal');
// Init Signature Pad
const canvas = document.getElementById('signature-pad');
signaturePad = new SignaturePad(canvas, {
backgroundColor: 'rgba(255, 255, 255, 0)'
});
function resizeCanvas() {
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
canvas.getContext("2d").scale(ratio, ratio);
signaturePad.clear();
}
window.addEventListener("resize", resizeCanvas);
document.querySelectorAll('.close-modal').forEach(btn => {
btn.addEventListener('click', () => modal.classList.add('hidden'));
});
document.getElementById('clearSignature').addEventListener('click', () => {
signaturePad.clear();
});
function fetchActiveJob() {
$.ajax({
url: 'api/jobs.php',
type: 'GET',
data: { action: 'get_active_job' },
dataType: 'json',
success: function(res) {
if (res.status === 'success' && res.data) {
currentJob = res.data;
renderJob(currentJob);
} else {
renderNoJob();
}
},
error: function() {
renderNoJob(true);
}
});
}
function renderNoJob(isError = false) {
currentJob = null;
const msg = isError ? 'เกิดข้อผิดพลาดในการดึงข้อมูล' : 'ขณะนี้คุณยังไม่มีงานที่ได้รับมอบหมาย';
const icon = isError ? 'fa-triangle-exclamation text-red-500' : 'fa-check-circle text-emerald-500';
document.getElementById('jobContainer').innerHTML = `
<div class="glass-card p-8 text-center text-slate-500 flex flex-col items-center justify-center min-h-[300px]">
<div class="w-16 h-16 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center mb-4 text-3xl">
<i class="fa-solid ${icon}"></i>
</div>
<h3 class="text-xl font-medium text-slate-800 dark:text-white mb-2">${msg}</h3>
<p class="text-sm">ระบบจะแจ้งเตือนเมื่อมีงานใหม่เข้ามา</p>
<button onclick="location.reload()" class="mt-6 btn-secondary-glass px-6 py-2">
<i class="fa-solid fa-rotate-right me-2"></i> รีเฟรช
</button>
</div>
`;
}
function renderJob(job) {
let statusBadge = '';
let btnArrivedDisabled = '';
let btnPickedUpDisabled = 'opacity-50 cursor-not-allowed" disabled';
let btnCompletedDisabled = 'opacity-50 cursor-not-allowed" disabled';
let btnArrivedClass = 'btn-secondary-glass';
let btnPickedUpClass = 'btn-secondary-glass';
let btnArrivedText = '<i class="fa-solid fa-person-walking-arrow-right me-2"></i> ถึงจุดรับผู้ป่วย';
let btnPickedUpText = '<i class="fa-solid fa-bed-pulse me-2"></i> รับผู้ป่วยขึ้นเปล';
if (job.status === 'assigned') {
statusBadge = '<span class="bg-blue-100 text-blue-800 dark:bg-blue-900/50 dark:text-blue-300 text-xs font-semibold px-2.5 py-0.5 rounded border border-blue-200 dark:border-blue-800">กำลังเดินทางไปรับ</span>';
} else if (job.status === 'accepted') {
statusBadge = '<span class="bg-indigo-100 text-indigo-800 dark:bg-indigo-900/50 dark:text-indigo-300 text-xs font-semibold px-2.5 py-0.5 rounded border border-indigo-200 dark:border-indigo-800">ถึงจุดรับผู้ป่วยแล้ว</span>';
btnArrivedDisabled = 'opacity-50 cursor-not-allowed" disabled';
btnArrivedClass = 'bg-emerald-100 text-emerald-700 border-emerald-200';
btnArrivedText = '<i class="fa-solid fa-check me-2"></i> ถึงจุดรับแล้ว';
btnPickedUpDisabled = '';
} else if (job.status === 'in_progress') {
statusBadge = '<span class="bg-amber-100 text-amber-800 dark:bg-amber-900/50 dark:text-amber-300 text-xs font-semibold px-2.5 py-0.5 rounded border border-amber-200 dark:border-amber-800">กำลังเดินทางไปส่ง</span>';
btnArrivedDisabled = 'opacity-50 cursor-not-allowed" disabled';
btnArrivedClass = 'bg-emerald-100 text-emerald-700 border-emerald-200';
btnArrivedText = '<i class="fa-solid fa-check me-2"></i> ถึงจุดรับแล้ว';
btnPickedUpDisabled = 'opacity-50 cursor-not-allowed" disabled';
btnPickedUpClass = 'bg-emerald-100 text-emerald-700 border-emerald-200';
btnPickedUpText = '<i class="fa-solid fa-check me-2"></i> รับผู้ป่วยแล้ว';
btnCompletedDisabled = '';
} else if (job.status === 'waiting_for_return') {
statusBadge = '<span class="bg-blue-100 text-blue-800 dark:bg-blue-900/50 dark:text-blue-300 text-xs font-semibold px-2.5 py-0.5 rounded border border-blue-200 dark:border-blue-800">กำลังรอรับกลับ</span>';
btnArrivedDisabled = 'opacity-50 cursor-not-allowed" disabled';
btnArrivedClass = 'bg-emerald-100 text-emerald-700 border-emerald-200';
btnArrivedText = '<i class="fa-solid fa-check me-2"></i> ถึงจุดรับแล้ว';
btnPickedUpDisabled = 'opacity-50 cursor-not-allowed" disabled';
btnPickedUpClass = 'bg-emerald-100 text-emerald-700 border-emerald-200';
btnPickedUpText = '<i class="fa-solid fa-check me-2"></i> รับผู้ป่วยแล้ว';
btnCompletedDisabled = '';
}
let equipmentIcon = job.equipment_icon || 'fa-wheelchair';
let equipmentName = job.equipment_name || job.equipment_type.toUpperCase();
const html = `
<div class="glass-card mb-8 border-l-4 border-${job.priority_color}-500" id="activeJobCard">
<div class="px-6 py-4 border-b border-emerald-500/20 bg-emerald-50/50 dark:bg-emerald-900/20 rounded-t-2xl flex justify-between items-center">
<h5 class="font-bold text-emerald-700 dark:text-emerald-400 m-0 flex items-center">
<span class="relative flex h-3 w-3 mr-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-emerald-500"></span>
</span>
งานที่กำลังดำเนินการ (Active)
</h5>
<div class="flex items-center gap-2">
${job.is_round_trip == 1 ? '<span class="bg-purple-100 text-purple-800 dark:bg-purple-900/50 dark:text-purple-300 text-xs font-bold px-2 py-1 rounded-full"><i class="fa-solid fa-rotate-left me-1"></i> ไป-กลับ</span>' : ''}
<button onclick="openChatModal(${job.id}, '${job.job_number}')" class="bg-blue-100 hover:bg-blue-200 text-blue-700 p-2 rounded-full transition-colors" title="แชทกับจุดรับ">
<i class="fa-solid fa-comment-dots"></i>
</button>
${statusBadge}
</div>
</div>
<div class="p-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<div class="flex justify-between items-start mb-4">
<div>
<p class="text-sm text-slate-500 dark:text-slate-400 mb-1">หมายเลขงาน</p>
<h4 class="text-xl font-bold text-slate-800 dark:text-white">${job.job_number}</h4>
</div>
<span class="bg-${job.priority_color}-100 text-${job.priority_color}-800 text-xs font-medium px-2.5 py-0.5 rounded border border-${job.priority_color}-200">${job.priority_name}</span>
</div>
<p class="text-sm text-slate-500 dark:text-slate-400 mb-1">ชื่อผู้ป่วย / รูปถ่าย</p>
${job.patient_image ? `<div class="mb-3"><img src="${job.patient_image}" class="w-full max-w-[200px] h-auto rounded-lg border border-slate-200 shadow-sm object-cover" alt="รูปผู้เรียก"></div>` : ''}
<p class="text-lg font-medium text-slate-800 dark:text-white mb-4">${job.patient_name || 'ไม่ระบุชื่อ (ดูรูปภาพ)'} ${job.patient_hn ? '(HN: ' + job.patient_hn + ')' : ''}</p>
${job.infection_control == 1 ? '<div class="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-2 rounded-lg flex items-center shadow-lg animate-pulse"><i class="fa-solid fa-biohazard text-xl mr-2"></i><span class="font-bold">ผู้ป่วยโรคติดต่อ / แยกกักโรค โปรดสวม PPE</span></div>' : ''}
<p class="text-sm text-slate-500 dark:text-slate-400 mb-1">อุปกรณ์</p>
<p class="font-medium text-slate-800 dark:text-white"><i class="fa-solid ${equipmentIcon} text-emerald-500 me-2"></i> ${equipmentName}</p>
</div>
<div class="bg-slate-50/50 dark:bg-slate-800/50 p-4 rounded-xl border border-slate-200 dark:border-slate-700">
<h6 class="font-semibold text-slate-700 dark:text-slate-300 mb-3 border-b border-slate-200 dark:border-slate-700 pb-2">เส้นทาง (Route)</h6>
<div class="flex items-center mb-4">
<div class="w-8 h-8 rounded-full bg-red-100 dark:bg-red-900/50 text-red-600 dark:text-red-400 flex items-center justify-center font-bold z-10">A</div>
<div class="ml-4">
<p class="text-xs text-slate-500 dark:text-slate-400">รับที่ (From)</p>
<p class="font-bold text-slate-800 dark:text-white">${job.from_department_name}</p>
</div>
</div>
<div class="relative ml-4 border-l-2 border-dashed border-slate-300 dark:border-slate-600 h-6 -my-4 z-0"></div>
<div class="flex items-center mt-4">
<div class="w-8 h-8 rounded-full bg-green-100 dark:bg-green-900/50 text-green-600 dark:text-green-400 flex items-center justify-center font-bold z-10">B</div>
<div class="ml-4">
<p class="text-xs text-slate-500 dark:text-slate-400">ส่งที่ (To)</p>
<p class="font-bold text-slate-800 dark:text-white">${job.to_department_name || job.to_department_custom}</p>
</div>
</div>
</div>
</div>
<div class="mt-8 pt-6 border-t border-slate-200 dark:border-slate-700">
<h6 class="font-medium text-slate-700 dark:text-slate-300 mb-4">อัปเดตสถานะงาน (Actions)</h6>
<div class="flex flex-col sm:flex-row gap-3">
<button class="flex-1 py-3 px-4 font-medium ${btnArrivedClass} ${btnArrivedDisabled}" id="btnArrived" onclick="updateJobStatus('accepted')">
${btnArrivedText}
</button>
<button class="flex-1 py-3 px-4 font-medium ${btnPickedUpClass} ${btnPickedUpDisabled}" id="btnPickedUp" onclick="updateJobStatus('in_progress')">
${btnPickedUpText}
</button>
${job.is_round_trip == 1 && job.status === 'in_progress' ?
`<button class="btn-primary-glass flex-1 py-3 px-4 font-medium ${btnCompletedDisabled}" id="btnWaitReturn" onclick="updateJobStatus('waiting_for_return')">
<i class="fa-solid fa-clock me-2"></i> รอรับกลับ
</button>` :
`<button class="btn-primary-glass flex-1 py-3 px-4 font-medium ${btnCompletedDisabled}" id="btnCompleted" onclick="openSignatureModal()">
<i class="fa-solid fa-check-double me-2"></i> ${job.status === 'waiting_for_return' ? 'ส่งกลับเรียบร้อย' : 'ส่งผู้ป่วยเรียบร้อย'}
</button>`}
</div>
<div class="mt-3">
<button class="w-full py-2 px-4 font-medium bg-white/50 dark:bg-slate-800 border border-red-200 dark:border-red-900/50 text-red-500 hover:bg-red-50 dark:hover:bg-red-900/30 rounded-xl transition-colors shadow-sm" onclick="promptCancelJob('${job.job_number}')">
<i class="fa-solid fa-times-circle me-1"></i> ปฏิเสธ/ยกเลิกงาน (พบปัญหาระหว่างงาน)
</button>
</div>
</div>
</div>
</div>
`;
document.getElementById('jobContainer').innerHTML = html;
}
window.updateJobStatus = function(newStatus) {
if (!currentJob) return;
$.ajax({
url: 'api/jobs.php',
type: 'POST',
data: {
action: 'update_status',
job_id: currentJob.job_number,
status: newStatus
},
dataType: 'json',
success: function(res) {
if (res.status === 'success') {
// Refetch job to update UI
fetchActiveJob();
} else {
Swal.fire('ผิดพลาด', res.message, 'error');
}
}
});
}
window.promptCancelJob = function(jobNumber) {
Swal.fire({
title: 'ปฏิเสธ/ยกเลิกงาน',
input: 'text',
inputLabel: 'โปรดระบุเหตุผลที่ยกเลิกงาน (เช่น ผู้ป่วยปฏิเสธ, หาผู้ป่วยไม่พบ)',
inputPlaceholder: 'พิมพ์เหตุผลที่นี่...',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#ef4444',
cancelButtonColor: '#94a3b8',
confirmButtonText: 'ยืนยันยกเลิก',
cancelButtonText: 'ปิด',
inputValidator: (value) => {
if (!value) {
return 'กรุณาระบุเหตุผล!';
}
}
}).then((result) => {
if (result.isConfirmed) {
Swal.showLoading();
$.ajax({
url: 'api/jobs.php',
type: 'POST',
data: {
action: 'cancel_job',
job_id: jobNumber,
reason: result.value
},
dataType: 'json',
success: function(res) {
if (res.status === 'success') {
Swal.fire({
title: 'สำเร็จ!',
text: 'ยกเลิกงานเรียบร้อยแล้ว',
icon: 'success',
timer: 1500,
showConfirmButton: false
}).then(() => {
fetchActiveJob(); // Will show no jobs UI
});
} else {
Swal.fire('ข้อผิดพลาด', res.message, 'error');
}
},
error: function() {
Swal.fire('ข้อผิดพลาด', 'ไม่สามารถติดต่อเซิร์ฟเวอร์ได้', 'error');
}
});
}
});
}
window.openSignatureModal = function() {
if (!currentJob) return;
modal.classList.remove('hidden');
resizeCanvas();
const qrContainer = document.getElementById('qrcode');
if (qrGeneratedFor !== currentJob.job_number) {
qrContainer.innerHTML = "";
new QRCode(qrContainer, {
text: window.location.origin + window.location.pathname + "?page=job_detail&id=" + currentJob.job_number,
width: 128,
height: 128,
colorDark : "#0f172a",
colorLight : "#ffffff",
});
qrGeneratedFor = currentJob.job_number;
}
}
document.getElementById('saveSignature').addEventListener('click', function() {
if (signaturePad.isEmpty()) {
Swal.fire({
title: 'แจ้งเตือน',
text: 'กรุณาเซ็นชื่อรับผู้ป่วย',
icon: 'warning',
background: document.documentElement.classList.contains('dark') ? '#1e293b' : '#fff',
color: document.documentElement.classList.contains('dark') ? '#f1f5f9' : '#1e293b'
});
return;
}
const dataURL = signaturePad.toDataURL('image/png');
const formData = new FormData();
formData.append('action', 'save_signature');
formData.append('job_id', currentJob.job_number);
formData.append('signature', dataURL);
const btn = $(this);
const originalText = btn.html();
btn.html('<i class="fa-solid fa-spinner fa-spin"></i>').prop('disabled', true);
fetch('api/jobs.php', {
method: 'POST',
body: formData
}).then(res => res.json()).then(data => {
btn.html(originalText).prop('disabled', false);
if (data.status === 'success') {
modal.classList.add('hidden');
Swal.fire({
title: 'เสร็จสิ้น',
text: 'ปิดงานและบันทึกลายเซ็นเรียบร้อย',
icon: 'success',
background: document.documentElement.classList.contains('dark') ? '#1e293b' : '#fff',
color: document.documentElement.classList.contains('dark') ? '#f1f5f9' : '#1e293b'
}).then(() => {
fetchActiveJob(); // Should return No Job
});
} else {
Swal.fire('ผิดพลาด', data.message, 'error');
}
}).catch(err => {
btn.html(originalText).prop('disabled', false);
Swal.fire('ผิดพลาด', 'เกิดข้อผิดพลาดในการเชื่อมต่อ', 'error');
});
});
// Start fetching
fetchActiveJob();
});
// Chat Functions
let chatInterval;
function openChatModal(jobId, jobNumber) {
document.getElementById('chat_job_id').value = jobId;
document.getElementById('chatJobNumber').textContent = jobNumber;
document.getElementById('chatModal').classList.remove('hidden');
loadChatMessages();
chatInterval = setInterval(loadChatMessages, 3000);
}
function closeChatModal() {
document.getElementById('chatModal').classList.add('hidden');
clearInterval(chatInterval);
}
function loadChatMessages() {
const jobId = document.getElementById('chat_job_id').value;
fetch(`api/chat.php?action=get_messages&job_id=${jobId}`)
.then(res => res.json())
.then(res => {
if (res.status === 'success') {
const chatBox = document.getElementById('chatBox');
let html = '';
res.data.forEach(msg => {
const isMe = msg.user_id == <?= $_SESSION['user_id'] ?>;
if (isMe) {
html += `
<div class="flex justify-end mb-3">
<div class="bg-emerald-500 text-white rounded-l-xl rounded-br-xl px-4 py-2 max-w-[80%] shadow-sm">
<p class="text-sm">${msg.message}</p>
<p class="text-[10px] text-emerald-100 text-right mt-1">${new Date(msg.created_at).toLocaleTimeString('th-TH', {hour: '2-digit', minute:'2-digit'})}</p>
</div>
</div>`;
} else {
html += `
<div class="flex justify-start mb-3">
<div class="bg-white dark:bg-slate-700 text-slate-800 dark:text-white rounded-r-xl rounded-bl-xl px-4 py-2 max-w-[80%] shadow-sm border border-slate-100 dark:border-slate-600">
<p class="text-xs text-slate-500 dark:text-slate-400 font-bold mb-1">${msg.full_name || 'ผู้ใช้งาน'}</p>
<p class="text-sm">${msg.message}</p>
<p class="text-[10px] text-slate-400 text-right mt-1">${new Date(msg.created_at).toLocaleTimeString('th-TH', {hour: '2-digit', minute:'2-digit'})}</p>
</div>
</div>`;
}
});
chatBox.innerHTML = html;
chatBox.scrollTop = chatBox.scrollHeight;
}
});
}
function sendChatMessage() {
const jobId = document.getElementById('chat_job_id').value;
const input = document.getElementById('chatInput');
const message = input.value.trim();
if (!message) return;
input.value = '';
fetch('api/chat.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `action=send_message&job_id=${jobId}&message=${encodeURIComponent(message)}`
}).then(() => loadChatMessages());
}
// Map Functions
let hospitalMapsData = [];
function openMapModal() {
document.getElementById('mapModal').classList.remove('hidden');
loadHospitalMaps();
}
function closeMapModal() {
document.getElementById('mapModal').classList.add('hidden');
}
function loadHospitalMaps() {
fetch('api/maps.php?action=list&status=active')
.then(res => res.json())
.then(res => {
if (res.status === 'success') {
hospitalMapsData = res.data;
const selector = document.getElementById('mapSelector');
if (hospitalMapsData.length === 0) {
selector.innerHTML = '<option value="">ไม่มีข้อมูลแผนผังในระบบ</option>';
selector.disabled = true;
showMapDetails(null);
return;
}
selector.disabled = false;
let html = '<option value="">-- เลือกอาคารและชั้น --</option>';
hospitalMapsData.forEach(map => {
html += `<option value="${map.id}">${map.name} (${map.building} ชั้น ${map.floor})</option>`;
});
selector.innerHTML = html;
// Auto select first map if available
if(hospitalMapsData.length > 0) {
selector.value = hospitalMapsData[0].id;
showMapDetails(hospitalMapsData[0].id);
}
}
});
}
function showMapDetails(mapId) {
const container = document.getElementById('mapImageContainer');
const locText = document.getElementById('mapTransportLocationText');
const locBox = document.getElementById('mapTransportLocationBox');
if (!mapId) {
container.innerHTML = '<div class="text-slate-500 py-12 text-center w-full">กรุณาเลือกแผนผังที่ต้องการดู</div>';
locBox.classList.add('hidden');
return;
}
const map = hospitalMapsData.find(m => m.id == mapId);
if (map) {
container.innerHTML = `<img src="${map.image_path}" alt="${map.name}" class="max-w-full rounded shadow-sm border border-slate-200 dark:border-slate-700 animate-fade-in">`;
if (map.transport_center_location) {
locText.textContent = map.transport_center_location;
locBox.classList.remove('hidden');
} else {
locBox.classList.add('hidden');
}
}
}
</script>
<!-- Chat Modal -->
<div id="chatModal" class="hidden fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/50 backdrop-blur-sm">
<div class="bg-slate-50 dark:bg-slate-800 w-full max-w-md rounded-2xl shadow-2xl flex flex-col h-[600px] max-h-[90vh] animate-fade-in-up border border-slate-200 dark:border-slate-700 overflow-hidden">
<div class="bg-emerald-600 px-4 py-3 flex justify-between items-center text-white">
<h3 class="font-bold flex items-center">
<i class="fa-solid fa-comments me-2"></i> แชทงาน <span id="chatJobNumber" class="ml-2 bg-emerald-500 px-2 py-0.5 rounded text-sm"></span>
</h3>
<button onclick="closeChatModal()" class="text-white hover:text-emerald-200"><i class="fa-solid fa-xmark text-xl"></i></button>
</div>
<input type="hidden" id="chat_job_id">
<div id="chatBox" class="flex-1 p-4 overflow-y-auto bg-slate-100 dark:bg-slate-900/50 flex flex-col gap-1">
<!-- Messages will be loaded here -->
</div>
<div class="p-3 bg-white dark:bg-slate-800 border-t border-slate-200 dark:border-slate-700 flex gap-2">
<input type="text" id="chatInput" class="flex-1 bg-slate-100 dark:bg-slate-900 border-none rounded-full px-4 py-2 text-sm focus:ring-2 focus:ring-emerald-500 dark:text-white" placeholder="พิมพ์ข้อความ..." onkeypress="if(event.key === 'Enter') sendChatMessage()">
<button onclick="sendChatMessage()" class="bg-emerald-500 hover:bg-emerald-600 text-white w-10 h-10 rounded-full flex items-center justify-center transition-colors shadow-sm">
<i class="fa-solid fa-paper-plane text-sm"></i>
</button>
</div>
</div>
</div>
<!-- Map Modal -->
<div id="mapModal" class="hidden fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/80 backdrop-blur-sm">
<div class="bg-white dark:bg-slate-800 w-full max-w-4xl rounded-2xl shadow-2xl flex flex-col max-h-[90vh] animate-fade-in-up overflow-hidden">
<div class="px-6 py-4 border-b border-slate-200 dark:border-slate-700 flex flex-col sm:flex-row justify-between items-start sm:items-center bg-slate-50 dark:bg-slate-800/50 gap-4">
<h3 class="font-bold text-slate-800 dark:text-white flex items-center text-lg whitespace-nowrap">
<i class="fa-solid fa-map-location-dot text-emerald-500 me-2"></i> แผนผังอาคารโรงพยาบาล
</h3>
<div class="flex items-center w-full sm:w-auto gap-3">
<select id="mapSelector" class="glass-input px-4 py-2 w-full sm:w-64 bg-white dark:bg-slate-900" onchange="showMapDetails(this.value)">
<option value="">กำลังโหลด...</option>
</select>
<button onclick="closeMapModal()" class="text-slate-500 hover:text-slate-700 dark:hover:text-white bg-slate-200 dark:bg-slate-700 w-10 h-10 rounded-xl flex items-center justify-center shrink-0"><i class="fa-solid fa-xmark"></i></button>
</div>
</div>
<div id="mapTransportLocationBox" class="bg-blue-50 dark:bg-blue-900/30 border-b border-blue-100 dark:border-blue-800 px-6 py-3 hidden">
<p class="text-blue-800 dark:text-blue-300 font-medium flex items-center text-sm">
<i class="fa-solid fa-location-crosshairs text-blue-500 mr-2"></i>
<strong>จุดประจำศูนย์เปล / จุดพักคอย:&nbsp;</strong> <span id="mapTransportLocationText"></span>
</p>
</div>
<div class="p-4 flex-1 overflow-auto bg-slate-100 dark:bg-slate-900 flex justify-center items-center" id="mapImageContainer">
<!-- Map Image -->
<div class="text-slate-500 py-12 text-center w-full">กำลังโหลดข้อมูล...</div>
</div>
</div>
</div>