315 lines
14 KiB
PHP
315 lines
14 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/includes/app.php';
|
|
|
|
if (!is_super_admin()) {
|
|
http_response_code(403);
|
|
render_page_start('صلاحيات غير كافية', '');
|
|
?>
|
|
<section class="py-5 text-center">
|
|
<div class="container-xxl">
|
|
<h1 class="mb-3">عذراً</h1>
|
|
<p>هذه الصفحة مخصصة للمشرف العام فقط.</p>
|
|
<a href="index.php" class="btn btn-primary mt-3">العودة للرئيسية</a>
|
|
</div>
|
|
</section>
|
|
<?php
|
|
render_page_end();
|
|
exit;
|
|
}
|
|
|
|
|
|
$flash = consume_flash();
|
|
$errors = [];
|
|
|
|
// Handle form submission
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$action = $_POST['action'] ?? '';
|
|
if ($action === 'add') {
|
|
$cycleName = clean_text($_POST['cycle_name'] ?? '');
|
|
$startDate = $_POST['start_date'] ?? '';
|
|
$endDate = $_POST['end_date'] ?? '';
|
|
|
|
if ($cycleName === '') $errors['cycle_name'] = 'اسم الدورة مطلوب';
|
|
if ($startDate === '') $errors['start_date'] = 'تاريخ البداية مطلوب';
|
|
if ($endDate === '') $errors['end_date'] = 'تاريخ النهاية مطلوب';
|
|
|
|
if (empty($errors)) {
|
|
try {
|
|
$stmt = db()->prepare('INSERT INTO global_cycles (cycle_name, start_date, end_date) VALUES (?, ?, ?)');
|
|
$stmt->execute([$cycleName, $startDate, $endDate]);
|
|
set_flash('success', 'تم إضافة الدورة بنجاح.');
|
|
header('Location: global_cycles.php');
|
|
exit;
|
|
} catch (Throwable $e) {
|
|
$errors['form'] = 'حدث خطأ أثناء حفظ الدورة.';
|
|
}
|
|
}
|
|
} elseif ($action === 'toggle') {
|
|
$cycleId = filter_input(INPUT_POST, 'cycle_id', FILTER_VALIDATE_INT);
|
|
if ($cycleId) {
|
|
try {
|
|
$stmt = db()->prepare('UPDATE global_cycles SET is_active = NOT is_active WHERE id = ?');
|
|
$stmt->execute([$cycleId]);
|
|
set_flash('success', 'تم تغيير حالة الدورة.');
|
|
} catch (Throwable $e) {
|
|
set_flash('error', 'حدث خطأ.');
|
|
}
|
|
}
|
|
header('Location: global_cycles.php');
|
|
exit;
|
|
} elseif ($action === 'delete') {
|
|
$cycleId = filter_input(INPUT_POST, 'cycle_id', FILTER_VALIDATE_INT);
|
|
if ($cycleId) {
|
|
try {
|
|
$stmt = db()->prepare('DELETE FROM global_cycles WHERE id = ?');
|
|
$stmt->execute([$cycleId]);
|
|
set_flash('success', 'تم حذف الدورة بنجاح.');
|
|
} catch (Throwable $e) {
|
|
set_flash('error', 'لا يمكن حذف الدورة، ربما تكون مرتبطة بطلبات أخرى.');
|
|
}
|
|
}
|
|
header('Location: global_cycles.php');
|
|
exit;
|
|
} elseif ($action === 'edit') {
|
|
$cycleId = filter_input(INPUT_POST, 'cycle_id', FILTER_VALIDATE_INT);
|
|
$cycleName = clean_text($_POST['cycle_name'] ?? '');
|
|
$startDate = $_POST['start_date'] ?? '';
|
|
$endDate = $_POST['end_date'] ?? '';
|
|
|
|
if ($cycleId && $cycleName && $startDate && $endDate) {
|
|
try {
|
|
$stmt = db()->prepare('UPDATE global_cycles SET cycle_name = ?, start_date = ?, end_date = ? WHERE id = ?');
|
|
$stmt->execute([$cycleName, $startDate, $endDate, $cycleId]);
|
|
set_flash('success', 'تم تعديل الدورة بنجاح.');
|
|
} catch (Throwable $e) {
|
|
set_flash('error', 'حدث خطأ أثناء التعديل.');
|
|
}
|
|
}
|
|
header('Location: global_cycles.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Fetch cycles
|
|
$search = clean_text($_GET['search'] ?? '', 255);
|
|
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT) ?: 1;
|
|
$limit = 10;
|
|
$offset = ($page - 1) * $limit;
|
|
|
|
$cycles = [];
|
|
$totalItems = 0;
|
|
|
|
try {
|
|
$query = 'SELECT * FROM global_cycles';
|
|
$countQuery = 'SELECT COUNT(*) FROM global_cycles';
|
|
$params = [];
|
|
|
|
if ($search !== '') {
|
|
$where = ' WHERE cycle_name LIKE ?';
|
|
$query .= $where;
|
|
$countQuery .= $where;
|
|
$params[] = "%$search%";
|
|
}
|
|
|
|
$stmtCount = db()->prepare($countQuery);
|
|
$stmtCount->execute($params);
|
|
$totalItems = (int)$stmtCount->fetchColumn();
|
|
|
|
$query .= ' ORDER BY start_date DESC LIMIT ' . $limit . ' OFFSET ' . $offset;
|
|
$stmt = db()->prepare($query);
|
|
$stmt->execute($params);
|
|
$cycles = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (Throwable $e) {}
|
|
|
|
render_page_start('إدارة الدورات الموسمية', 'cycles', 'إضافة وإدارة الدورات التي تتقدم لها المراكز.');
|
|
render_flash($flash);
|
|
?>
|
|
<section class="py-4 py-lg-5">
|
|
<div class="container-xxl">
|
|
<div class="admin-layout row g-4 align-items-start">
|
|
<div class="col-lg-3 layout-sidebar-column">
|
|
<?php require __DIR__ . '/includes/sidebar.php'; ?>
|
|
</div>
|
|
<div class="col-lg-9 layout-content-column">
|
|
<div class="page-banner mb-4">
|
|
<div class="row align-items-center">
|
|
<div class="col-md-8">
|
|
<h1 class="page-title mb-2">الدورات الموسمية</h1>
|
|
<p class="page-copy mb-0">يمكنك هنا تعريف الدورات الجديدة ليتاح للمراكز التقديم عليها.</p>
|
|
</div>
|
|
<div class="col-md-4 text-md-end mt-3 mt-md-0">
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addCycleModal">
|
|
إضافة دورة جديدة
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!empty($errors['form'])): ?>
|
|
<div class="alert alert-danger mb-4"><?= e($errors['form']) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php render_search_bar($search, "ابحث باسم الدورة...", "global_cycles.php", $_GET); ?>
|
|
<div class="app-card table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>اسم الدورة</th>
|
|
<th>الفترة الزمنية</th>
|
|
<th>الحالة</th>
|
|
<th class="text-end">الإجراءات</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($cycles)): ?>
|
|
<tr>
|
|
<td colspan="4" class="text-center py-4 text-muted">لا توجد دورات مسجلة حالياً.</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($cycles as $cycle): ?>
|
|
<tr>
|
|
<td><strong><?= e((string)$cycle['cycle_name']) ?></strong></td>
|
|
<td>
|
|
<small class="text-muted d-block">من: <?= e((string)$cycle['start_date']) ?></small>
|
|
<small class="text-muted d-block">إلى: <?= e((string)$cycle['end_date']) ?></small>
|
|
</td>
|
|
<td>
|
|
<?php if ($cycle['is_active']): ?>
|
|
<span class="badge bg-success">متاحة للتقديم</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-secondary">مغلقة</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-end">
|
|
<div class="d-flex justify-content-end gap-2">
|
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#editCycleModal"
|
|
data-id="<?= e((string)$cycle['id']) ?>"
|
|
data-name="<?= e((string)$cycle['cycle_name']) ?>"
|
|
data-start="<?= e((string)$cycle['start_date']) ?>"
|
|
data-end="<?= e((string)$cycle['end_date']) ?>">
|
|
تعديل
|
|
</button>
|
|
<form method="post" class="d-inline-block m-0" onsubmit="return confirm('هل أنت متأكد من حذف هذه الدورة؟');">
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" name="cycle_id" value="<?= e((string)$cycle['id']) ?>">
|
|
<button type="submit" class="btn btn-sm btn-outline-danger">
|
|
حذف
|
|
</button>
|
|
</form>
|
|
<form method="post" class="d-inline-block m-0">
|
|
<input type="hidden" name="action" value="toggle">
|
|
<input type="hidden" name="cycle_id" value="<?= e((string)$cycle['id']) ?>">
|
|
<button type="submit" class="btn btn-sm <?= $cycle['is_active'] ? 'btn-outline-secondary' : 'btn-outline-success' ?>">
|
|
<?= $cycle['is_active'] ? 'إغلاق' : 'تفعيل' ?>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<?php render_pagination($totalItems, $limit, $page, $_GET); ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Add Cycle Modal -->
|
|
<div class="modal fade" id="addCycleModal" tabindex="-1" aria-labelledby="addCycleModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post">
|
|
<input type="hidden" name="action" value="add">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="addCycleModalLabel">إضافة دورة جديدة</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label" for="cycle_name">اسم الدورة</label>
|
|
<input type="text" class="form-control" id="cycle_name" name="cycle_name" required placeholder="مثال: الدورة الصيفية لعام 2026">
|
|
</div>
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="start_date">تاريخ البداية</label>
|
|
<input type="date" class="form-control" id="start_date" name="start_date" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="end_date">تاريخ النهاية</label>
|
|
<input type="date" class="form-control" id="end_date" name="end_date" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">إلغاء</button>
|
|
<button type="submit" class="btn btn-primary">حفظ الدورة</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Edit Cycle Modal -->
|
|
<div class="modal fade" id="editCycleModal" tabindex="-1" aria-labelledby="editCycleModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post">
|
|
<input type="hidden" name="action" value="edit">
|
|
<input type="hidden" name="cycle_id" id="edit_cycle_id">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="editCycleModalLabel">تعديل الدورة</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="إغلاق"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label" for="edit_cycle_name">اسم الدورة</label>
|
|
<input type="text" class="form-control" id="edit_cycle_name" name="cycle_name" required>
|
|
</div>
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="edit_start_date">تاريخ البداية</label>
|
|
<input type="date" class="form-control" id="edit_start_date" name="start_date" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="edit_end_date">تاريخ النهاية</label>
|
|
<input type="date" class="form-control" id="edit_end_date" name="end_date" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">إلغاء</button>
|
|
<button type="submit" class="btn btn-primary">حفظ التعديلات</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var editModal = document.getElementById('editCycleModal');
|
|
if(editModal) {
|
|
editModal.addEventListener('show.bs.modal', function (event) {
|
|
var button = event.relatedTarget;
|
|
var id = button.getAttribute('data-id');
|
|
var name = button.getAttribute('data-name');
|
|
var start = button.getAttribute('data-start');
|
|
var end = button.getAttribute('data-end');
|
|
|
|
editModal.querySelector('#edit_cycle_id').value = id;
|
|
editModal.querySelector('#edit_cycle_name').value = name;
|
|
editModal.querySelector('#edit_start_date').value = start;
|
|
editModal.querySelector('#edit_end_date').value = end;
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<?php render_page_end(); ?>
|