216 lines
10 KiB
PHP
216 lines
10 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/includes/app.php';
|
|
|
|
$templateId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) ?: 0;
|
|
if ($templateId <= 0) {
|
|
set_flash('error', 'اختر قالب التقييم أولاً.');
|
|
header('Location: global_center_assessments.php');
|
|
exit;
|
|
}
|
|
|
|
$template = get_global_center_assessment_type($templateId);
|
|
if (!$template) {
|
|
set_flash('error', 'القالب غير موجود.');
|
|
header('Location: global_center_assessments.php');
|
|
exit;
|
|
}
|
|
|
|
$requestedCycleName = $_GET['cycle'] ?? '';
|
|
|
|
// Fetch distinct cycle names from active cycles
|
|
$pdo = db();
|
|
$cyclesStmt = $pdo->query("SELECT DISTINCT cycle_name FROM school_cycles WHERE status != 'archived' ORDER BY cycle_name ASC");
|
|
$cycles = $cyclesStmt->fetchAll(PDO::FETCH_COLUMN) ?: [];
|
|
|
|
// Find default cycle if not selected
|
|
if (empty($requestedCycleName) && count($cycles) > 0) {
|
|
$requestedCycleName = $cycles[0];
|
|
}
|
|
|
|
// Action: assess a specific center
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'assess') {
|
|
$centerId = filter_input(INPUT_POST, 'center_id', FILTER_VALIDATE_INT) ?: 0;
|
|
$cycleId = filter_input(INPUT_POST, 'cycle_id', FILTER_VALIDATE_INT) ?: 0;
|
|
$cycleName = $_POST['cycle_name'] ?? '';
|
|
|
|
if ($centerId > 0 && $cycleId > 0) {
|
|
// Check if already imported
|
|
$stmt = $pdo->prepare('SELECT id FROM center_assessment_types WHERE center_application_id = :center_id AND cycle_id = :cycle_id AND global_template_id = :template_id LIMIT 1');
|
|
$stmt->execute([
|
|
':center_id' => $centerId,
|
|
':cycle_id' => $cycleId,
|
|
':template_id' => $templateId
|
|
]);
|
|
$existingAssessmentId = $stmt->fetchColumn();
|
|
|
|
if ($existingAssessmentId) {
|
|
$assessmentId = (int)$existingAssessmentId;
|
|
} else {
|
|
// Import it
|
|
try {
|
|
$assessmentId = import_global_center_assessment_to_center($templateId, $centerId, $cycleId);
|
|
} catch (Exception $e) {
|
|
set_flash('error', 'فشل استيراد التقييم للمركز.');
|
|
header("Location: execute_global_assessment.php?id={$templateId}&cycle=" . urlencode($cycleName));
|
|
exit;
|
|
}
|
|
}
|
|
|
|
$returnUrl = urlencode("execute_global_assessment.php?id={$templateId}&cycle=" . urlencode($cycleName));
|
|
header("Location: center_assessment_score_sheet.php?id={$centerId}&cycle={$cycleId}&assessment_id={$assessmentId}&return_url={$returnUrl}");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// Fetch all approved centers and their assessment status for this template
|
|
$centers = [];
|
|
if (!empty($requestedCycleName)) {
|
|
// Join with school_cycles by cycle_name, then left join with center_assessment_types and center_assessment_scores
|
|
$query = "
|
|
SELECT
|
|
c.id, c.center_name, c.city,
|
|
sc.id AS center_cycle_id,
|
|
cat.id AS assessment_type_id,
|
|
cas.status AS score_status,
|
|
cas.score,
|
|
cas.max_score
|
|
FROM center_applications c
|
|
JOIN school_cycles sc ON sc.center_application_id = c.id AND sc.cycle_name = :cycle_name
|
|
LEFT JOIN center_assessment_types cat ON cat.center_application_id = c.id
|
|
AND cat.cycle_id = sc.id
|
|
AND cat.global_template_id = :template_id
|
|
LEFT JOIN center_assessment_scores cas ON cas.assessment_type_id = cat.id
|
|
WHERE c.status = 'approved'
|
|
ORDER BY c.center_name ASC
|
|
";
|
|
$stmt = $pdo->prepare($query);
|
|
$stmt->execute([
|
|
':cycle_name' => $requestedCycleName,
|
|
':template_id' => $templateId
|
|
]);
|
|
$centers = $stmt->fetchAll() ?: [];
|
|
}
|
|
|
|
$pageTitle = 'تطبيق التقييم: ' . (string) ($template['title'] ?? '');
|
|
$pageDescription = 'تنفيذ التقييم العام على المراكز المعتمدة.';
|
|
render_page_start($pageTitle, 'admin', $pageDescription);
|
|
$flash = consume_flash();
|
|
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 admin-hero mb-4">
|
|
<div class="row g-4 align-items-center">
|
|
<div class="col-lg-8">
|
|
<span class="admin-kicker mb-3">تطبيق قالب التقييم</span>
|
|
<h1 class="page-title mb-3"><?= e((string) ($template['title'] ?? '')) ?></h1>
|
|
<p class="page-copy mb-3">من هذه الشاشة يمكنك المرور على جميع المراكز ورصد درجاتها بناءً على هذا القالب الموحد.</p>
|
|
<div class="hero-meta">
|
|
<span>الوزن: <?= e((string) ($template['weight_percentage'] ?? '0')) ?>%</span>
|
|
<span>الدرجة القصوى: <?= e((string) ($template['max_score'] ?? '0')) ?></span>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-4 text-lg-end">
|
|
<a class="btn btn-outline-secondary" href="global_center_assessments.php">العودة للقوالب</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="app-card mb-4">
|
|
<form method="get" class="row g-3 align-items-end">
|
|
<input type="hidden" name="id" value="<?= e((string)$templateId) ?>">
|
|
<div class="col-md-8">
|
|
<label class="form-label" for="cycle">الدورة المستهدفة</label>
|
|
<select class="form-select" id="cycle" name="cycle" onchange="this.form.submit()">
|
|
<?php if (count($cycles) === 0): ?>
|
|
<option value="">لا توجد دورات</option>
|
|
<?php else: ?>
|
|
<?php foreach ($cycles as $c): ?>
|
|
<option value="<?= e((string)$c) ?>" <?= $c === $requestedCycleName ? 'selected' : '' ?>>
|
|
<?= e((string)$c) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4 d-grid">
|
|
<button type="submit" class="btn btn-primary">عرض المراكز</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<?php if (!empty($requestedCycleName) && count($centers) > 0): ?>
|
|
<div class="app-card">
|
|
<div class="table-responsive">
|
|
<table class="table app-table align-middle mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>المركز</th>
|
|
<th>المنطقة</th>
|
|
<th>الحالة</th>
|
|
<th>الدرجة</th>
|
|
<th class="text-end">الإجراءات</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($centers as $center):
|
|
$status = (string) ($center['score_status'] ?? '');
|
|
$hasScore = $center['score'] !== null;
|
|
$scoreVal = $hasScore ? rtrim(rtrim(number_format((float)$center['score'], 2, '.', ''), '0'), '.') : '—';
|
|
$maxScore = $center['max_score'] !== null ? rtrim(rtrim(number_format((float)$center['max_score'], 2, '.', ''), '0'), '.') : '';
|
|
|
|
$statusBadge = '<span class="badge bg-secondary">لم يبدأ الرصد</span>';
|
|
if ($status === 'draft') $statusBadge = '<span class="badge bg-warning text-dark">مسودة</span>';
|
|
if ($status === 'completed') $statusBadge = '<span class="badge bg-success">مكتمل</span>';
|
|
if ($status === 'waived') $statusBadge = '<span class="badge bg-info">مستثنى</span>';
|
|
?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-semibold"><?= e((string) ($center['center_name'] ?? '')) ?></div>
|
|
</td>
|
|
<td><?= e((string) ($center['city'] ?? '—')) ?></td>
|
|
<td><?= $statusBadge ?></td>
|
|
<td>
|
|
<?php if ($hasScore): ?>
|
|
<span class="fw-bold"><?= e($scoreVal) ?></span> / <?= e($maxScore) ?>
|
|
<?php else: ?>
|
|
<span class="text-muted">—</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-end">
|
|
<form method="post" style="display:inline-block;">
|
|
<input type="hidden" name="action" value="assess">
|
|
<input type="hidden" name="center_id" value="<?= e((string)$center['id']) ?>">
|
|
<input type="hidden" name="cycle_id" value="<?= e((string)$center['center_cycle_id']) ?>">
|
|
<input type="hidden" name="cycle_name" value="<?= e((string)$requestedCycleName) ?>">
|
|
<?php if ($status === 'completed'): ?>
|
|
<button type="submit" class="btn btn-sm btn-outline-primary">تعديل الرصد</button>
|
|
<?php else: ?>
|
|
<button type="submit" class="btn btn-sm btn-primary">رصد</button>
|
|
<?php endif; ?>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<?php elseif (!empty($requestedCycleName)): ?>
|
|
<div class="app-card text-center py-5">
|
|
<div class="empty-title mb-2">لا توجد مراكز معتمدة</div>
|
|
<p class="text-muted">لم يتم العثور على مراكز معتمدة لتقييمها في هذه الدورة.</p>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php render_page_end(); ?>
|