395 lines
25 KiB
PHP
395 lines
25 KiB
PHP
<?php
|
|
require_once 'includes/db.php';
|
|
require_once 'includes/auth.php';
|
|
requireLogin();
|
|
|
|
// Fetch stations from database
|
|
$stations = [];
|
|
try {
|
|
$stmt = $pdo->query("SELECT id, name FROM units WHERE status = 'ready' ORDER BY id ASC LIMIT 16");
|
|
$stations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
// If table doesn't exist, it will fallback to default stations
|
|
}
|
|
|
|
$stationList = [];
|
|
foreach ($stations as $station) {
|
|
$stationList[] = $station['name'];
|
|
}
|
|
|
|
$defaultStations = [
|
|
"พะงัน 2", "เกาะเต่า 2", "กู้ภัยพะงัน", "กู้ภัยสมุย", "เมืองสมุย",
|
|
"กู้ชีพละไม", "กู้ชีพหน้าเมือง", "กู้ชีพตลิ่งงาม", "โรงพยาบาลกรุงเทพสมุย",
|
|
"โรงพยาบาลไทยอินเตอร์", "โรงพยาบาลบ้านดอนอินเตอร์", "โรงพยาบาลวัฒนแพทย์สมุย",
|
|
"โรงพยาบาลเกาะสมุยอินเตอร์", "โรงพยาบาลไทยอินเตอร์เกาะพะงัน", "ER สมุย", "ทชท. ว.4"
|
|
];
|
|
|
|
if (empty($stationList)) {
|
|
$stationList = $defaultStations;
|
|
}
|
|
|
|
$currentUserFullName = isset($_SESSION['user_name']) ? $_SESSION['user_name'] : 'ผู้ทดสอบ (Admin)';
|
|
$testerFirstName = explode(' ', trim($currentUserFullName))[0];
|
|
$currentTime = date('13:58:40');
|
|
$currentDateStr = "23 กรกฎาคม 2569";
|
|
$shift = "เช้า";
|
|
|
|
$announceStart = "“เจ็บป่วยฉุกเฉิน โทร 1669 ที่นี่ศูนย์รับแจ้งเหตุนเรนทรอ่าวไทย\nขณะนี้เวลา {$currentTime} นเรนทรอ่าวไทยแจ้งลูกข่ายและในข่าย จะทำการทดสอบ ว.16\nลูกข่ายและในข่ายนเรนทรอ่าวไทย มี ว.29 ไม่เร่งด่วน ให้ ว.00\nหากมี ว.29 เร่งด่วน ให้ขออนุญาต ว.6 เข้ามาได้”";
|
|
|
|
$announceEnd = "“มีอีกหรือไม่ ลูกข่ายและในข่ายนเรนทรอ่าวไทยที่ต้องการทดสอบ ว.16 ให้ ว.6 เข้ามาได้\nว.24 นี้ [ {$currentTime} ] นเรนทรอ่าวไทยแจ้ง ว.14 ว.16\nวันนี้มีผู้ร่วมทดสอบ ว.16 จำนวน <span id=\"announce-tested\">16</span> สถานี\nนเรนทรอ่าวไทยขอขอบคุณทุกสถานีที่ร่วมทดสอบ ว.16\nแจ้งลูกข่ายและในข่ายใช้ความถี่ได้ตามปกติ\nทดสอบโดย สมุย [ {$testerFirstName} ]\nนเรนทรอ่าวไทย [ {$currentTime} ]”";
|
|
|
|
require_once 'includes/header.php';
|
|
?>
|
|
|
|
<div class="space-y-6 animate-fadeIn pb-10">
|
|
|
|
<!-- Top Announcement Box -->
|
|
<div class="bg-gradient-to-br from-blue-900 to-indigo-900 text-white rounded-2xl p-5 md:p-6 shadow-lg border border-blue-800">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="flex items-center gap-2.5">
|
|
<i data-lucide="radio" class="w-5 h-5 text-blue-300 animate-pulse"></i>
|
|
<span class="text-sm font-bold uppercase tracking-wider text-blue-200">ข้อความประกาศ ว.16 - ก่อนทดสอบ</span>
|
|
</div>
|
|
<button type="button" class="flex items-center gap-1.5 bg-blue-800/80 hover:bg-blue-700 text-xs px-3 py-1.5 rounded-lg border border-blue-600/50 transition-all cursor-pointer font-medium" onclick="navigator.clipboard.writeText(`<?php echo htmlspecialchars($announceStart); ?>`); Swal.fire({title: 'สำเร็จ', text: 'คัดลอกข้อความ เรียบร้อยแล้ว', icon: 'success', timer: 1500, showConfirmButton: false});">
|
|
<i data-lucide="copy" class="w-3.5 h-3.5"></i> คัดลอกบทพูด
|
|
</button>
|
|
</div>
|
|
<div class="bg-slate-950/50 p-4 rounded-xl border border-blue-800/50 font-mono text-xs md:text-sm leading-relaxed whitespace-pre-line text-slate-100"><?php echo $announceStart; ?></div>
|
|
</div>
|
|
|
|
<!-- Main 16 Stations Table -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-200/80 overflow-hidden">
|
|
<div class="p-4 md:p-5 bg-slate-50 border-b border-slate-200/80 flex flex-col sm:flex-row sm:items-center justify-between gap-3">
|
|
<div>
|
|
<h3 class="text-base font-bold text-slate-800 flex items-center gap-2">
|
|
<i data-lucide="mic" class="w-4.5 h-4.5 text-indigo-600 animate-pulse"></i> ตารางทดสอบวิทยุ (16 สถานีหลัก)
|
|
</h3>
|
|
<p class="text-xs text-slate-400 mt-0.5 font-medium">ระบุระดับสัญญาณรับส่ง (5 หมายถึงดีที่สุด, ติดต่อไม่ได้ หมายถึงสัญญาณขาดหาย)</p>
|
|
</div>
|
|
<div class="text-xs font-bold bg-indigo-50 text-indigo-700 px-3 py-1.5 rounded-lg border border-indigo-100 self-start sm:self-auto flex items-center gap-1.5">
|
|
<i data-lucide="clock" class="w-3.5 h-3.5 text-indigo-500"></i> เวร<?php echo $shift; ?> | ผู้บันทึก: <?php echo $testerFirstName; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="overflow-x-auto">
|
|
<table class="w-full text-left border-collapse text-xs md:text-sm" id="main-stations-table">
|
|
<thead>
|
|
<tr class="bg-slate-100/50 text-slate-600 font-bold border-b border-slate-200/80">
|
|
<th class="py-3 px-4 w-12 text-center">ลำดับ</th>
|
|
<th class="py-3 px-3 min-w-[150px]">ชื่อสถานี</th>
|
|
<th class="py-3 px-3 text-center min-w-[130px]">สัญญาณส่ง (TX)</th>
|
|
<th class="py-3 px-3 text-center min-w-[130px]">สัญญาณรับ (RX)</th>
|
|
<th class="py-3 px-3 text-center w-36">ช่องรับสัญญาณ</th>
|
|
<th class="py-3 px-3 min-w-[150px]">หมายเหตุเพิ่มเติม</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-100 text-slate-700 font-medium">
|
|
<?php foreach ($stationList as $index => $stationName): ?>
|
|
<tr class="hover:bg-slate-50/50 transition-colors radio-row" data-id="s_<?php echo $index + 1; ?>">
|
|
<td class="py-2.5 px-4 text-center text-slate-400 font-semibold"><?php echo $index + 1; ?></td>
|
|
<td class="py-2.5 px-3">
|
|
<div class="font-bold text-slate-800 station-name"><?php echo htmlspecialchars($stationName); ?></div>
|
|
</td>
|
|
|
|
<td class="py-2.5 px-3 text-center">
|
|
<select class="tx-level tx-rx-select w-full py-1.5 px-2 rounded-lg border border-slate-200 text-xs font-bold text-slate-700 focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all bg-emerald-50 text-emerald-700 border-emerald-200">
|
|
<option value="5" selected>5/5 - ดีมาก</option>
|
|
<option value="4">4/5 - ดี</option>
|
|
<option value="3">3/5 - ปานกลาง</option>
|
|
<option value="2">2/5 - อ่อน</option>
|
|
<option value="1">1/5 - แย่มาก</option>
|
|
<option value="ติดต่อไม่ได้">❌ ติดต่อไม่ได้</option>
|
|
</select>
|
|
</td>
|
|
|
|
<td class="py-2.5 px-3 text-center">
|
|
<select class="rx-level tx-rx-select w-full py-1.5 px-2 rounded-lg border border-slate-200 text-xs font-bold text-slate-700 focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all bg-emerald-50 text-emerald-700 border-emerald-200">
|
|
<option value="5" selected>5/5 - ดีมาก</option>
|
|
<option value="4">4/5 - ดี</option>
|
|
<option value="3">3/5 - ปานกลาง</option>
|
|
<option value="2">2/5 - อ่อน</option>
|
|
<option value="1">1/5 - แย่มาก</option>
|
|
<option value="ติดต่อไม่ได้">❌ ติดต่อไม่ได้</option>
|
|
</select>
|
|
</td>
|
|
|
|
<td class="py-2.5 px-3 text-center">
|
|
<div class="flex rounded-lg overflow-hidden border border-slate-200 p-0.5 bg-slate-100">
|
|
<input type="hidden" class="channel-type" value="T">
|
|
<button type="button" class="btn-channel-t flex-1 py-1 text-[10px] font-bold rounded-md transition-all cursor-pointer bg-indigo-600 text-white shadow-sm">T (ช่องตรง)</button>
|
|
<button type="button" class="btn-channel-r flex-1 py-1 text-[10px] font-bold rounded-md transition-all cursor-pointer text-slate-600 hover:text-slate-800">R (Repeater)</button>
|
|
</div>
|
|
</td>
|
|
|
|
<td class="py-2.5 px-3">
|
|
<input type="text" class="note-input w-full px-2.5 py-1.5 border border-slate-200 rounded-lg text-xs font-medium outline-none focus:border-indigo-400 focus:ring-1 focus:ring-indigo-400 transition-all bg-slate-50/50 hover:bg-white focus:bg-white" placeholder="ไม่มีความเห็นพิเศษ...">
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Extra 5 Stations Table -->
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden" id="extra-stations-container">
|
|
<div class="p-4 md:p-5 bg-slate-50 border-b border-slate-100">
|
|
<h3 class="text-base font-bold text-slate-800 flex items-center gap-2">
|
|
<i data-lucide="plus-circle" class="w-4 h-4 text-emerald-600"></i> ตารางทดสอบวิทยุเพิ่มเติม (ลูกข่ายอื่น ๆ 5 ช่องพิเศษ)
|
|
</h3>
|
|
<p class="text-xs text-slate-500 mt-0.5">ระบุชื่อลูกข่ายและผลทดสอบวิทยุ (หากมีการกรอกชื่อ ระบบจึงจะนำข้อมูลมาคำนวณจำนวนผลสรุป)</p>
|
|
</div>
|
|
<div class="p-4 space-y-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-5 gap-3 font-bold text-xs text-slate-500 border-b border-slate-100 pb-2 hidden md:grid">
|
|
<div class="col-span-2 px-1">ระบุชื่อสถานีลูกข่ายเพิ่มเติม</div>
|
|
<div class="text-center">สัญญาณส่ง (TX)</div>
|
|
<div class="text-center">สัญญาณรับ (RX)</div>
|
|
<div class="px-1">หมายเหตุเพิ่มเติม</div>
|
|
</div>
|
|
|
|
<?php for($i = 0; $i < 5; $i++): ?>
|
|
<div class="radio-row extra-row grid grid-cols-1 md:grid-cols-5 gap-3 items-center bg-slate-50/30 p-2.5 md:p-1 rounded-xl border border-slate-100 md:border-none md:bg-transparent" data-id="extra_<?php echo $i; ?>">
|
|
<div class="col-span-2 flex items-center gap-2">
|
|
<span class="text-xs font-bold text-slate-400 w-6 text-center"><?php echo $i + 17; ?></span>
|
|
<input type="text" placeholder="เช่น กู้ชีพตลิ่งงาม (ปล่อยว่างเพื่อไม่บันทึก)" class="station-name-input flex-1 px-3 py-2 border border-slate-200 rounded-lg text-xs font-semibold outline-none focus:border-emerald-400 focus:ring-1 focus:ring-emerald-400 transition-all bg-white">
|
|
<input type="hidden" class="channel-type" value="T">
|
|
</div>
|
|
<div>
|
|
<select disabled class="tx-level tx-rx-select w-full py-2 px-2.5 rounded-lg border border-slate-200 text-xs font-bold text-slate-700 outline-none transition-all disabled:opacity-50 disabled:bg-slate-50 bg-emerald-50 text-emerald-700 border-emerald-200">
|
|
<option value="5" selected>5/5 - ดีมาก</option>
|
|
<option value="4">4/5 - ดี</option>
|
|
<option value="3">3/5 - ปานกลาง</option>
|
|
<option value="2">2/5 - อ่อน</option>
|
|
<option value="1">1/5 - แย่มาก</option>
|
|
<option value="ติดต่อไม่ได้">❌ ติดต่อไม่ได้</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<select disabled class="rx-level tx-rx-select w-full py-2 px-2.5 rounded-lg border border-slate-200 text-xs font-bold text-slate-700 outline-none transition-all disabled:opacity-50 disabled:bg-slate-50 bg-emerald-50 text-emerald-700 border-emerald-200">
|
|
<option value="5" selected>5/5 - ดีมาก</option>
|
|
<option value="4">4/5 - ดี</option>
|
|
<option value="3">3/5 - ปานกลาง</option>
|
|
<option value="2">2/5 - อ่อน</option>
|
|
<option value="1">1/5 - แย่มาก</option>
|
|
<option value="ติดต่อไม่ได้">❌ ติดต่อไม่ได้</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-span-1">
|
|
<input type="text" disabled placeholder="หมายเหตุเพิ่มเติม..." class="note-input w-full px-3 py-2 border border-slate-200 rounded-lg text-xs font-medium outline-none focus:border-emerald-400 focus:ring-1 focus:ring-emerald-400 transition-all bg-white disabled:opacity-50 disabled:bg-slate-50">
|
|
</div>
|
|
</div>
|
|
<?php endfor; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bottom Announcement Box -->
|
|
<div class="bg-gradient-to-br from-indigo-900 to-slate-900 text-white rounded-2xl p-5 md:p-6 shadow-lg border border-indigo-800">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<div class="flex items-center gap-2.5">
|
|
<i data-lucide="radio" class="w-5 h-5 text-indigo-300 animate-pulse"></i>
|
|
<span class="text-sm font-bold uppercase tracking-wider text-indigo-200">ข้อความประกาศ ว.16 - ปิดการทดสอบ</span>
|
|
</div>
|
|
<button type="button" class="flex items-center gap-1.5 bg-indigo-800/80 hover:bg-indigo-700 text-xs px-3 py-1.5 rounded-lg border border-indigo-600/50 transition-all cursor-pointer font-medium" onclick="copyEndAnnouncement()">
|
|
<i data-lucide="copy" class="w-3.5 h-3.5"></i> คัดลอกบทพูด
|
|
</button>
|
|
</div>
|
|
<div class="bg-slate-950/50 p-4 rounded-xl border border-indigo-800/50 font-mono text-xs md:text-sm leading-relaxed whitespace-pre-line text-slate-100" id="announce-end-text"><?php echo $announceEnd; ?></div>
|
|
</div>
|
|
|
|
<!-- Footer Confirmation Bar -->
|
|
<div class="bg-slate-50 rounded-2xl p-4 md:p-5 border border-slate-200/80 flex flex-col sm:flex-row items-center justify-between gap-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="p-2 bg-indigo-100 rounded-xl text-indigo-700 border border-indigo-200/50">
|
|
<i data-lucide="check-circle" class="w-5 h-5"></i>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-sm font-bold text-slate-800">ยืนยันและสรุปผลตรวจ ว.16</h4>
|
|
<p class="text-xs text-slate-400 mt-0.5 font-medium">เข้าร่วม <span id="summary-tested">16</span> สถานี | ติดต่อไม่ได้ <span id="summary-untested">0</span> สถานี | ผู้ทดสอบ: <?php echo htmlspecialchars($currentUserFullName); ?></p>
|
|
</div>
|
|
</div>
|
|
<button type="button" id="btn-save" class="w-full sm:w-auto flex items-center justify-center gap-2.5 bg-indigo-600 hover:bg-indigo-700 text-white font-bold text-sm px-6 py-3 rounded-xl shadow-md shadow-indigo-100 transition-all active:scale-95 cursor-pointer">
|
|
<i data-lucide="save" class="w-4 h-4"></i> บันทึกและส่งข้อมูลเข้ารายงานเวร
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
|
|
const updateCalculations = () => {
|
|
let testedCount = 0;
|
|
let untestedCount = 0;
|
|
|
|
document.querySelectorAll('.radio-row').forEach(row => {
|
|
const isExtra = row.classList.contains('extra-row');
|
|
|
|
let name = '';
|
|
if (isExtra) {
|
|
name = row.querySelector('.station-name-input').value.trim();
|
|
if (!name) return; // skip empty extra rows
|
|
}
|
|
|
|
const tx = row.querySelector('.tx-level').value;
|
|
const rx = row.querySelector('.rx-level').value;
|
|
|
|
if (tx === 'ติดต่อไม่ได้' && rx === 'ติดต่อไม่ได้') {
|
|
untestedCount++;
|
|
} else {
|
|
testedCount++;
|
|
}
|
|
});
|
|
|
|
document.getElementById('summary-tested').innerText = testedCount;
|
|
document.getElementById('announce-tested').innerText = testedCount;
|
|
document.getElementById('summary-untested').innerText = untestedCount;
|
|
};
|
|
|
|
// Colorize selects and update calculations
|
|
document.querySelectorAll('.tx-rx-select').forEach(select => {
|
|
select.addEventListener('change', function() {
|
|
this.classList.remove('bg-emerald-50', 'text-emerald-700', 'border-emerald-200', 'bg-rose-100', 'text-rose-700', 'border-rose-200');
|
|
if (this.value === '5') {
|
|
this.classList.add('bg-emerald-50', 'text-emerald-700', 'border-emerald-200');
|
|
} else if (this.value === 'ติดต่อไม่ได้') {
|
|
this.classList.add('bg-rose-100', 'text-rose-700', 'border-rose-200');
|
|
}
|
|
|
|
// Check row red background
|
|
const row = this.closest('tr');
|
|
if (row) {
|
|
const tx = row.querySelector('.tx-level').value;
|
|
const rx = row.querySelector('.rx-level').value;
|
|
if (tx === 'ติดต่อไม่ได้' && rx === 'ติดต่อไม่ได้') {
|
|
row.classList.add('bg-red-50/20');
|
|
} else {
|
|
row.classList.remove('bg-red-50/20');
|
|
}
|
|
}
|
|
|
|
updateCalculations();
|
|
});
|
|
});
|
|
|
|
// T/R buttons
|
|
document.querySelectorAll('.btn-channel-t').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const hidden = this.parentElement.querySelector('.channel-type');
|
|
hidden.value = 'T';
|
|
this.classList.add('bg-indigo-600','text-white','shadow-sm');
|
|
this.classList.remove('text-slate-600','hover:text-slate-800');
|
|
this.nextElementSibling.classList.remove('bg-indigo-600','text-white','shadow-sm');
|
|
this.nextElementSibling.classList.add('text-slate-600','hover:text-slate-800');
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('.btn-channel-r').forEach(btn => {
|
|
btn.addEventListener('click', function() {
|
|
const hidden = this.parentElement.querySelector('.channel-type');
|
|
hidden.value = 'R';
|
|
this.classList.add('bg-indigo-600','text-white','shadow-sm');
|
|
this.classList.remove('text-slate-600','hover:text-slate-800');
|
|
this.previousElementSibling.classList.remove('bg-indigo-600','text-white','shadow-sm');
|
|
this.previousElementSibling.classList.add('text-slate-600','hover:text-slate-800');
|
|
});
|
|
});
|
|
|
|
// Extra stations
|
|
document.querySelectorAll('.station-name-input').forEach(input => {
|
|
input.addEventListener('input', function() {
|
|
const active = this.value.trim() !== '';
|
|
const selects = this.parentElement.parentElement.querySelectorAll('select, input[type=text]:not(.station-name-input)');
|
|
selects.forEach(el => el.disabled = !active);
|
|
updateCalculations();
|
|
});
|
|
});
|
|
|
|
window.copyEndAnnouncement = () => {
|
|
const text = document.getElementById('announce-end-text').innerText;
|
|
navigator.clipboard.writeText(text);
|
|
Swal.fire({title: 'สำเร็จ', text: 'คัดลอกข้อความ เรียบร้อยแล้ว', icon: 'success', timer: 1500, showConfirmButton: false});
|
|
};
|
|
|
|
// Save logic
|
|
document.getElementById('btn-save').addEventListener('click', async () => {
|
|
const btn = document.getElementById('btn-save');
|
|
btn.disabled = true;
|
|
const originalText = btn.innerHTML;
|
|
btn.innerHTML = 'กำลังบันทึก...';
|
|
|
|
let items = [];
|
|
|
|
document.querySelectorAll('.radio-row').forEach(row => {
|
|
const isExtra = row.classList.contains('extra-row');
|
|
|
|
let name = '';
|
|
if (isExtra) {
|
|
name = row.querySelector('.station-name-input').value.trim();
|
|
if (!name) return;
|
|
} else {
|
|
name = row.querySelector('.station-name').innerText.trim();
|
|
}
|
|
|
|
items.push({
|
|
station_id: row.dataset.id,
|
|
station_name: name,
|
|
tx_level: row.querySelector('.tx-level').value,
|
|
rx_level: row.querySelector('.rx-level').value,
|
|
channel_type: row.querySelector('.channel-type').value,
|
|
note: row.querySelector('.note-input').value.trim()
|
|
});
|
|
});
|
|
|
|
const payload = {
|
|
date: new Date().toISOString().split('T')[0],
|
|
time: '<?php echo $currentTime; ?>',
|
|
shift: '<?php echo $shift; ?>',
|
|
tested_count: document.getElementById('summary-tested').innerText,
|
|
untested_count: document.getElementById('summary-untested').innerText,
|
|
items: items
|
|
};
|
|
|
|
try {
|
|
const response = await fetch('api/save_radio_test.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(payload)
|
|
});
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
Swal.fire({
|
|
title: 'สำเร็จ',
|
|
text: data.message,
|
|
icon: 'success',
|
|
confirmButtonColor: '#4f46e5'
|
|
}).then(() => {
|
|
window.scrollTo({top: 0, behavior: 'smooth'});
|
|
});
|
|
} else {
|
|
Swal.fire({
|
|
title: 'ข้อผิดพลาด',
|
|
text: data.message,
|
|
icon: 'error',
|
|
confirmButtonColor: '#ef4444'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error(error);
|
|
Swal.fire({
|
|
title: 'ข้อผิดพลาด',
|
|
text: 'เกิดข้อผิดพลาดในการเชื่อมต่อ',
|
|
icon: 'error',
|
|
confirmButtonColor: '#ef4444'
|
|
});
|
|
} finally {
|
|
btn.innerHTML = originalText;
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
|
|
});
|
|
</script>
|
|
|
|
<?php require_once 'includes/footer.php'; ?>
|