Files
gravity/จัดการข้อมูลยานพาหนะ-พนักงานขับรถ/settings_notifications.php
T
2026-09-16 23:20:08 +07:00

308 lines
21 KiB
PHP

<?php
require_once 'includes/auth.php';
// เช็คสิทธิ์ว่าเป็นแอดมินหรือไม่
if (!isAdmin()) {
header("Location: index.php");
exit();
}
$pageTitle = 'การตั้งค่าแจ้งเตือน | ระบบจัดการข้อมูลยานพาหนะ โรงพยาบาลเกาะสมุย';
$bodyClass = 'bg-slate-50 dark:bg-slate-900 overflow-hidden';
require_once 'includes/header.php';
?>
<div class="flex h-screen overflow-hidden" x-data="notificationSettings()">
<?php require_once 'includes/sidebar.php'; ?>
<!-- Main Content -->
<main class="flex-1 flex flex-col min-w-0 overflow-hidden page-transition">
<?php require_once 'includes/navbar.php'; ?>
<!-- Content Area -->
<div class="flex-1 overflow-auto p-4 sm:p-6 lg:p-8 custom-scrollbar relative">
<!-- Background decoration -->
<div class="absolute top-[-10%] right-[-5%] w-[40vw] h-[40vw] rounded-full bg-green-300/10 dark:bg-green-900/10 blur-[100px] pointer-events-none"></div>
<div class="absolute bottom-[-10%] left-[-5%] w-[30vw] h-[30vw] rounded-full bg-blue-300/10 dark:bg-blue-900/10 blur-[80px] pointer-events-none"></div>
<div class="max-w-4xl mx-auto relative z-10">
<div class="flex flex-col sm:flex-row sm:items-center justify-between mb-8 gap-4">
<div>
<h1 class="text-3xl font-bold text-slate-800 dark:text-white drop-shadow-sm flex items-center gap-3">
<div class="bg-gradient-to-br from-green-500 to-green-600 text-white p-2 rounded-xl shadow-lg shadow-green-500/30">
<i class="fa-solid fa-bell text-xl w-6 text-center"></i>
</div>
การตั้งค่าแจ้งเตือน
</h1>
<p class="text-slate-600 dark:text-slate-400 mt-2 font-medium">ตั้งค่าการส่งแจ้งเตือนผ่าน LINE Notify และ Telegram</p>
</div>
</div>
<!-- Loading State -->
<div x-show="isLoading" class="p-10 flex justify-center items-center">
<i class="fa-solid fa-spinner fa-spin text-3xl text-primary-500"></i>
</div>
<div x-show="!isLoading" style="display: none;" class="space-y-6">
<!-- Event Selection -->
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 overflow-hidden">
<div class="px-6 py-4 border-b border-slate-100 dark:border-slate-700/50 bg-slate-50/50 dark:bg-slate-800/50 flex items-center gap-3">
<i class="fa-solid fa-list-check text-primary-500 text-lg"></i>
<h3 class="font-bold text-slate-800 dark:text-white">เลือกเหตุการณ์ที่ต้องการแจ้งเตือน</h3>
</div>
<div class="p-6">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<label class="flex items-start gap-3 cursor-pointer p-3 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors border border-transparent hover:border-slate-200 dark:hover:border-slate-600">
<div class="relative flex items-center mt-0.5">
<input type="checkbox" value="vehicle" x-model="form.notify_events" class="w-5 h-5 text-primary-600 bg-slate-100 border-slate-300 rounded focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-slate-800 focus:ring-2 dark:bg-slate-700 dark:border-slate-600">
</div>
<div>
<span class="block text-sm font-semibold text-slate-800 dark:text-slate-200">ข้อมูลยานพาหนะ</span>
<span class="block text-xs text-slate-500 mt-1">เมื่อมีการเพิ่ม ลบ หรือแก้ไขข้อมูลรถ</span>
</div>
</label>
<label class="flex items-start gap-3 cursor-pointer p-3 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors border border-transparent hover:border-slate-200 dark:hover:border-slate-600">
<div class="relative flex items-center mt-0.5">
<input type="checkbox" value="driver" x-model="form.notify_events" class="w-5 h-5 text-primary-600 bg-slate-100 border-slate-300 rounded focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-slate-800 focus:ring-2 dark:bg-slate-700 dark:border-slate-600">
</div>
<div>
<span class="block text-sm font-semibold text-slate-800 dark:text-slate-200">พนักงานขับรถ</span>
<span class="block text-xs text-slate-500 mt-1">เมื่อมีการเพิ่ม ลบ หรือแก้ไขข้อมูลพนักงานขับรถ</span>
</div>
</label>
<label class="flex items-start gap-3 cursor-pointer p-3 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors border border-transparent hover:border-slate-200 dark:hover:border-slate-600">
<div class="relative flex items-center mt-0.5">
<input type="checkbox" value="schedule" x-model="form.notify_events" class="w-5 h-5 text-primary-600 bg-slate-100 border-slate-300 rounded focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-slate-800 focus:ring-2 dark:bg-slate-700 dark:border-slate-600">
</div>
<div>
<span class="block text-sm font-semibold text-slate-800 dark:text-slate-200">ตารางการเดินรถ</span>
<span class="block text-xs text-slate-500 mt-1">เมื่อมีการเพิ่มหรืออัปเดตตารางเดินรถ</span>
</div>
</label>
<label class="flex items-start gap-3 cursor-pointer p-3 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors border border-transparent hover:border-slate-200 dark:hover:border-slate-600">
<div class="relative flex items-center mt-0.5">
<input type="checkbox" value="maintenance" x-model="form.notify_events" class="w-5 h-5 text-primary-600 bg-slate-100 border-slate-300 rounded focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-slate-800 focus:ring-2 dark:bg-slate-700 dark:border-slate-600">
</div>
<div>
<span class="block text-sm font-semibold text-slate-800 dark:text-slate-200">การซ่อมบำรุง</span>
<span class="block text-xs text-slate-500 mt-1">เมื่อมีการแจ้งซ่อมหรืออัปเดตสถานะการซ่อมบำรุง</span>
</div>
</label>
</div>
</div>
</div>
<!-- LINE Notify Settings -->
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 overflow-hidden">
<div class="px-6 py-4 border-b border-slate-100 dark:border-slate-700/50 bg-[#00B900]/5 flex justify-between items-center">
<div class="flex items-center gap-3">
<i class="fa-brands fa-line text-[#00B900] text-2xl"></i>
<h3 class="font-bold text-slate-800 dark:text-white">LINE Notify</h3>
</div>
<a href="https://notify-bot.line.me/my/" target="_blank" class="text-xs text-[#00B900] hover:underline font-medium">รับ Token ที่นี่ <i class="fa-solid fa-external-link text-[10px]"></i></a>
</div>
<div class="p-6">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">LINE Notify Token</label>
<input type="password" x-model="form.line_notify_token" class="glass-input block w-full p-2.5 text-sm font-mono" placeholder="วาง Token ที่ได้จาก LINE Notify">
<p class="text-xs text-slate-500 mt-1">เว้นว่างไว้หากไม่ต้องการใช้งาน LINE Notify</p>
</div>
<div class="flex justify-end">
<button type="button" @click="testLine()" :disabled="!form.line_notify_token" class="btn-gradient px-4 py-2 rounded-lg text-sm flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed from-[#00B900] to-[#009900] shadow-[#00B900]/30">
<i class="fa-regular fa-paper-plane"></i> ทดสอบส่งข้อความ LINE
</button>
</div>
</div>
</div>
</div>
<!-- Telegram Settings -->
<div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 overflow-hidden">
<div class="px-6 py-4 border-b border-slate-100 dark:border-slate-700/50 bg-[#0088cc]/5 flex items-center gap-3">
<i class="fa-brands fa-telegram text-[#0088cc] text-2xl"></i>
<h3 class="font-bold text-slate-800 dark:text-white">Telegram Bot</h3>
</div>
<div class="p-6">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Bot Token</label>
<input type="password" x-model="form.telegram_bot_token" class="glass-input block w-full p-2.5 text-sm font-mono" placeholder="เช่น 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11">
<p class="text-xs text-slate-500 mt-1">ได้จากการสร้าง Bot ผ่าน @BotFather</p>
</div>
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Chat ID</label>
<input type="text" x-model="form.telegram_chat_id" class="glass-input block w-full p-2.5 text-sm font-mono" placeholder="เช่น -100123456789 หรือ 123456789">
<p class="text-xs text-slate-500 mt-1">ID ของกลุ่มหรือผู้ใช้ (ต้องดึงบอทเข้ากลุ่มก่อน)</p>
</div>
<div class="flex justify-end">
<button type="button" @click="testTelegram()" :disabled="!form.telegram_bot_token || !form.telegram_chat_id" class="btn-gradient px-4 py-2 rounded-lg text-sm flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed from-[#0088cc] to-[#0077b3] shadow-[#0088cc]/30">
<i class="fa-regular fa-paper-plane"></i> ทดสอบส่งข้อความ Telegram
</button>
</div>
</div>
</div>
</div>
<!-- Error Alert -->
<div x-show="errorMsg" style="display: none;" class="bg-danger/10 border border-danger/30 text-danger text-sm rounded-xl p-4 flex items-start gap-3">
<i class="fa-solid fa-circle-exclamation mt-0.5"></i>
<span x-text="errorMsg"></span>
</div>
<!-- Save Actions -->
<div class="flex justify-end pt-4 border-t border-slate-200 dark:border-slate-700 mt-6">
<button @click="saveSettings()" type="button" class="btn-gradient px-6 py-2.5 rounded-xl shadow-lg shadow-primary-500/30 flex items-center gap-2 text-sm font-medium hover:-translate-y-0.5 transition-all">
<i class="fa-solid fa-save"></i>
<span>บันทึกการตั้งค่า</span>
</button>
</div>
</div>
</div>
</div>
</main>
</div>
<script>
function notificationSettings() {
return {
isExpanded: true,
toggleSidebar() { this.isExpanded = !this.isExpanded; },
isLoading: true,
errorMsg: '',
form: {
line_notify_token: '',
telegram_bot_token: '',
telegram_chat_id: '',
notify_events: []
},
init() {
this.fetchSettings();
},
fetchSettings() {
this.isLoading = true;
fetch('api/settings.php')
.then(res => res.json())
.then(data => {
if (data.settings) {
this.form.line_notify_token = data.settings.line_notify_token || '';
this.form.telegram_bot_token = data.settings.telegram_bot_token || '';
this.form.telegram_chat_id = data.settings.telegram_chat_id || '';
try {
if(data.settings.notify_events) {
this.form.notify_events = JSON.parse(data.settings.notify_events);
} else {
this.form.notify_events = ["vehicle","driver","schedule","maintenance"];
}
} catch(e) {
this.form.notify_events = ["vehicle","driver","schedule","maintenance"];
}
}
this.isLoading = false;
})
.catch(err => {
console.error(err);
this.errorMsg = 'เกิดข้อผิดพลาดในการโหลดข้อมูล';
this.isLoading = false;
});
},
saveSettings() {
this.errorMsg = '';
Swal.fire({
title: 'กำลังบันทึก...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
fetch('api/settings.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'save',
settings: {
line_notify_token: this.form.line_notify_token,
telegram_bot_token: this.form.telegram_bot_token,
telegram_chat_id: this.form.telegram_chat_id,
notify_events: JSON.stringify(this.form.notify_events)
}
})
})
.then(res => res.json())
.then(data => {
if (data.error) {
Swal.fire('ข้อผิดพลาด!', data.error, 'error');
} else {
Swal.fire({
icon: 'success',
title: 'สำเร็จ',
text: 'บันทึกการตั้งค่าเรียบร้อยแล้ว',
timer: 1500,
showConfirmButton: false
});
}
})
.catch(err => {
console.error(err);
Swal.fire('ข้อผิดพลาด!', 'ไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ได้', 'error');
});
},
testLine() {
this.testNotification('test_line', { token: this.form.line_notify_token });
},
testTelegram() {
this.testNotification('test_telegram', {
token: this.form.telegram_bot_token,
chat_id: this.form.telegram_chat_id
});
},
testNotification(action, dataObj) {
Swal.fire({
title: 'กำลังทดสอบส่งข้อความ...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
fetch('api/settings.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: action,
...dataObj
})
})
.then(res => res.json())
.then(data => {
if (data.success) {
Swal.fire('สำเร็จ', 'ส่งข้อความทดสอบเรียบร้อยแล้ว กรุณาตรวจสอบในแอปของคุณ', 'success');
} else {
Swal.fire('ส่งล้มเหลว', data.error || 'ไม่ทราบสาเหตุ', 'error');
}
})
.catch(err => {
console.error(err);
Swal.fire('ข้อผิดพลาด', 'ไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ได้', 'error');
});
}
}
}
</script>
<?php require_once 'includes/footer.php'; ?>