Files
gravity/One Stop Web Service/admin/index.php
T
2026-09-16 23:20:08 +07:00

301 lines
17 KiB
PHP

<?php
require_once '../init.php';
requireLogin();
$stmt = $pdo->query("SELECT * FROM websites ORDER BY display_order ASC");
$websites = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>จัดการเว็บไซต์ - <?= htmlspecialchars($globalSettings['site_name'] ?? 'ศูนย์รวมเว็บหน่วยงาน') ?></title>
<link rel="icon" type="image/png" href="../assets/images/logo.png">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Datatables -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<!-- SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</head>
<body class="antialiased min-h-screen bg-gray-50 py-10 px-4">
<div class="w-full max-w-6xl mx-auto glass-container">
<div class="flex flex-wrap justify-between items-center mb-8 border-b border-gray-200 pb-4 gap-4">
<h1 class="text-2xl font-bold text-gray-800"><i class="fa-solid fa-list mr-2"></i> จัดการเว็บไซต์</h1>
<div class="flex flex-wrap gap-2">
<a href="settings.php" class="magic-btn-outline"><i class="fa-solid fa-gear mr-1"></i> ตั้งค่าระบบ</a>
<a href="logs.php" class="magic-btn-outline"><i class="fa-solid fa-history mr-1"></i> ประวัติการทำงาน</a>
<a href="../index.php" class="magic-btn-outline"><i class="fa-solid fa-home mr-1"></i> หน้าหลัก</a>
<a href="logout.php" class="bg-red-500 hover:bg-red-600 text-white py-2 px-4 rounded-xl transition"><i class="fa-solid fa-right-from-bracket mr-1"></i> ออกจากระบบ</a>
</div>
</div>
<div class="mb-6 flex flex-wrap gap-2">
<button onclick="openModal()" class="magic-btn"><i class="fa-solid fa-plus mr-1"></i> เพิ่มเว็บไซต์ใหม่</button>
<button onclick="addMockData()" class="magic-btn-outline"><i class="fa-solid fa-vial mr-1"></i> เพิ่มข้อมูลตัวอย่าง 10 รายการ</button>
<button onclick="clearMockData()" class="bg-orange-500 hover:bg-orange-600 text-white py-2 px-4 rounded-xl transition shadow-sm"><i class="fa-solid fa-trash-can mr-1"></i> ล้างข้อมูลตัวอย่าง</button>
</div>
<div class="bg-white rounded-xl shadow-sm p-4 border border-gray-100 overflow-x-auto">
<table id="websitesTable" class="w-full border-collapse">
<thead>
<tr class="bg-gray-50">
<th class="p-3 border-b text-center whitespace-nowrap">ลำดับ</th>
<th class="p-3 border-b text-center whitespace-nowrap">โลโก้</th>
<th class="p-3 border-b text-center whitespace-nowrap">ชื่อเว็บ</th>
<th class="p-3 border-b text-center whitespace-nowrap">ลิงก์</th>
<th class="p-3 border-b text-center whitespace-nowrap">สถานะ</th>
<th class="p-3 border-b text-center whitespace-nowrap">สถิติ (คลิก)</th>
<th class="p-3 border-b text-center whitespace-nowrap">จัดการ</th>
</tr>
</thead>
<tbody>
<?php foreach($websites as $web): ?>
<tr>
<td class="p-3 border-b text-center whitespace-nowrap"><?= htmlspecialchars($web['display_order']) ?></td>
<td class="p-3 border-b text-center whitespace-nowrap">
<?php $logo = !empty($web['logo_url']) ? htmlspecialchars($web['logo_url']) : '../assets/images/logo.png'; ?>
<img src="<?= $logo ?>" alt="logo" class="w-10 h-10 object-contain rounded bg-gray-50 border border-gray-100 mx-auto" onerror="this.src='../assets/images/logo.png'">
</td>
<td class="p-3 border-b font-medium"><?= htmlspecialchars($web['name']) ?> <?php if($web['is_mock']) echo '<span class="text-xs bg-gray-200 text-gray-600 px-2 py-1 rounded ml-2">ตัวอย่าง</span>'; ?></td>
<td class="p-3 border-b text-center">
<a href="<?= htmlspecialchars($web['url']) ?>" target="_blank" class="inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-50 text-blue-500 hover:bg-blue-100 hover:text-blue-700 transition" title="<?= htmlspecialchars($web['url']) ?>">
<i class="fa-solid fa-link"></i>
</a>
</td>
<td class="p-3 border-b text-center whitespace-nowrap">
<?php
if($web['status'] == 'normal') echo '<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">ปกติ</span>';
elseif($web['status'] == 'cancelled') echo '<span class="px-2 py-1 bg-red-100 text-red-800 rounded-full text-xs">ยกเลิก</span>';
elseif($web['status'] == 'maintenance') echo '<span class="px-2 py-1 bg-orange-100 text-orange-800 rounded-full text-xs">ปรับปรุง</span>';
?>
</td>
<td class="p-3 border-b text-center font-bold text-gray-700 whitespace-nowrap"><?= number_format($web['click_count']) ?></td>
<td class="p-3 border-b text-center whitespace-nowrap">
<button onclick="editWeb(<?= $web['id'] ?>, '<?= htmlspecialchars(addslashes($web['name'])) ?>', '<?= htmlspecialchars(addslashes($web['url'])) ?>', <?= $web['display_order'] ?>, '<?= htmlspecialchars(addslashes($web['logo_url'] ?? '')) ?>', '<?= $web['status'] ?>')" class="text-blue-500 hover:text-blue-700 mr-2" title="แก้ไข"><i class="fa-solid fa-pen-to-square text-lg"></i></button>
<button onclick="resetClicks(<?= $web['id'] ?>, '<?= htmlspecialchars(addslashes($web['name'])) ?>')" class="text-orange-500 hover:text-orange-700 mr-2" title="เคลียร์สถิติการเข้าชม"><i class="fa-solid fa-eraser text-lg"></i></button>
<button onclick="deleteWeb(<?= $web['id'] ?>)" class="text-red-500 hover:text-red-700" title="ลบ"><i class="fa-solid fa-trash text-lg"></i></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Modal Form -->
<div id="formModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50 px-4">
<div class="bg-white rounded-2xl p-6 w-full max-w-md shadow-2xl transform transition-all">
<h2 id="modalTitle" class="text-xl font-bold mb-4">เพิ่มเว็บไซต์ใหม่</h2>
<form id="webForm" onsubmit="saveWeb(event)">
<input type="hidden" id="webId" name="id" value="">
<input type="hidden" id="actionType" name="action" value="add">
<div class="mb-4">
<label class="block text-gray-700 mb-2 font-medium">ชื่อเว็บไซต์</label>
<input type="text" id="webName" name="name" class="magic-input border border-gray-300" required>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-2 font-medium">ลิงค์ (URL)</label>
<input type="url" id="webUrl" name="url" class="magic-input border border-gray-300" placeholder="https://" required>
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-2 font-medium">ลิงก์โลโก้ (ปล่อยว่างเพื่อใช้โลโก้เริ่มต้น)</label>
<input type="text" id="webLogo" name="logo_url" class="magic-input border border-gray-300" placeholder="https://.../logo.png">
</div>
<div class="mb-4">
<label class="block text-gray-700 mb-2 font-medium">สถานะ</label>
<select id="webStatus" name="status" class="magic-input border border-gray-300">
<option value="normal">ใช้งานปกติ</option>
<option value="cancelled">ยกเลิกใช้งาน</option>
<option value="maintenance">ปรับปรุง</option>
</select>
</div>
<div class="mb-6">
<label class="block text-gray-700 mb-2 font-medium">ลำดับการแสดงผล (ตัวเลข)</label>
<input type="number" id="webOrder" name="display_order" class="magic-input border border-gray-300" value="0" required>
</div>
<div class="flex justify-end gap-2">
<button type="button" onclick="closeModal()" class="px-4 py-2 text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-xl transition font-medium">ยกเลิก</button>
<button type="submit" class="magic-btn">บันทึก</button>
</div>
</form>
</div>
</div>
<script>
$(document).ready(function() {
$('#websitesTable').DataTable({
"language": {
"url": "//cdn.datatables.net/plug-ins/1.13.6/i18n/th.json"
},
"order": [[ 0, "asc" ]]
});
});
function openModal() {
document.getElementById('formModal').classList.remove('hidden');
document.getElementById('formModal').classList.add('flex');
document.getElementById('modalTitle').innerText = 'เพิ่มเว็บไซต์ใหม่';
document.getElementById('webForm').reset();
document.getElementById('webId').value = '';
document.getElementById('actionType').value = 'add';
document.getElementById('webStatus').value = 'normal';
}
function closeModal() {
document.getElementById('formModal').classList.add('hidden');
document.getElementById('formModal').classList.remove('flex');
}
function editWeb(id, name, url, order, logo_url, status) {
openModal();
document.getElementById('modalTitle').innerText = 'แก้ไขเว็บไซต์';
document.getElementById('webId').value = id;
document.getElementById('webName').value = name;
document.getElementById('webUrl').value = url;
document.getElementById('webOrder').value = order;
document.getElementById('webLogo').value = logo_url;
document.getElementById('webStatus').value = status;
document.getElementById('actionType').value = 'edit';
}
function saveWeb(e) {
e.preventDefault();
const formData = new FormData(e.target);
fetch('api.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.success) {
Swal.fire('สำเร็จ', 'บันทึกข้อมูลเรียบร้อยแล้ว', 'success').then(() => {
location.reload();
});
} else {
Swal.fire('ข้อผิดพลาด', data.message, 'error');
}
})
.catch(error => {
Swal.fire('ข้อผิดพลาด', 'ไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ได้', 'error');
});
}
function deleteWeb(id) {
Swal.fire({
title: 'ยืนยันการลบ?',
text: "คุณต้องการลบเว็บไซต์นี้ใช่หรือไม่!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'ใช่, ลบเลย!',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
const formData = new FormData();
formData.append('action', 'delete');
formData.append('id', id);
fetch('api.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.success) {
Swal.fire('ลบแล้ว!', 'ลบข้อมูลเรียบร้อยแล้ว.', 'success').then(() => {
location.reload();
});
} else {
Swal.fire('ข้อผิดพลาด', data.message, 'error');
}
});
}
})
}
function resetClicks(id, name) {
Swal.fire({
title: 'ยืนยันการเคลียร์สถิติ?',
text: `คุณต้องการรีเซ็ตยอดผู้เข้าชมของเว็บ ${name} ให้กลับเป็น 0 ใช่หรือไม่?`,
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#f97316',
cancelButtonColor: '#3085d6',
confirmButtonText: 'ใช่, เคลียร์เลย!',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
const formData = new FormData();
formData.append('action', 'reset_clicks');
formData.append('id', id);
fetch('api.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.success) {
Swal.fire('สำเร็จ!', 'เคลียร์สถิติเรียบร้อยแล้ว.', 'success').then(() => {
location.reload();
});
} else {
Swal.fire('ข้อผิดพลาด', data.message, 'error');
}
});
}
});
}
function addMockData() {
fetch('mock_data.php?action=add')
.then(response => response.json())
.then(data => {
if(data.success) {
Swal.fire('สำเร็จ', 'เพิ่มข้อมูลตัวอย่าง 10 รายการแล้ว', 'success').then(() => {
location.reload();
});
}
});
}
function clearMockData() {
Swal.fire({
title: 'ยืนยันการล้างข้อมูล?',
text: "ลบเฉพาะข้อมูลที่ถูกสร้างเป็นตัวอย่างเท่านั้น",
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'ล้างข้อมูล',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
fetch('mock_data.php?action=clear')
.then(response => response.json())
.then(data => {
if(data.success) {
Swal.fire('สำเร็จ', 'ล้างข้อมูลตัวอย่างแล้ว', 'success').then(() => {
location.reload();
});
}
});
}
});
}
</script>
</body>
</html>