150 lines
8.4 KiB
PHP
150 lines
8.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/includes/app.php';
|
|
|
|
$flash = consume_flash();
|
|
$applicationId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) ?: 0;
|
|
$application = $applicationId > 0 ? get_application($applicationId) : null;
|
|
|
|
if (!$application) {
|
|
http_response_code(404);
|
|
render_page_start('طلب غير موجود', 'applications', 'لم يتم العثور على طلب فتح المركز المطلوب.');
|
|
render_flash($flash);
|
|
?>
|
|
<section class="py-5">
|
|
<div class="container-xxl">
|
|
<div class="app-card text-center py-5">
|
|
<div class="empty-title mb-2">الطلب غير موجود</div>
|
|
<p class="text-muted mb-3">تحقق من رقم المرجع أو ارجع إلى لوحة الطلبات.</p>
|
|
<a class="btn btn-dark" href="applications.php">العودة إلى القائمة</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php
|
|
render_page_end();
|
|
exit;
|
|
}
|
|
|
|
$reviewErrors = [];
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$status = clean_text((string) ($_POST['status'] ?? 'submitted'), 30);
|
|
$adminNotes = clean_text((string) ($_POST['admin_notes'] ?? ''), 1000);
|
|
$evaluationScore = filter_var($_POST['evaluation_score'] ?? null, FILTER_VALIDATE_INT, [
|
|
'options' => ['min_range' => 0, 'max_range' => 100],
|
|
]);
|
|
|
|
if (($_POST['evaluation_score'] ?? '') !== '' && $evaluationScore === false) {
|
|
$reviewErrors['evaluation_score'] = 'أدخل درجة بين 0 و100.';
|
|
}
|
|
|
|
if ($reviewErrors === []) {
|
|
try {
|
|
update_application_review($applicationId, $status, $adminNotes, $evaluationScore === false ? null : $evaluationScore);
|
|
set_flash('success', 'تم تحديث حالة الطلب وملاحظات التقييم بنجاح.');
|
|
header('Location: application_detail.php?id=' . urlencode((string) $applicationId));
|
|
exit;
|
|
} catch (Throwable $exception) {
|
|
$reviewErrors['form'] = 'تعذر حفظ التحديث الآن. حاول مرة أخرى.';
|
|
}
|
|
}
|
|
}
|
|
|
|
$application = get_application($applicationId);
|
|
$statusMeta = status_meta((string) $application['status']);
|
|
|
|
render_page_start('تفاصيل الطلب #' . $applicationId, 'applications', 'عرض تفصيلي لطلب فتح المركز مع نموذج المراجعة للمشرف العام.');
|
|
render_flash($flash);
|
|
?>
|
|
<section class="py-4 py-lg-5">
|
|
<div class="container-xxl">
|
|
<div class="row g-4 align-items-start">
|
|
<div class="col-lg-8">
|
|
<div class="app-card detail-card mb-4">
|
|
<div class="section-head mb-4">
|
|
<div>
|
|
<div class="eyebrow mb-2">مرجع الطلب #<?= e((string) $application['id']) ?></div>
|
|
<div class="section-title"><?= e((string) $application['center_name']) ?></div>
|
|
<div class="section-copy">مقدم الطلب: <?= e((string) $application['director_name']) ?> — <?= e((string) $application['city']) ?></div>
|
|
</div>
|
|
<?= status_badge((string) $application['status']) ?>
|
|
</div>
|
|
|
|
<div class="row g-3 detail-grid">
|
|
<div class="col-md-6"><div class="detail-item"><span>نوع المركز</span><strong><?= e((string) $application['center_type']) ?></strong></div></div>
|
|
<div class="col-md-6"><div class="detail-item"><span>الفئة المستهدفة</span><strong><?= e((string) $application['gender_scope']) ?></strong></div></div>
|
|
<div class="col-md-6"><div class="detail-item"><span>رقم الهاتف</span><strong><?= e((string) $application['phone']) ?></strong></div></div>
|
|
<div class="col-md-6"><div class="detail-item"><span>البريد الإلكتروني</span><strong><?= e((string) $application['email']) ?></strong></div></div>
|
|
<div class="col-md-6"><div class="detail-item"><span>السعة المتوقعة</span><strong><?= e((string) $application['expected_students']) ?> طالب</strong></div></div>
|
|
<div class="col-md-6"><div class="detail-item"><span>فترة البرنامج</span><strong><?= e((string) $application['start_date']) ?> — <?= e((string) $application['end_date']) ?></strong></div></div>
|
|
</div>
|
|
|
|
<div class="notes-block mt-4">
|
|
<div class="section-title small-title mb-2">ملخص البرنامج والاحتياجات</div>
|
|
<p class="mb-0 text-muted"><?= nl2br(e((string) ($application['notes'] ?: 'لا توجد ملاحظات إضافية.'))) ?></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="app-card detail-card">
|
|
<div class="section-title mb-3">سجل المراجعة</div>
|
|
<div class="timeline-list">
|
|
<div class="timeline-item">
|
|
<div class="timeline-title">تم استلام الطلب</div>
|
|
<div class="timeline-copy text-muted">أُرسل الطلب بتاريخ <?= e((string) $application['submitted_at']) ?>.</div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<div class="timeline-title">الحالة الحالية: <?= e($statusMeta['label']) ?></div>
|
|
<div class="timeline-copy text-muted">آخر تحديث بتاريخ <?= e((string) $application['updated_at']) ?>.</div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<div class="timeline-title">ملاحظات المشرف العام</div>
|
|
<div class="timeline-copy text-muted"><?= nl2br(e((string) ($application['admin_notes'] ?: 'لم تُسجل ملاحظات بعد.'))) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-4">
|
|
<div class="app-card sidebar-card mb-4">
|
|
<div class="section-title mb-3">ملخص القرار</div>
|
|
<div class="summary-stack">
|
|
<div class="summary-row"><span>الحالة</span><strong><?= e($statusMeta['label']) ?></strong></div>
|
|
<div class="summary-row"><span>درجة الاستعداد</span><strong><?= $application['evaluation_score'] !== null ? e((string) $application['evaluation_score']) . '%' : 'غير محددة' ?></strong></div>
|
|
<div class="summary-row"><span>آخر تحديث</span><strong><?= e((string) $application['updated_at']) ?></strong></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="app-card sidebar-card">
|
|
<div class="section-title mb-3">إجراء المشرف العام</div>
|
|
<?php if (!empty($reviewErrors['form'])): ?>
|
|
<div class="alert alert-danger"><?= e($reviewErrors['form']) ?></div>
|
|
<?php endif; ?>
|
|
<form method="post" novalidate>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="status">حالة الطلب</label>
|
|
<select class="form-select" id="status" name="status">
|
|
<?php foreach (status_map() as $value => $meta): ?>
|
|
<option value="<?= e($value) ?>" <?= (string) $application['status'] === $value ? 'selected' : '' ?>><?= e($meta['label']) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="evaluation_score">درجة التقييم الأولي</label>
|
|
<input type="number" min="0" max="100" class="form-control <?= isset($reviewErrors['evaluation_score']) ? 'is-invalid' : '' ?>" id="evaluation_score" name="evaluation_score" value="<?= e((string) ($application['evaluation_score'] ?? '')) ?>" placeholder="مثال: 85">
|
|
<?php if (isset($reviewErrors['evaluation_score'])): ?><div class="invalid-feedback"><?= e($reviewErrors['evaluation_score']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="admin_notes">ملاحظات التقييم</label>
|
|
<textarea class="form-control" id="admin_notes" name="admin_notes" rows="5" placeholder="سجّل نقاط القوة أو النواقص المطلوب استكمالها."><?= e((string) ($application['admin_notes'] ?? '')) ?></textarea>
|
|
</div>
|
|
<div class="d-grid gap-2">
|
|
<button class="btn btn-dark" type="submit">حفظ التحديث</button>
|
|
<a class="btn btn-outline-secondary" href="applications.php">العودة إلى القائمة</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php render_page_end(); ?>
|