39496-vm/admin_assignments.php
2026-04-07 18:26:56 +00:00

256 lines
11 KiB
PHP

<?php
// admin_assignments.php
require_once __DIR__ . '/includes/app.php';
require_once __DIR__ . '/includes/auth.php';
require_permission('assignments', 'view');
// Initialize table if not exists
db()->exec("CREATE TABLE IF NOT EXISTS teacher_assignments (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
teacher_id INT NOT NULL,
class_id INT NOT NULL,
subject_id INT NOT NULL DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_assignment (teacher_id, class_id, subject_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
$action = $_GET['action'] ?? 'list';
$id = (int)($_GET['id'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$post_action = $_POST['action'] ?? $action;
$post_id = (int)($_POST['id'] ?? $id);
if ($post_action === 'delete' && $post_id > 0) {
require_permission('assignments', 'delete');
$stmt = db()->prepare("DELETE FROM teacher_assignments WHERE id = ?");
$stmt->execute([$post_id]);
header('Location: ' . app_url('admin.php', ['page' => 'assignments']));
exit;
}
if ($post_action === 'add') {
$teacher_id = (int)($_POST['teacher_id'] ?? 0);
$class_id = (int)($_POST['class_id'] ?? 0);
$subject_id = (int)($_POST['subject_id'] ?? 0);
if ($teacher_id > 0 && $class_id > 0) {
try {
$stmt = db()->prepare("INSERT INTO teacher_assignments (teacher_id, class_id, subject_id) VALUES (?, ?, ?)");
$stmt->execute([$teacher_id, $class_id, $subject_id]);
} catch (PDOException $e) {
// Ignore duplicate key error
}
}
header('Location: ' . app_url('admin.php', ['page' => 'assignments']));
exit;
}
}
// Fetch all for dropdowns
$teachers = db()->query("SELECT id, name FROM teachers ORDER BY name")->fetchAll(PDO::FETCH_ASSOC);
$classes = db()->query("SELECT id, name_en, name_ar FROM classes ORDER BY name_en")->fetchAll(PDO::FETCH_ASSOC);
$subjects = db()->query("SELECT id, title_en, title_ar, class_id FROM subjects ORDER BY title_en")->fetchAll(PDO::FETCH_ASSOC);
// Fetch assignments for table
$search = $_GET['search'] ?? '';
$page_num = max(1, (int)($_GET['p'] ?? 1));
$limit = 10;
$offset = ($page_num - 1) * $limit;
$where = "";
$params = [];
if ($search !== '') {
$where = "WHERE t.name LIKE ? OR c.name_en LIKE ? OR s.title_en LIKE ?";
$params[] = "%$search%";
$params[] = "%$search%";
$params[] = "%$search%";
}
$count_sql = "
SELECT COUNT(*)
FROM teacher_assignments ta
JOIN teachers t ON ta.teacher_id = t.id
JOIN classes c ON ta.class_id = c.id
LEFT JOIN subjects s ON ta.subject_id = s.id
$where
";
$total_stmt = db()->prepare($count_sql);
$total_stmt->execute($params);
$total = $total_stmt->fetchColumn();
$pages = ceil($total / $limit);
$sql = "
SELECT ta.id, t.name as teacher_name, c.name_en as class_name_en, c.name_ar as class_name_ar, s.title_en as subject_title_en, s.title_ar as subject_title_ar, ta.subject_id
FROM teacher_assignments ta
JOIN teachers t ON ta.teacher_id = t.id
JOIN classes c ON ta.class_id = c.id
LEFT JOIN subjects s ON ta.subject_id = s.id
$where
ORDER BY ta.id DESC
LIMIT $limit OFFSET $offset
";
$stmt = db()->prepare($sql);
$stmt->execute($params);
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<div class="section-header mb-4 d-flex justify-content-between align-items-center">
<div>
<h1 class="section-title mb-2"><?= h(t('Teacher Assignments', 'تعيينات المعلمين')) ?></h1>
</div>
<?php if (has_permission('assignments', 'add')): ?>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addAssignmentModal" style="background-color: var(--accent); border-color: var(--accent);">+ <?= h(t('Add Assignment', 'إضافة تعيين')) ?></button>
<?php endif; ?>
</div>
<div class="panel-card mb-4">
<form method="get" class="d-flex gap-2 align-items-center">
<input type="hidden" name="page" value="assignments">
<input type="text" name="search" class="form-control w-auto" placeholder="<?= h(t('Search...', 'بحث...')) ?>" value="<?= h($search) ?>">
<button type="submit" class="btn btn-outline-secondary"><?= h(t('Filter', 'تصفية')) ?></button>
<?php if ($search): ?>
<a href="<?= h(app_url('admin.php', ['page'=>'assignments'])) ?>" class="btn btn-link text-secondary text-decoration-none"><?= h(t('Clear', 'مسح')) ?></a>
<?php endif; ?>
</form>
</div>
<div class="panel-card">
<div class="table-responsive">
<table class="table align-middle dashboard-table mb-0">
<thead>
<tr>
<th><?= h(t('Teacher', 'المعلم')) ?></th>
<th><?= h(t('Class', 'الصف')) ?></th>
<th><?= h(t('Subject', 'المادة')) ?></th>
<th><?= h(t('Actions', 'إجراءات')) ?></th>
</tr>
</thead>
<tbody>
<?php if(empty($items)): ?>
<tr>
<td colspan="4" class="text-center text-muted py-4"><?= h(t('No assignments found.', 'لا توجد تعيينات.')) ?></td>
</tr>
<?php endif; ?>
<?php foreach($items as $row): ?>
<tr>
<td>
<div class="fw-semibold"><?= h($row['teacher_name']) ?></div>
</td>
<td>
<div class="text-secondary"><?= h(current_lang() === 'ar' ? $row['class_name_ar'] : $row['class_name_en']) ?></div>
</td>
<td>
<div class="text-secondary">
<?php if ($row['subject_id'] > 0): ?>
<?= h(current_lang() === 'ar' ? $row['subject_title_ar'] : $row['subject_title_en']) ?>
<?php else: ?>
<span class="badge bg-secondary"><?= h(t('All Subjects', 'كل المواد')) ?></span>
<?php endif; ?>
</div>
</td>
<td>
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'assignments'])) ?>" style="display:inline;" onsubmit="return confirm('<?= h(t('Are you sure you want to remove this assignment?', 'هل أنت متأكد من إزالة هذا التعيين؟')) ?>');">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= h((string)$row['id']) ?>">
<button type="submit" class="btn btn-sm btn-outline-danger">
<?= h(t('Remove', 'إزالة')) ?>
</button>
</form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php if ($pages > 1): ?>
<nav class="mt-4">
<ul class="pagination pagination-sm">
<?php for ($i = 1; $i <= $pages; $i++): ?>
<li class="page-item <?= $i === $page_num ? 'active' : '' ?>">
<a class="page-link" href="<?= h(app_url('admin.php', ['page'=>'assignments', 'p'=>$i, 'search'=>$search])) ?>">
<?= $i ?>
</a>
</li>
<?php endfor; ?>
</ul>
</nav>
<?php endif; ?>
<!-- Add Assignment Modal -->
<div class="modal fade" id="addAssignmentModal" tabindex="-1" aria-labelledby="addAssignmentModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow">
<div class="modal-header border-0 bg-dark-blue">
<h5 class="modal-title section-title text-white" id="addAssignmentModalLabel"><?= h(t('Add Assignment', 'إضافة تعيين')) ?></h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form method="post" action="<?= h(app_url('admin.php', ['page'=>'assignments'])) ?>">
<input type="hidden" name="action" value="add">
<div class="mb-3">
<label class="form-label"><?= h(t('Teacher', 'المعلم')) ?></label>
<select name="teacher_id" class="form-select" required>
<option value=""><?= h(t('Select a teacher...', 'اختر معلماً...')) ?></option>
<?php foreach($teachers as $t): ?>
<option value="<?= h((string)$t['id']) ?>"><?= h($t['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label class="form-label"><?= h(t('Class', 'الصف')) ?></label>
<select name="class_id" id="classSelect" class="form-select" required onchange="filterSubjects()">
<option value=""><?= h(t('Select a class...', 'اختر صفاً...')) ?></option>
<?php foreach($classes as $c): ?>
<option value="<?= h((string)$c['id']) ?>"><?= h(current_lang() === 'ar' ? $c['name_ar'] : $c['name_en']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-4">
<label class="form-label"><?= h(t('Subject (Optional)', 'المادة (اختياري)')) ?></label>
<select name="subject_id" id="subjectSelect" class="form-select">
<option value="0" class="default-opt"><?= h(t('All Subjects / Not Specified', 'كل المواد / غير محدد')) ?></option>
<?php foreach($subjects as $s): ?>
<option value="<?= h((string)$s['id']) ?>" data-class-id="<?= h((string)$s['class_id']) ?>" style="display:none;">
<?= h(current_lang() === 'ar' ? $s['title_ar'] : $s['title_en']) ?>
</option>
<?php endforeach; ?>
</select>
<small class="text-muted d-block mt-1"><?= h(t('Select a class first to view its specific subjects.', 'اختر الصف أولاً لرؤية مواده المحددة.')) ?></small>
</div>
<div class="d-flex justify-content-end gap-2">
<button type="button" class="btn btn-light" data-bs-dismiss="modal"><?= h(t('Cancel', 'إلغاء')) ?></button>
<button type="submit" class="btn btn-primary" style="background-color: var(--accent); border-color: var(--accent);"><?= h(t('Save', 'حفظ')) ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
function filterSubjects() {
var classId = document.getElementById('classSelect').value;
var subjectSelect = document.getElementById('subjectSelect');
var options = subjectSelect.getElementsByTagName('option');
// reset selection to default
subjectSelect.value = "0";
for (var i = 0; i < options.length; i++) {
var opt = options[i];
if (opt.classList.contains('default-opt')) continue;
if (opt.getAttribute('data-class-id') === classId && classId !== "") {
opt.style.display = '';
} else {
opt.style.display = 'none';
}
}
}
</script>