748 lines
49 KiB
PHP
748 lines
49 KiB
PHP
<?php
|
|
require_once 'includes/db.php';
|
|
require_once 'includes/auth.php';
|
|
|
|
requireLogin();
|
|
|
|
// -----------------------------------------------------
|
|
// Backend Logic Processing
|
|
// -----------------------------------------------------
|
|
$success_msg = '';
|
|
$error_msg = '';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$action = $_POST['action'] ?? '';
|
|
|
|
if ($action === 'save_user') {
|
|
$user_id = $_POST['user_id'] ?? '';
|
|
$username = trim($_POST['username']);
|
|
$full_name = trim($_POST['full_name']);
|
|
$role = $_POST['role'];
|
|
$pin = trim($_POST['pin']);
|
|
$must_change_pin = isset($_POST['must_change_pin']) ? 1 : 0;
|
|
$is_active = isset($_POST['is_active']) ? 1 : 0;
|
|
|
|
$password = $_POST['password'] ?? '';
|
|
|
|
try {
|
|
if ($user_id) {
|
|
// Update
|
|
if (!empty($password)) {
|
|
$pw_hash = password_hash($password, PASSWORD_BCRYPT);
|
|
$stmt = $pdo->prepare("UPDATE users SET username=?, password=?, full_name=?, role=?, pin=?, must_change_pin=?, is_active=? WHERE id=?");
|
|
$stmt->execute([$username, $pw_hash, $full_name, $role, $pin, $must_change_pin, $is_active, $user_id]);
|
|
} else {
|
|
$stmt = $pdo->prepare("UPDATE users SET username=?, full_name=?, role=?, pin=?, must_change_pin=?, is_active=? WHERE id=?");
|
|
$stmt->execute([$username, $full_name, $role, $pin, $must_change_pin, $is_active, $user_id]);
|
|
}
|
|
$success_msg = "อัปเดตข้อมูลผู้ใช้เรียบร้อยแล้ว";
|
|
} else {
|
|
// Insert
|
|
$pw_hash = password_hash($password ?: '123456', PASSWORD_BCRYPT);
|
|
$stmt = $pdo->prepare("INSERT INTO users (username, password, full_name, role, pin, must_change_pin, is_active) VALUES (?, ?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([$username, $pw_hash, $full_name, $role, $pin, $must_change_pin, $is_active]);
|
|
$success_msg = "สร้างบัญชีผู้ใช้ใหม่เรียบร้อยแล้ว";
|
|
}
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาด: " . $e->getMessage();
|
|
}
|
|
}
|
|
elseif ($action === 'delete_user') {
|
|
$user_id = $_POST['user_id'] ?? '';
|
|
if ($user_id && $user_id != $_SESSION['user_id']) { // prevent deleting oneself
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM users WHERE id=?");
|
|
$stmt->execute([$user_id]);
|
|
$success_msg = "ลบบัญชีผู้ใช้เรียบร้อยแล้ว";
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาด: " . $e->getMessage();
|
|
}
|
|
} else {
|
|
$error_msg = "ไม่สามารถลบบัญชีนี้ได้";
|
|
}
|
|
}
|
|
elseif ($action === 'save_unit') {
|
|
$unit_id = $_POST['unit_id'] ?? '';
|
|
$unit_name = trim($_POST['unit_name']);
|
|
$level = $_POST['level'];
|
|
$sort_order = (int)$_POST['sort_order'];
|
|
$is_samui_hospital = isset($_POST['is_samui_hospital']) ? 1 : 0;
|
|
$is_active = isset($_POST['is_active']) ? 1 : 0;
|
|
|
|
try {
|
|
if ($unit_id) {
|
|
// Update
|
|
$stmt = $pdo->prepare("UPDATE units SET name=?, level=?, sort_order=?, is_samui_hospital=?, is_active=? WHERE id=?");
|
|
$stmt->execute([$unit_name, $level, $sort_order, $is_samui_hospital, $is_active, $unit_id]);
|
|
$success_msg = "อัปเดตข้อมูลหน่วยกู้ชีพเรียบร้อยแล้ว";
|
|
} else {
|
|
// Insert
|
|
$stmt = $pdo->prepare("INSERT INTO units (name, level, sort_order, is_samui_hospital, is_active) VALUES (?, ?, ?, ?, ?)");
|
|
$stmt->execute([$unit_name, $level, $sort_order, $is_samui_hospital, $is_active]);
|
|
$success_msg = "เพิ่มหน่วยกู้ภัยเครือข่ายใหม่เรียบร้อยแล้ว";
|
|
}
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาด: " . $e->getMessage();
|
|
}
|
|
}
|
|
elseif ($action === 'delete_unit') {
|
|
$unit_id = $_POST['unit_id'] ?? '';
|
|
if ($unit_id) {
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM units WHERE id=?");
|
|
$stmt->execute([$unit_id]);
|
|
$success_msg = "ลบหน่วยกู้ชีพเรียบร้อยแล้ว";
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาด: " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
elseif ($action === 'save_settings') {
|
|
$system_name = trim($_POST['system_name'] ?? '');
|
|
$footer_text = trim($_POST['footer_text'] ?? '');
|
|
|
|
try {
|
|
// Check if settings table exists
|
|
$pdo->query("SELECT 1 FROM settings LIMIT 1");
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('system_name', ?) ON DUPLICATE KEY UPDATE setting_value = ?");
|
|
$stmt->execute([$system_name, $system_name]);
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('footer_text', ?) ON DUPLICATE KEY UPDATE setting_value = ?");
|
|
$stmt->execute([$footer_text, $footer_text]);
|
|
|
|
$success_msg = "อัปเดตการตั้งค่าทั่วไปเรียบร้อยแล้ว";
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาด: กรุณารัน mockup_settings.sql เพื่อสร้างตาราง settings ก่อน";
|
|
}
|
|
}
|
|
|
|
elseif ($action === 'save_master_data') {
|
|
$id = $_POST['id'] ?? '';
|
|
$category = trim($_POST['category'] ?? '');
|
|
$item_value = trim($_POST['item_value'] ?? '');
|
|
$item_label = trim($_POST['item_label'] ?? '');
|
|
$sort_order = (int)($_POST['sort_order'] ?? 99);
|
|
$is_active = isset($_POST['is_active']) ? 1 : 0;
|
|
|
|
if ($category && $item_value && $item_label) {
|
|
try {
|
|
if ($id) {
|
|
$stmt = $pdo->prepare("UPDATE master_data SET category = ?, item_value = ?, item_label = ?, sort_order = ?, is_active = ? WHERE id = ?");
|
|
$stmt->execute([$category, $item_value, $item_label, $sort_order, $is_active, $id]);
|
|
$success_msg = "อัปเดตข้อมูลตัวเลือกเรียบร้อยแล้ว";
|
|
} else {
|
|
$stmt = $pdo->prepare("INSERT INTO master_data (category, item_value, item_label, sort_order, is_active) VALUES (?, ?, ?, ?, ?)");
|
|
$stmt->execute([$category, $item_value, $item_label, $sort_order, $is_active]);
|
|
$success_msg = "เพิ่มตัวเลือกใหม่เรียบร้อยแล้ว";
|
|
}
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาด: กรุณารัน mockup_master_data.sql เพื่อสร้างตาราง master_data ก่อน";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle GET actions for deletions
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action'])) {
|
|
$action = $_GET['action'];
|
|
if ($action === 'delete_master_data' && isset($_GET['id'])) {
|
|
try {
|
|
$stmt = $pdo->prepare("DELETE FROM master_data WHERE id = ?");
|
|
$stmt->execute([$_GET['id']]);
|
|
$success_msg = "ลบตัวเลือกเรียบร้อยแล้ว";
|
|
} catch (PDOException $e) {
|
|
$error_msg = "เกิดข้อผิดพลาดในการลบข้อมูล: " . $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------
|
|
// Fetch Data
|
|
// -----------------------------------------------------
|
|
$users = [];
|
|
$units = [];
|
|
|
|
try {
|
|
$stmt = $pdo->query("SELECT * FROM users ORDER BY id ASC");
|
|
if ($stmt) $users = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$stmt = $pdo->query("SELECT * FROM units ORDER BY sort_order ASC, id ASC");
|
|
if ($stmt) $units = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$master_data = [];
|
|
try {
|
|
$stmt = $pdo->query("SELECT * FROM master_data ORDER BY category ASC, sort_order ASC, id ASC");
|
|
if ($stmt) $master_data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {}
|
|
} catch (PDOException $e) {}
|
|
|
|
// Fetch settings
|
|
$system_name = getSetting($pdo, 'system_name', 'ระบบบริหารจัดการ ศูนย์รับแจ้งเหตุและสั่งการนเรนทรอ่าวไทย');
|
|
$footer_text = getSetting($pdo, 'footer_text', 'ศูนย์รับแจ้งเหตุและสั่งการนเรนทรอ่าวไทย ระบบบริหารจัดการ. สงวนลิขสิทธิ์.');
|
|
|
|
?>
|
|
|
|
<?php require_once 'includes/header.php'; ?>
|
|
|
|
<div class="space-y-6 animate-fadeIn pb-10">
|
|
|
|
<!-- Top Navigation Tabs -->
|
|
<div class="flex flex-wrap items-center gap-2 mt-2">
|
|
<button type="button" onclick="switchTab('users')" id="tab-btn-users" class="flex items-center justify-center gap-2 px-5 py-2.5 rounded-xl text-sm font-bold shadow-sm cursor-pointer transition-all bg-indigo-600 text-white">
|
|
<i data-lucide="users" class="w-4 h-4"></i> ผู้ใช้งาน (Users)
|
|
</button>
|
|
<button type="button" onclick="switchTab('units')" id="tab-btn-units" class="flex items-center justify-center gap-2 px-5 py-2.5 rounded-xl text-sm font-bold shadow-sm cursor-pointer transition-all bg-white text-slate-600 border border-slate-200 hover:bg-slate-50">
|
|
<i data-lucide="truck" class="w-4 h-4"></i> หน่วยกู้ชีพ (Units)
|
|
</button>
|
|
<button type="button" onclick="switchTab('settings')" id="tab-btn-settings" class="flex items-center justify-center gap-2 px-5 py-2.5 rounded-xl text-sm font-bold shadow-sm cursor-pointer transition-all bg-white text-slate-600 border border-slate-200 hover:bg-slate-50">
|
|
<i data-lucide="settings" class="w-4 h-4"></i> ตั้งค่าทั่วไป (Settings)
|
|
</button>
|
|
<button type="button" onclick="switchTab('dropdowns')" id="tab-btn-dropdowns" class="flex items-center justify-center gap-2 px-5 py-2.5 rounded-xl text-sm font-bold shadow-sm cursor-pointer transition-all bg-white text-slate-600 border border-slate-200 hover:bg-slate-50">
|
|
<i data-lucide="list" class="w-4 h-4"></i> ตั้งค่าตัวเลือก (Dropdowns)
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Main Content Area -->
|
|
<div class="grid grid-cols-1 gap-6">
|
|
|
|
<!-- Tab Content: User Management -->
|
|
<div id="tab-users" class="bg-white rounded-2xl p-5 md:p-6 shadow-sm border border-slate-100 space-y-6">
|
|
<div class="border-b border-slate-100 pb-3">
|
|
<h3 class="text-base font-black text-slate-800">จัดการข้อมูลผู้ใช้งานระบบ (User Management)</h3>
|
|
<p class="text-xs text-slate-400 mt-0.5">เพิ่ม ลบ บัญชีผู้ใช้ เปลี่ยนสิทธิ์ และ PIN ปลดล็อคระบบ</p>
|
|
</div>
|
|
|
|
<form method="POST" id="userForm" class="space-y-4 max-w-4xl" onsubmit="return validateUserForm()">
|
|
<input type="hidden" name="action" value="save_user">
|
|
<input type="hidden" name="user_id" id="user_id" value="">
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">Username (ลงชื่อเข้าใช้งาน)</label>
|
|
<input type="text" name="username" id="username" required placeholder="เช่น dispatcher_test" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">รหัสผ่าน (Password)</label>
|
|
<input type="password" name="password" id="password" required minlength="6" placeholder="รหัสผ่านอย่างน้อย 6 อักขระ" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
<p class="text-[9px] text-slate-400 mt-1 hidden" id="password_hint">เว้นว่างไว้หากไม่ต้องการเปลี่ยนรหัสผ่าน (กรณีแก้ไข)</p>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ยืนยันรหัสผ่าน (Confirm Password)</label>
|
|
<input type="password" id="confirm_password" required minlength="6" placeholder="ยืนยันรหัสผ่านอีกครั้ง" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
<p class="text-[9px] text-rose-500 mt-1 hidden" id="password_error">รหัสผ่านไม่ตรงกัน</p>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ชื่อ-นามสกุลทางการแพทย์</label>
|
|
<input type="text" name="full_name" id="full_name" required placeholder="เช่น นายกู้ชีพ มีสุข" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">สิทธิ์/บทบาทการทำงาน (Role)</label>
|
|
<select name="role" id="role" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 bg-white focus:border-blue-400 outline-none">
|
|
<option value="Admin">Admin</option>
|
|
<option value="Supervisor">Supervisor</option>
|
|
<option value="Dispatcher">Dispatcher</option>
|
|
<option value="Executive">Executive</option>
|
|
<option value="ER Koh Samui">ER Koh Samui</option>
|
|
<option value="Quality Officer">Quality Officer</option>
|
|
<option value="Driver">Driver</option>
|
|
<option value="EMS">EMS</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">รหัส PIN 4 หลัก (สำหรับความปลอดภัย)</label>
|
|
<input type="password" name="pin" id="pin" maxlength="4" required placeholder="เช่น 1234" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 font-mono text-center tracking-widest outline-none focus:border-blue-400">
|
|
</div>
|
|
<div class="col-span-2 flex flex-wrap items-center gap-4 py-1">
|
|
<label class="flex items-center gap-1.5 text-xs font-bold text-slate-600 cursor-pointer">
|
|
<input type="checkbox" name="must_change_pin" id="must_change_pin" value="1" class="w-4 h-4 text-blue-600 border-slate-200 rounded">
|
|
บังคับให้เปลี่ยน PIN เมื่อเข้าสู่ระบบครั้งแรก
|
|
</label>
|
|
<label class="flex items-center gap-1.5 text-xs font-bold text-slate-600 cursor-pointer">
|
|
<input type="checkbox" name="is_active" id="user_is_active" value="1" checked class="w-4 h-4 text-blue-600 border-slate-200 rounded">
|
|
เปิดใช้งานบัญชีนี้ (Active)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="flex gap-2 w-full md:w-1/2">
|
|
<button type="button" id="btn_cancel_user" onclick="resetUserForm()" class="hidden flex-1 py-2 bg-slate-100 hover:bg-slate-200 text-slate-600 text-xs font-bold rounded-xl transition-all cursor-pointer">ยกเลิกแก้ไข</button>
|
|
<button type="submit" id="btn_submit_user" class="flex-1 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-bold text-xs rounded-xl shadow-md transition-all cursor-pointer">เพิ่มและจัดสร้างผู้ใช้ใหม่</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="overflow-x-auto border border-slate-100 rounded-xl max-w-4xl">
|
|
<table class="w-full text-left border-collapse text-xs">
|
|
<thead>
|
|
<tr class="bg-slate-50 text-slate-600 font-bold border-b border-slate-100">
|
|
<th class="py-2.5 px-3">บัญชี / ชื่อผู้ใช้</th>
|
|
<th class="py-2.5 px-3">บทบาท (Role)</th>
|
|
<th class="py-2.5 px-3 text-center">สถานะ</th>
|
|
<th class="py-2.5 px-3 text-center w-16">แก้ไข</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-50 font-semibold text-slate-700">
|
|
<?php foreach ($users as $u): ?>
|
|
<tr class="hover:bg-slate-50/50">
|
|
<td class="py-2 px-3">
|
|
<div class="font-bold text-slate-800"><?php echo htmlspecialchars($u['full_name']); ?></div>
|
|
<div class="text-[10px] text-slate-400 font-mono">@<?php echo htmlspecialchars($u['username']); ?></div>
|
|
</td>
|
|
<td class="py-2 px-3">
|
|
<span class="bg-slate-100 px-2 py-0.5 rounded text-[10px] border border-slate-200 text-slate-600"><?php echo htmlspecialchars($u['role']); ?></span>
|
|
</td>
|
|
<td class="py-2 px-3 text-center">
|
|
<?php if($u['is_active']): ?>
|
|
<span class="px-2 py-0.5 rounded-[5px] text-[9px] font-black bg-emerald-50 text-emerald-600 border border-emerald-100">Active</span>
|
|
<?php else: ?>
|
|
<span class="px-2 py-0.5 rounded-[5px] text-[9px] font-black bg-slate-100 text-slate-500 border border-slate-200">Inactive</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="py-2 px-3 text-center">
|
|
<div class="flex gap-1.5 justify-center">
|
|
<button type="button" onclick='editUser(<?php echo json_encode($u); ?>)' class="p-1 hover:bg-blue-50 text-slate-400 hover:text-blue-600 rounded cursor-pointer transition-colors"><i data-lucide="pencil" class="w-3.5 h-3.5"></i></button>
|
|
<?php if($u['id'] != $_SESSION['user_id']): ?>
|
|
<button type="button" onclick="deleteUser(<?php echo $u['id']; ?>)" class="p-1 hover:bg-rose-50 text-slate-300 hover:text-rose-600 rounded cursor-pointer transition-colors"><i data-lucide="trash-2" class="w-3.5 h-3.5"></i></button>
|
|
<?php endif; ?>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab Content: Ambulance Fleet -->
|
|
<div id="tab-units" class="bg-white rounded-2xl p-5 md:p-6 shadow-sm border border-slate-100 space-y-6 hidden">
|
|
<div class="border-b border-slate-100 pb-3">
|
|
<h3 class="text-base font-black text-slate-800">จัดการหน่วยกู้ชีพและระดับกู้ภัย (Ambulance Fleet)</h3>
|
|
<p class="text-xs text-slate-400 mt-0.5">เพิ่ม ปรับลำดับการทำงาน และระบุหน่วยรับส่งประจำเกาะสมุย</p>
|
|
</div>
|
|
|
|
<form method="POST" class="space-y-4 max-w-4xl">
|
|
<input type="hidden" name="action" value="save_unit">
|
|
<input type="hidden" name="unit_id" id="unit_id" value="">
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div class="col-span-2">
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ชื่อสถานี / หน่วยกู้ชีพร่วมเครือข่าย</label>
|
|
<input type="text" name="unit_name" id="unit_name" required placeholder="เช่น หน่วยกู้ชีพตลิ่งงาม" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ระดับหน่วย (Level)</label>
|
|
<select name="level" id="unit_level" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 bg-white focus:border-blue-400 outline-none">
|
|
<option value="ALS">ALS (วิชาชีพขั้นสูง)</option>
|
|
<option value="BLS">BLS (รถพยาบาลมาตรฐาน)</option>
|
|
<option value="CLS">CLS (หน่วยกู้ภัยพื้นฐาน)</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">จัดลำดับการทำงาน (Sort Order)</label>
|
|
<input type="number" name="sort_order" id="sort_order" placeholder="ลำดับการออกขบวน" value="99" required class="w-full py-2 px-3 border border-slate-200 rounded-lg text-xs font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div class="col-span-2 flex flex-wrap items-center gap-4 py-1">
|
|
<label class="flex items-center gap-1.5 text-xs font-bold text-slate-600 cursor-pointer">
|
|
<input type="checkbox" name="is_samui_hospital" id="is_samui_hospital" value="1" class="w-4 h-4 text-blue-600 border-slate-200 rounded">
|
|
ระบุเป็นหน่วยโรงพยาบาลเกาะสมุย (ER สมุยหลัก)
|
|
</label>
|
|
<label class="flex items-center gap-1.5 text-xs font-bold text-slate-600 cursor-pointer">
|
|
<input type="checkbox" name="is_active" id="unit_is_active" value="1" checked class="w-4 h-4 text-blue-600 border-slate-200 rounded">
|
|
เปิดใช้งานขบวนนี้ (Active)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="flex gap-2 w-full md:w-1/2">
|
|
<button type="button" id="btn_cancel_unit" onclick="resetUnitForm()" class="hidden flex-1 py-2 bg-slate-100 hover:bg-slate-200 text-slate-600 text-xs font-bold rounded-xl transition-all cursor-pointer">ยกเลิกแก้ไข</button>
|
|
<button type="submit" id="btn_submit_unit" class="flex-1 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-bold text-xs rounded-xl shadow-md transition-all cursor-pointer">เพิ่มหน่วยกู้ภัยเครือข่ายใหม่</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="overflow-x-auto border border-slate-100 rounded-xl max-w-4xl">
|
|
<table class="w-full text-left border-collapse text-xs">
|
|
<thead>
|
|
<tr class="bg-slate-50 text-slate-600 font-bold border-b border-slate-100">
|
|
<th class="py-2.5 px-3">ชื่อหน่วยกู้ภัยเครือข่าย</th>
|
|
<th class="py-2.5 px-3">ระดับ</th>
|
|
<th class="py-2.5 px-3 text-center">สิทธิ์ รพ.สมุย</th>
|
|
<th class="py-2.5 px-3 text-center w-16">แก้ไข</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-50 font-semibold text-slate-700">
|
|
<?php foreach ($units as $unit): ?>
|
|
<tr class="hover:bg-slate-50/50">
|
|
<td class="py-2 px-3">
|
|
<div class="font-bold text-slate-800"><?php echo htmlspecialchars($unit['name']); ?></div>
|
|
<div class="text-[10px] text-slate-400 font-mono">ลำดับ: <?php echo htmlspecialchars($unit['sort_order']); ?></div>
|
|
</td>
|
|
<td class="py-2 px-3">
|
|
<?php
|
|
$levelColor = 'bg-slate-100 text-slate-600 border-slate-200';
|
|
if ($unit['level'] === 'ALS') $levelColor = 'bg-red-50 text-red-600 border-red-100';
|
|
if ($unit['level'] === 'BLS') $levelColor = 'bg-blue-50 text-blue-600 border-blue-100';
|
|
if ($unit['level'] === 'CLS') $levelColor = 'bg-amber-50 text-amber-600 border-amber-100';
|
|
?>
|
|
<span class="px-1.5 py-0.5 rounded-[4px] text-[10px] font-black border <?php echo $levelColor; ?>"><?php echo htmlspecialchars($unit['level']); ?></span>
|
|
</td>
|
|
<td class="py-2 px-3 text-center">
|
|
<?php if($unit['is_samui_hospital']): ?>
|
|
<span class="text-emerald-600 flex items-center justify-center gap-1 font-black"><span class="w-2 h-2 rounded-full bg-emerald-500"></span> ใช่</span>
|
|
<?php else: ?>
|
|
<span class="text-rose-600 flex items-center justify-center gap-1 font-bold"><i data-lucide="x" class="w-3.5 h-3.5 text-rose-500 stroke-[3px]"></i> ไม่</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="py-2 px-3 text-center">
|
|
<div class="flex gap-1.5 justify-center">
|
|
<button type="button" onclick='editUnit(<?php echo json_encode($unit); ?>)' class="p-1 hover:bg-blue-50 text-slate-400 hover:text-blue-600 rounded cursor-pointer transition-colors"><i data-lucide="pencil" class="w-3.5 h-3.5"></i></button>
|
|
<button type="button" onclick="deleteUnit(<?php echo $unit['id']; ?>)" class="p-1 hover:bg-rose-50 text-slate-300 hover:text-rose-600 rounded cursor-pointer transition-colors"><i data-lucide="trash-2" class="w-3.5 h-3.5"></i></button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab Content: General Settings -->
|
|
<div id="tab-settings" class="bg-white rounded-2xl p-5 md:p-6 shadow-sm border border-slate-100 space-y-6 hidden">
|
|
<div class="border-b border-slate-100 pb-3">
|
|
<h3 class="text-base font-black text-slate-800">ตั้งค่าทั่วไป (General Settings)</h3>
|
|
<p class="text-xs text-slate-400 mt-0.5">ปรับแต่งข้อความและชื่อระบบหลัก</p>
|
|
</div>
|
|
|
|
<form method="POST" class="space-y-4 max-w-4xl">
|
|
<input type="hidden" name="action" value="save_settings">
|
|
|
|
<div class="grid grid-cols-1 gap-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ชื่อระบบ (แสดงผลที่ Topbar)</label>
|
|
<input type="text" name="system_name" value="<?php echo htmlspecialchars($system_name); ?>" required class="w-full py-2 px-3 border border-slate-200 rounded-lg text-sm font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ข้อความส่วนท้าย (Footer)</label>
|
|
<input type="text" name="footer_text" value="<?php echo htmlspecialchars($footer_text); ?>" required class="w-full py-2 px-3 border border-slate-200 rounded-lg text-sm font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-2 w-full md:w-1/3 pt-2">
|
|
<button type="submit" class="flex-1 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-bold text-xs rounded-xl shadow-md transition-all cursor-pointer">
|
|
บันทึกการตั้งค่า
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Tab Content: Dropdowns Master Data -->
|
|
<div id="tab-dropdowns" class="bg-white rounded-2xl p-5 md:p-6 shadow-sm border border-slate-100 space-y-6 hidden">
|
|
<div class="border-b border-slate-100 pb-3">
|
|
<h3 class="text-base font-black text-slate-800">ตั้งค่าตัวเลือกฟอร์ม (Form Dropdowns)</h3>
|
|
<p class="text-xs text-slate-400 mt-0.5">จัดการรายการตัวเลือกต่างๆ ในหน้าฟอร์มรับแจ้งเหตุ</p>
|
|
</div>
|
|
|
|
<form method="POST" class="space-y-4 max-w-4xl">
|
|
<input type="hidden" name="action" value="save_master_data">
|
|
<input type="hidden" name="id" id="md_id" value="">
|
|
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">หมวดหมู่ (Category)</label>
|
|
<select name="category" id="md_category" required class="w-full py-2 px-3 border border-slate-200 rounded-lg text-sm font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
<option value="call_type">ประเภทสายเรียกเข้า (call_type)</option>
|
|
<option value="call_channel">ช่องทางการแจ้งเหตุ (call_channel)</option>
|
|
<option value="ems_refer">ประเภทปฏิบัติการ (ems_refer)</option>
|
|
<option value="unit_level">ระดับหน่วยกู้ชีพ (unit_level)</option>
|
|
<option value="cbd_symptom">จำแนกกลุ่มอาการ (cbd_symptom)</option>
|
|
<option value="phone_triage">Phone Triage (phone_triage)</option>
|
|
<option value="fast_track">รหัสเฉพาะผู้ป่วยวิกฤต (fast_track)</option>
|
|
<option value="transport_route">เส้นทางลำเลียงผู้ป่วย (transport_route)</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ข้อความที่แสดง (Label)</label>
|
|
<input type="text" name="item_label" id="md_item_label" required placeholder="เช่น สายก่อกวน" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-sm font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ค่า (Value)</label>
|
|
<input type="text" name="item_value" id="md_item_value" required placeholder="เช่น สายก่อกวน" class="w-full py-2 px-3 border border-slate-200 rounded-lg text-sm font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs font-bold text-slate-500 mb-1">ลำดับการแสดงผล (Sort Order)</label>
|
|
<input type="number" name="sort_order" id="md_sort_order" value="99" required class="w-full py-2 px-3 border border-slate-200 rounded-lg text-sm font-bold text-slate-700 outline-none focus:border-blue-400">
|
|
</div>
|
|
<div class="col-span-2 flex items-center pt-2">
|
|
<label class="flex items-center gap-1.5 text-xs font-bold text-slate-600 cursor-pointer">
|
|
<input type="checkbox" name="is_active" id="md_is_active" value="1" checked class="w-4 h-4 text-blue-600 border-slate-200 rounded">
|
|
เปิดใช้งานตัวเลือกนี้ (Active)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-2 w-full md:w-1/2 pt-2">
|
|
<button type="button" id="btn_cancel_md" onclick="resetMasterDataForm()" class="hidden flex-1 py-2 bg-slate-100 hover:bg-slate-200 text-slate-600 text-xs font-bold rounded-xl transition-all cursor-pointer">ยกเลิก</button>
|
|
<button type="submit" id="btn_submit_md" class="flex-1 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-bold text-xs rounded-xl shadow-md transition-all cursor-pointer">เพิ่มตัวเลือกใหม่</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="overflow-x-auto border border-slate-100 rounded-xl max-w-4xl mt-6">
|
|
<?php
|
|
$grouped_md = [];
|
|
foreach($master_data as $md) {
|
|
$grouped_md[$md['category']][] = $md;
|
|
}
|
|
$category_names = [
|
|
'call_type' => 'ประเภทสายเรียกเข้า',
|
|
'call_channel' => 'ช่องทางการแจ้งเหตุ',
|
|
'ems_refer' => 'ประเภทปฏิบัติการ',
|
|
'unit_level' => 'ระดับหน่วยกู้ชีพ',
|
|
'cbd_symptom' => 'จำแนกกลุ่มอาการ',
|
|
'phone_triage' => 'Phone Triage',
|
|
'fast_track' => 'รหัสเฉพาะผู้ป่วยวิกฤต',
|
|
'transport_route' => 'เส้นทางลำเลียงผู้ป่วย'
|
|
];
|
|
?>
|
|
<table class="w-full text-left border-collapse text-xs">
|
|
<thead>
|
|
<tr class="bg-slate-50 text-slate-600 font-bold border-b border-slate-100">
|
|
<th class="py-2.5 px-3">ข้อความ (Label)</th>
|
|
<th class="py-2.5 px-3">ค่า (Value)</th>
|
|
<th class="py-2.5 px-3">ลำดับ</th>
|
|
<th class="py-2.5 px-3 text-center">สถานะ</th>
|
|
<th class="py-2.5 px-3 text-center w-16">จัดการ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-50 font-semibold text-slate-700">
|
|
<?php foreach ($grouped_md as $cat_key => $items): ?>
|
|
<tr class="bg-indigo-50/50 border-b border-indigo-100">
|
|
<td colspan="5" class="py-2 px-3 font-bold text-indigo-700">
|
|
<div class="flex items-center gap-2">
|
|
<i data-lucide="layers" class="w-4 h-4"></i>
|
|
หมวดหมู่: <?php echo htmlspecialchars($category_names[$cat_key] ?? $cat_key); ?> (<?php echo $cat_key; ?>)
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php foreach ($items as $md): ?>
|
|
<tr class="hover:bg-slate-50/50">
|
|
<td class="py-2 px-3"><?php echo htmlspecialchars($md['item_label']); ?></td>
|
|
<td class="py-2 px-3 text-slate-400"><?php echo htmlspecialchars($md['item_value']); ?></td>
|
|
<td class="py-2 px-3"><?php echo htmlspecialchars($md['sort_order']); ?></td>
|
|
<td class="py-2 px-3 text-center">
|
|
<?php if($md['is_active']): ?>
|
|
<span class="px-2 py-0.5 rounded-[5px] text-[9px] font-black bg-emerald-50 text-emerald-600 border border-emerald-100">Active</span>
|
|
<?php else: ?>
|
|
<span class="px-2 py-0.5 rounded-[5px] text-[9px] font-black bg-slate-100 text-slate-500 border border-slate-200">Inactive</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="py-2 px-3 text-center">
|
|
<div class="flex gap-1.5 justify-center">
|
|
<button type="button" onclick='editMasterData(<?php echo json_encode($md); ?>)' class="p-1 hover:bg-blue-50 text-slate-400 hover:text-blue-600 rounded cursor-pointer transition-colors"><i data-lucide="pencil" class="w-3.5 h-3.5"></i></button>
|
|
<a href="admin.php?action=delete_master_data&id=<?php echo $md['id']; ?>" onclick="return confirm('ยืนยันการลบ?');" class="p-1 hover:bg-rose-50 text-slate-300 hover:text-rose-600 rounded cursor-pointer transition-colors"><i data-lucide="trash-2" class="w-3.5 h-3.5"></i></a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Forms Hidden Actions for Delete -->
|
|
<form id="deleteUserForm" method="POST" style="display:none;">
|
|
<input type="hidden" name="action" value="delete_user">
|
|
<input type="hidden" name="user_id" id="delete_user_id" value="">
|
|
</form>
|
|
|
|
<form id="deleteUnitForm" method="POST" style="display:none;">
|
|
<input type="hidden" name="action" value="delete_unit">
|
|
<input type="hidden" name="unit_id" id="delete_unit_id" value="">
|
|
</form>
|
|
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
// Tab Switching Logic
|
|
function switchTab(tabName) {
|
|
// Hide all tabs
|
|
document.getElementById('tab-users').classList.add('hidden');
|
|
document.getElementById('tab-units').classList.add('hidden');
|
|
document.getElementById('tab-settings').classList.add('hidden');
|
|
document.getElementById('tab-dropdowns').classList.add('hidden');
|
|
|
|
// Reset all buttons styling
|
|
const btnClassesActive = ['bg-indigo-600', 'text-white'];
|
|
const btnClassesInactive = ['bg-white', 'text-slate-600', 'border', 'border-slate-200', 'hover:bg-slate-50'];
|
|
|
|
const btns = ['users', 'units', 'settings', 'dropdowns'];
|
|
btns.forEach(name => {
|
|
const btn = document.getElementById('tab-btn-' + name);
|
|
btn.classList.remove(...btnClassesActive);
|
|
btn.classList.add(...btnClassesInactive);
|
|
});
|
|
|
|
// Show target tab and update button styling
|
|
document.getElementById('tab-' + tabName).classList.remove('hidden');
|
|
const activeBtn = document.getElementById('tab-btn-' + tabName);
|
|
activeBtn.classList.remove(...btnClassesInactive);
|
|
activeBtn.classList.add(...btnClassesActive);
|
|
}
|
|
|
|
<?php if ($success_msg): ?>
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'สำเร็จ!',
|
|
text: '<?php echo $success_msg; ?>',
|
|
timer: 2500,
|
|
showConfirmButton: false
|
|
});
|
|
<?php endif; ?>
|
|
<?php if ($error_msg): ?>
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'เกิดข้อผิดพลาด',
|
|
text: '<?php echo $error_msg; ?>'
|
|
});
|
|
<?php endif; ?>
|
|
|
|
function editUser(user) {
|
|
document.getElementById('user_id').value = user.id;
|
|
document.getElementById('username').value = user.username;
|
|
document.getElementById('password').value = '';
|
|
document.getElementById('confirm_password').value = '';
|
|
document.getElementById('password').removeAttribute('required');
|
|
document.getElementById('confirm_password').removeAttribute('required');
|
|
document.getElementById('full_name').value = user.full_name;
|
|
document.getElementById('role').value = user.role;
|
|
document.getElementById('pin').value = user.pin;
|
|
document.getElementById('must_change_pin').checked = user.must_change_pin == 1;
|
|
document.getElementById('user_is_active').checked = user.is_active == 1;
|
|
|
|
document.getElementById('btn_submit_user').textContent = 'บันทึกการปรับปรุงผู้ใช้';
|
|
document.getElementById('btn_cancel_user').classList.remove('hidden');
|
|
document.getElementById('password_hint').classList.remove('hidden');
|
|
document.getElementById('password_error').classList.add('hidden');
|
|
window.scrollTo({top: 0, behavior: 'smooth'});
|
|
}
|
|
|
|
function resetUserForm() {
|
|
document.getElementById('user_id').value = '';
|
|
document.getElementById('username').value = '';
|
|
document.getElementById('password').value = '';
|
|
document.getElementById('confirm_password').value = '';
|
|
document.getElementById('password').setAttribute('required', 'required');
|
|
document.getElementById('confirm_password').setAttribute('required', 'required');
|
|
document.getElementById('full_name').value = '';
|
|
document.getElementById('role').value = 'Dispatcher';
|
|
document.getElementById('pin').value = '';
|
|
document.getElementById('must_change_pin').checked = false;
|
|
document.getElementById('user_is_active').checked = true;
|
|
|
|
document.getElementById('btn_submit_user').textContent = 'เพิ่มและจัดสร้างผู้ใช้ใหม่';
|
|
document.getElementById('btn_cancel_user').classList.add('hidden');
|
|
document.getElementById('password_hint').classList.add('hidden');
|
|
document.getElementById('password_error').classList.add('hidden');
|
|
}
|
|
|
|
function deleteUser(id) {
|
|
Swal.fire({
|
|
title: 'ยืนยันการลบผู้ใช้?',
|
|
text: "ข้อมูลผู้ใช้นี้จะถูกลบออกจากระบบอย่างถาวร",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#cbd5e1',
|
|
confirmButtonText: 'ใช่, ลบเลย!',
|
|
cancelButtonText: 'ยกเลิก'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
document.getElementById('delete_user_id').value = id;
|
|
document.getElementById('deleteUserForm').submit();
|
|
}
|
|
});
|
|
}
|
|
|
|
function editUnit(unit) {
|
|
document.getElementById('unit_id').value = unit.id;
|
|
document.getElementById('unit_name').value = unit.name;
|
|
document.getElementById('unit_level').value = unit.level;
|
|
document.getElementById('sort_order').value = unit.sort_order;
|
|
document.getElementById('is_samui_hospital').checked = unit.is_samui_hospital == 1;
|
|
document.getElementById('unit_is_active').checked = unit.is_active == 1;
|
|
|
|
document.getElementById('btn_submit_unit').textContent = 'บันทึกการปรับปรุงหน่วยงาน';
|
|
document.getElementById('btn_cancel_unit').classList.remove('hidden');
|
|
window.scrollTo({top: 0, behavior: 'smooth'});
|
|
}
|
|
|
|
function resetUnitForm() {
|
|
document.getElementById('unit_id').value = '';
|
|
document.getElementById('unit_name').value = '';
|
|
document.getElementById('unit_level').value = 'BLS';
|
|
document.getElementById('sort_order').value = '99';
|
|
document.getElementById('is_samui_hospital').checked = false;
|
|
document.getElementById('unit_is_active').checked = true;
|
|
|
|
document.getElementById('btn_submit_unit').textContent = 'เพิ่มหน่วยกู้ภัยเครือข่ายใหม่';
|
|
document.getElementById('btn_cancel_unit').classList.add('hidden');
|
|
}
|
|
|
|
function deleteUnit(id) {
|
|
Swal.fire({
|
|
title: 'ยืนยันการลบหน่วยกู้ชีพ?',
|
|
text: "ข้อมูลหน่วยกู้ชีพนี้จะถูกลบออกจากระบบอย่างถาวร",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#cbd5e1',
|
|
confirmButtonText: 'ใช่, ลบเลย!',
|
|
cancelButtonText: 'ยกเลิก'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
document.getElementById('delete_unit_id').value = id;
|
|
document.getElementById('deleteUnitForm').submit();
|
|
}
|
|
});
|
|
}
|
|
function editMasterData(md) {
|
|
document.getElementById('md_id').value = md.id;
|
|
document.getElementById('md_category').value = md.category;
|
|
document.getElementById('md_item_value').value = md.item_value;
|
|
document.getElementById('md_item_label').value = md.item_label;
|
|
document.getElementById('md_sort_order').value = md.sort_order;
|
|
document.getElementById('md_is_active').checked = md.is_active == 1;
|
|
|
|
document.getElementById('btn_submit_md').textContent = 'บันทึกการแก้ไขตัวเลือก';
|
|
document.getElementById('btn_cancel_md').classList.remove('hidden');
|
|
window.scrollTo({top: 0, behavior: 'smooth'});
|
|
}
|
|
|
|
function resetMasterDataForm() {
|
|
document.getElementById('md_id').value = '';
|
|
document.getElementById('md_category').value = 'call_type';
|
|
document.getElementById('md_item_value').value = '';
|
|
document.getElementById('md_item_label').value = '';
|
|
document.getElementById('md_sort_order').value = '99';
|
|
document.getElementById('md_is_active').checked = true;
|
|
|
|
document.getElementById('btn_submit_md').textContent = 'เพิ่มตัวเลือกใหม่';
|
|
document.getElementById('btn_cancel_md').classList.add('hidden');
|
|
}
|
|
|
|
|
|
function validateUserForm() {
|
|
const pw = document.getElementById('password').value;
|
|
const cpw = document.getElementById('confirm_password').value;
|
|
const errorMsg = document.getElementById('password_error');
|
|
|
|
if (pw !== cpw) {
|
|
errorMsg.classList.remove('hidden');
|
|
document.getElementById('confirm_password').focus();
|
|
return false;
|
|
}
|
|
errorMsg.classList.add('hidden');
|
|
return true;
|
|
}
|
|
</script>
|
|
|
|
<?php require_once 'includes/footer.php'; ?>
|