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

388 lines
21 KiB
PHP

<?php
require_once 'config.php';
requireLogin();
requireAdmin();
$action = $_GET['action'] ?? 'list';
$error = '';
$success = '';
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = $_POST['title'] ?? '';
$description = $_POST['description'] ?? '';
$due_date = $_POST['due_date'] ?? '';
$student_id = $_POST['student_id'] ?? '';
if (isset($_POST['add'])) {
$student_ids = $_POST['student_ids'] ?? [];
if (empty($title) || empty($due_date) || empty($student_ids)) {
$error = 'กรุณากรอกข้อมูลให้ครบถ้วน (เลือกนักเรียนอย่างน้อย 1 คน)';
} else {
$stmt = $pdo->prepare("INSERT INTO assignments (title, description, due_date, student_id) VALUES (?, ?, ?, ?)");
$success_count = 0;
foreach ($student_ids as $sid) {
if ($stmt->execute([$title, $description, $due_date, $sid])) {
$new_id = $pdo->lastInsertId();
logActivity($pdo, 'CREATE_ASSIGNMENT', "Created assignment ID: $new_id, Title: $title, Student ID: $sid");
$success_count++;
}
}
if ($success_count > 0) {
$success = "เพิ่มงานสำเร็จให้แก่ $success_count คน";
$action = 'list';
} else {
$error = 'เกิดข้อผิดพลาดในการเพิ่มงาน';
}
}
} elseif (isset($_POST['edit'])) {
$id = $_POST['id'] ?? '';
$status = $_POST['status'] ?? 'pending';
$student_ids = $_POST['student_ids'] ?? [];
if (empty($title) || empty($due_date) || empty($student_ids)) {
$error = 'กรุณากรอกข้อมูลให้ครบถ้วน (เลือกนักเรียนอย่างน้อย 1 คน)';
} else {
// Update the current assignment with the FIRST selected student
$first_student_id = array_shift($student_ids);
$stmt = $pdo->prepare("UPDATE assignments SET title=?, description=?, due_date=?, student_id=?, status=? WHERE id=?");
if ($stmt->execute([$title, $description, $due_date, $first_student_id, $status, $id])) {
logActivity($pdo, 'UPDATE_ASSIGNMENT', "Updated assignment ID: $id, Title: $title, Status: $status");
$success = 'แก้ไขงานสำเร็จ';
// If more students were checked, insert them as new assignments (cloning)
if (!empty($student_ids)) {
$insert_stmt = $pdo->prepare("INSERT INTO assignments (title, description, due_date, student_id, status) VALUES (?, ?, ?, ?, ?)");
$added_count = 0;
foreach ($student_ids as $sid) {
if ($insert_stmt->execute([$title, $description, $due_date, $sid, $status])) {
$added_count++;
}
}
if ($added_count > 0) {
$success .= " และเพิ่มงานใหม่ให้กับนักเรียนที่เลือกเพิ่มอีก $added_count คน";
}
}
$action = 'list';
} else {
$error = 'เกิดข้อผิดพลาดในการแก้ไขงาน';
}
}
}
}
// Handle delete
if (isset($_GET['delete'])) {
$id = $_GET['delete'];
// Get assignment info before deleting for log
$stmt_info = $pdo->prepare("SELECT title FROM assignments WHERE id=?");
$stmt_info->execute([$id]);
$assign_info = $stmt_info->fetch();
$stmt = $pdo->prepare("DELETE FROM assignments WHERE id=?");
if ($stmt->execute([$id])) {
$title = $assign_info ? $assign_info['title'] : 'Unknown';
logActivity($pdo, 'DELETE_ASSIGNMENT', "Deleted assignment ID: $id, Title: $title");
$success = 'ลบงานสำเร็จ';
}
}
// Fetch students for dropdowns
$stmt = $pdo->query("SELECT id, name FROM users WHERE role = 'student' ORDER BY name");
$students = $stmt->fetchAll();
include 'includes/header.php';
include 'includes/sidebar.php';
?>
<div class="mb-6 flex justify-between items-center">
<div>
<h2 class="text-2xl font-bold text-gray-800">จัดการงาน</h2>
<p class="text-gray-600 mt-1">เพิ่ม แก้ไข และลบงานที่มอบหมายให้นักเรียน</p>
</div>
<?php if ($action === 'list'): ?>
<a href="?action=add" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded shadow">
<i class="fas fa-plus mr-2"></i> เพิ่มงานใหม่
</a>
<?php else: ?>
<a href="assignments.php" class="bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded shadow">
<i class="fas fa-arrow-left mr-2"></i> กลับ
</a>
<?php endif; ?>
</div>
<?php if ($error): ?>
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded shadow-sm">
<p><i class="fas fa-exclamation-circle mr-2"></i> <?= htmlspecialchars($error) ?></p>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-6 rounded shadow-sm">
<p><i class="fas fa-check-circle mr-2"></i> <?= htmlspecialchars($success) ?></p>
</div>
<script>
Swal.fire({
icon: 'success',
title: 'สำเร็จ',
text: '<?= addslashes($success) ?>',
timer: 2000,
showConfirmButton: false
});
</script>
<?php endif; ?>
<?php if ($action === 'list'): ?>
<div class="bg-white rounded-lg shadow-md p-6">
<table class="dataTable display w-full text-sm text-left text-gray-500">
<thead class="text-xs text-gray-700 uppercase bg-gray-50">
<tr>
<th class="text-center w-16">ลำดับ</th>
<th class="text-center">ชื่องาน/ชื่อวิชา</th>
<th class="text-center">นักเรียน</th>
<th class="text-center w-32">วันที่เพิ่มข้อมูล</th>
<th class="text-center">กำหนดส่ง</th>
<th class="text-center w-24">สถานะ</th>
<th class="text-center">จัดการ</th>
</tr>
</thead>
<tbody>
<?php
$days_before = getSetting($pdo, 'days_before_due') ?: 3;
$stmt = $pdo->query("SELECT a.*, u.name as student_name, DATEDIFF(a.due_date, CURDATE()) as days_left FROM assignments a LEFT JOIN users u ON a.student_id = u.id ORDER BY a.id DESC");
$index = 1;
while ($row = $stmt->fetch()):
// Get all assigned students for this specific task
$stmt_group = $pdo->prepare("SELECT u.name FROM assignments a JOIN users u ON a.student_id = u.id WHERE a.title = ? AND a.due_date = ?");
$stmt_group->execute([$row['title'], $row['due_date']]);
$assigned_names = $stmt_group->fetchAll(PDO::FETCH_COLUMN);
$assigned_list = implode(', ', $assigned_names);
// Format Created At
$created_timestamp = strtotime($row['created_at']);
$created_date_th = date('d-m-', $created_timestamp) . (date('Y', $created_timestamp) + 543);
// Format Due Date
$due_timestamp = strtotime($row['due_date']);
$due_date_th = date('d-m-', $due_timestamp) . (date('Y', $due_timestamp) + 543);
$due_html = "<span>{$due_date_th}</span>";
$status_text = "รอดำเนินการ";
if ($row['status'] === 'pending') {
if ($row['days_left'] < 0) {
$due_html .= " <span class=\"bg-gray-800 text-white text-xs px-2 py-0.5 rounded ml-2 whitespace-nowrap\">เลยกำหนด " . abs($row['days_left']) . " วัน</span>";
} elseif ($row['days_left'] <= $days_before) {
$due_html .= " <span class=\"bg-orange-500 text-white text-xs px-2 py-0.5 rounded ml-2 whitespace-nowrap\">เหลือ {$row['days_left']} วัน</span>";
} else {
$due_html .= " <span class=\"bg-gray-100 text-gray-600 text-xs px-2 py-0.5 rounded ml-2 whitespace-nowrap\">เหลือ {$row['days_left']} วัน</span>";
}
} else {
$status_text = "เสร็จสิ้น";
}
?>
<tr class="bg-white border-b hover:bg-gray-50">
<td class="text-center"><?= $index++ ?></td>
<td class="font-medium text-gray-900"><?= htmlspecialchars($row['title']) ?></td>
<td><?= htmlspecialchars($row['student_name']) ?></td>
<td class="text-center"><?= $created_date_th ?></td>
<td class="text-center"><?= $due_html ?></td>
<td class="text-center">
<?php if ($row['status'] === 'submitted' || $row['status'] === 'completed'): ?>
<span class="bg-green-100 text-green-800 py-1 px-2 rounded-full text-xs font-semibold">เสร็จสิ้น</span>
<?php else: ?>
<span class="bg-yellow-100 text-yellow-800 py-1 px-2 rounded-full text-xs font-semibold">รอดำเนินการ</span>
<?php endif; ?>
</td>
<td class="text-center whitespace-nowrap">
<button type="button"
onclick="showDetails(
'<?= htmlspecialchars(addslashes($row['title'])) ?>',
'<?= htmlspecialchars(addslashes($row['description'] ?: '-')) ?>',
'<?= htmlspecialchars(addslashes($assigned_list)) ?>',
'<?= $due_date_th ?>',
'<?= $status_text ?>'
)"
class="text-white bg-blue-500 hover:bg-blue-600 font-medium rounded-lg text-sm px-3 py-1 mr-1" title="ดูรายละเอียด"><i class="fas fa-eye"></i></button>
<a href="?action=edit&id=<?= $row['id'] ?>" class="text-white bg-yellow-400 hover:bg-yellow-500 font-medium rounded-lg text-sm px-3 py-1 mr-1" title="แก้ไข"><i class="fas fa-edit"></i></a>
<button onclick="confirmDelete(<?= $row['id'] ?>)" class="text-white bg-red-600 hover:bg-red-700 font-medium rounded-lg text-sm px-3 py-1" title="ลบ"><i class="fas fa-trash"></i></button>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<script>
function showDetails(title, desc, assignedTo, dueDate, status) {
const statusColor = status === 'เสร็จสิ้น' ? 'text-green-600' : 'text-yellow-600';
let htmlContent = `
<div class="text-left space-y-4 text-sm mt-4">
<div class="bg-gray-50 p-3 rounded border">
<p class="text-gray-500 mb-1"><i class="fas fa-align-left mr-2"></i><strong>รายละเอียดงาน:</strong></p>
<p class="text-gray-800 whitespace-pre-wrap">${desc}</p>
</div>
<div class="flex items-center justify-between border-b pb-2">
<span class="text-gray-500"><i class="fas fa-users mr-2"></i><strong>ผู้ที่ถูกมอบหมาย:</strong></span>
<span class="text-gray-800 text-right ml-4">${assignedTo}</span>
</div>
<div class="flex items-center justify-between border-b pb-2">
<span class="text-gray-500"><i class="far fa-calendar-alt mr-2"></i><strong>วันที่กำหนดส่ง:</strong></span>
<span class="text-gray-800 font-medium">${dueDate}</span>
</div>
<div class="flex items-center justify-between pb-2">
<span class="text-gray-500"><i class="fas fa-info-circle mr-2"></i><strong>สถานะปัจจุบัน:</strong></span>
<span class="font-bold ${statusColor}">${status}</span>
</div>
</div>
`;
Swal.fire({
title: `<div class="text-xl text-blue-700 font-bold border-b pb-3">${title}</div>`,
html: htmlContent,
width: 600,
showCloseButton: true,
confirmButtonText: 'ปิดหน้าต่าง',
confirmButtonColor: '#3085d6',
customClass: {
title: 'mb-0'
}
});
}
function confirmDelete(id) {
Swal.fire({
title: 'ยืนยันการลบ?',
text: "คุณไม่สามารถกู้คืนข้อมูลนี้ได้!",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'ใช่, ลบเลย!',
cancelButtonText: 'ยกเลิก'
}).then((result) => {
if (result.isConfirmed) {
window.location.href = `assignments.php?delete=${id}`;
}
})
}
</script>
<?php elseif ($action === 'add' || $action === 'edit'):
$editMode = ($action === 'edit' && isset($_GET['id']));
$item = null;
if ($editMode) {
$stmt = $pdo->prepare("SELECT * FROM assignments WHERE id = ?");
$stmt->execute([$_GET['id']]);
$item = $stmt->fetch();
if (!$item) {
echo "<script>window.location.href='assignments.php';</script>";
exit;
}
}
?>
<div class="bg-white rounded-lg shadow-md p-6 max-w-2xl mx-auto">
<h3 class="text-xl font-bold mb-4 border-b pb-2"><?= $editMode ? 'แก้ไขงาน' : 'เพิ่มงานใหม่' ?></h3>
<form method="POST" action="assignments.php">
<?php if ($editMode): ?>
<input type="hidden" name="id" value="<?= $item['id'] ?>">
<?php endif; ?>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-bold mb-2" for="title">ชื่องาน/ชื่อวิชา <span class="text-red-500">*</span></label>
<input type="text" name="title" id="title" value="<?= $editMode ? htmlspecialchars($item['title']) : '' ?>" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
<div class="mb-4">
<label class="block text-gray-700 text-sm font-bold mb-2" for="description">รายละเอียดงาน</label>
<textarea name="description" id="description" rows="3" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500"><?= $editMode ? htmlspecialchars($item['description']) : '' ?></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-gray-700 text-sm font-bold mb-2" for="due_date">วันที่กำหนดส่ง <span class="text-red-500">*</span></label>
<input type="date" name="due_date" id="due_date" value="<?= $editMode ? $item['due_date'] : '' ?>" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
<div class="md:col-span-2">
<label class="block text-gray-700 text-sm font-bold mb-2" for="student_ids">มอบหมายให้นักเรียน <span class="text-red-500">*</span></label>
<div class="border rounded shadow-sm">
<div class="p-2 border-b bg-gray-50 flex justify-between items-center">
<input type="text" id="search_student" placeholder="ค้นหาชื่อ-สกุล..." class="text-sm px-2 py-1 border rounded w-2/3 focus:outline-none focus:border-blue-500">
<label class="flex items-center text-sm font-bold text-blue-600 cursor-pointer">
<input type="checkbox" id="select_all_students" class="mr-2"> เลือกทั้งหมด
</label>
</div>
<div class="max-h-48 overflow-y-auto p-2" id="student_list">
<?php foreach ($students as $student): ?>
<label class="flex items-center p-2 hover:bg-blue-50 rounded cursor-pointer student-item">
<input type="checkbox" name="student_ids[]" value="<?= $student['id'] ?>" class="mr-3 student-checkbox" <?= ($editMode && $item['student_id'] == $student['id']) ? 'checked' : '' ?>>
<span class="student-name text-gray-700"><?= htmlspecialchars($student['name']) ?></span>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<?php if ($editMode): ?>
<div class="mb-6">
<label class="block text-gray-700 text-sm font-bold mb-2" for="status">สถานะ</label>
<select name="status" id="status" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="pending" <?= $item['status'] === 'pending' ? 'selected' : '' ?>>รอดำเนินการ</option>
<option value="submitted" <?= $item['status'] === 'submitted' ? 'selected' : '' ?>>ส่งแล้ว</option>
</select>
</div>
<?php endif; ?>
<div class="flex items-center justify-end border-t pt-4 mt-6">
<a href="assignments.php" class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded mr-2">ยกเลิก</a>
<button type="submit" name="<?= $editMode ? 'edit' : 'add' ?>" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
<?= $editMode ? 'บันทึกการแก้ไข' : 'เพิ่มงาน' ?>
</button>
</div>
</form>
</div>
<?php endif; ?>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('search_student');
const selectAllCheckbox = document.getElementById('select_all_students');
const studentItems = document.querySelectorAll('.student-item');
const studentCheckboxes = document.querySelectorAll('.student-checkbox');
if (searchInput) {
searchInput.addEventListener('input', function(e) {
const term = e.target.value.toLowerCase();
studentItems.forEach(item => {
const name = item.querySelector('.student-name').textContent.toLowerCase();
if (name.includes(term)) {
item.style.display = 'flex';
} else {
item.style.display = 'none';
}
});
});
}
if (selectAllCheckbox) {
selectAllCheckbox.addEventListener('change', function(e) {
const isChecked = e.target.checked;
studentCheckboxes.forEach(cb => {
const parent = cb.closest('.student-item');
if (parent.style.display !== 'none') {
cb.checked = isChecked;
}
});
});
}
});
</script>
<?php include 'includes/footer.php'; ?>