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

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'; ?>