exam draft fix
This commit is contained in:
@@ -214,7 +214,17 @@
|
||||
<strong class="small mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
|
||||
<span class="badge <?= $badgeClass ?>"><?= esc($statusTag) ?></span>
|
||||
</div>
|
||||
<div class="small text-muted"><?= $report ? esc($report['unit_title'] ?: '-') : 'No submission' ?></div>
|
||||
<div class="small">
|
||||
<?php if ($report): ?>
|
||||
<?= view('admin/partials/class_progress_unit_display', [
|
||||
'unitTitle' => (string) ($report['unit_title'] ?? ''),
|
||||
'isQuran' => ($subjectName === 'Quran/Arabic'),
|
||||
'compact' => true,
|
||||
]) ?>
|
||||
<?php else: ?>
|
||||
<span class="text-muted">No submission</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
<?php
|
||||
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
|
||||
$isQuran = $subjectName === 'Quran/Arabic';
|
||||
$unitLabel = $isQuran ? 'Surah / Custom Arabic' : 'Unit / Chapter';
|
||||
$homeworkLabel = $isQuran ? 'Arabic Practice / Homework' : 'Assigned Homework';
|
||||
$report = $reportsBySubject[$subjectName] ?? null;
|
||||
?>
|
||||
@@ -51,7 +50,13 @@
|
||||
<?php if (! $report): ?>
|
||||
<div class="text-muted">No entry submitted for this subject this week.</div>
|
||||
<?php else: ?>
|
||||
<div class="mb-2"><strong><?= $unitLabel ?>:</strong> <?= esc($report['unit_title'] ?: '-') ?></div>
|
||||
<div class="mb-2">
|
||||
<?= view('admin/partials/class_progress_unit_display', [
|
||||
'unitTitle' => (string) ($report['unit_title'] ?? ''),
|
||||
'isQuran' => $isQuran,
|
||||
'compact' => false,
|
||||
]) ?>
|
||||
</div>
|
||||
<?php if (!empty($report['materials'])): ?>
|
||||
<div class="mb-2"><strong>Materials:</strong> <?= esc($report['materials']) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Renders class progress unit_title with explicit curriculum vs custom subject lines.
|
||||
*
|
||||
* @var string $unitTitle
|
||||
* @var bool $isQuran
|
||||
* @var bool $compact If true, tighter layout for the list accordion.
|
||||
*/
|
||||
|
||||
use App\Controllers\ClassProgressController;
|
||||
|
||||
$unitTitle = trim((string) ($unitTitle ?? ''));
|
||||
$compact = ! empty($compact);
|
||||
$isQuran = ! empty($isQuran);
|
||||
|
||||
$split = ClassProgressController::splitUnitTitleForDisplay($unitTitle);
|
||||
$curriculumLines = $split['curriculum'];
|
||||
$customTopics = $split['custom'];
|
||||
|
||||
$labelCurriculum = $isQuran ? 'Surah / curriculum' : 'Unit / chapter';
|
||||
$labelCustom = $isQuran ? 'Custom Surah / Arabic' : 'Custom subject(s)';
|
||||
?>
|
||||
|
||||
<?php if ($unitTitle === ''): ?>
|
||||
<span class="text-muted">-</span>
|
||||
<?php elseif ($compact): ?>
|
||||
<?php if (! empty($customTopics)): ?>
|
||||
<div class="small">
|
||||
<span class="badge text-bg-info me-1"><?= $isQuran ? 'Custom' : 'Custom subject' ?></span><?= esc(implode(', ', $customTopics)) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (! empty($curriculumLines)): ?>
|
||||
<div class="small <?= ! empty($customTopics) ? 'text-muted mt-1' : 'text-muted' ?>"><?= esc(implode(' · ', $curriculumLines)) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (empty($customTopics) && empty($curriculumLines)): ?>
|
||||
<div class="small text-muted"><?= esc($unitTitle) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<?php if (! empty($curriculumLines)): ?>
|
||||
<div class="mb-2"><strong><?= esc($labelCurriculum) ?>:</strong> <?= esc(implode(' ; ', $curriculumLines)) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (! empty($customTopics)): ?>
|
||||
<div class="mb-2"><strong><?= esc($labelCustom) ?>:</strong> <?= esc(implode(' ; ', $customTopics)) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if (empty($curriculumLines) && empty($customTopics)): ?>
|
||||
<div class="mb-2"><strong><?= esc($labelCurriculum) ?>:</strong> <?= esc($unitTitle) ?></div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
@@ -6,6 +6,9 @@ $drafts = $drafts ?? [];
|
||||
$legacyByClass = $legacyByClass ?? [];
|
||||
$classSections = $classSections ?? [];
|
||||
$examTypes = $examTypes ?? [];
|
||||
$visibleClasses = $visibleClasses ?? [];
|
||||
$classDraftGroups = $classDraftGroups ?? [];
|
||||
$newSubmissionClasses = $newSubmissionClasses ?? [];
|
||||
$schoolYear = $schoolYear ?? '';
|
||||
$semester = $semester ?? '';
|
||||
$maxUploadBytes = $maxUploadBytes ?? (12 * 1024 * 1024);
|
||||
@@ -56,172 +59,207 @@ $fileAccept = implode(',', array_map(static fn ($x) => '.' . $x, $allowedExtensi
|
||||
<div class="tab-pane fade show active" id="submissions" role="tabpanel" aria-labelledby="submissions-tab">
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<?php if (empty($drafts)): ?>
|
||||
<p class="text-muted mb-0">No exam drafts have been submitted yet.</p>
|
||||
<?php if (empty($visibleClasses)): ?>
|
||||
<p class="text-muted mb-0">No classes with enrolled students are available for this term.</p>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered align-middle mb-0 exam-drafts-table no-mgmt-sticky">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Teacher</th>
|
||||
<th>Class</th>
|
||||
<th>Title & AuthorNote</th>
|
||||
<th>Version</th>
|
||||
<th>Date-Time</th>
|
||||
<th>Status</th>
|
||||
<th>Files</th>
|
||||
<th>Reviewer Action</th>
|
||||
<th>Final version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($drafts as $draft): ?>
|
||||
<?php
|
||||
$teacherName = trim(($draft['teacher_first'] ?? '') . ' ' . ($draft['teacher_last'] ?? ''));
|
||||
if ($teacherName === '') {
|
||||
$teacherName = ($draft['admin_id'] ?? null) === ($draft['teacher_id'] ?? null)
|
||||
? 'Admin upload'
|
||||
: 'User #' . ($draft['teacher_id'] ?? 'N/A');
|
||||
}
|
||||
$st = strtolower((string) ($draft['status'] ?? ''));
|
||||
$adminName = trim(($draft['admin_first'] ?? '') . ' ' . ($draft['admin_last'] ?? ''));
|
||||
$authorNote = $draft['author_comment'] ?? $draft['description'] ?? '';
|
||||
$reviewerNote = $draft['reviewer_comment'] ?? $draft['admin_comments'] ?? '';
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($teacherName) ?></td>
|
||||
<td><?= esc($draft['class_section_name'] ?? 'Unknown') ?></td>
|
||||
<td>
|
||||
<strong><?= esc($draft['draft_title'] ?? 'Untitled') ?></strong>
|
||||
<div class="small text-muted"><?= esc($draft['exam_type'] ?? 'N/A') ?></div>
|
||||
<?php if ($authorNote !== ''): ?>
|
||||
<div class="small mt-1">
|
||||
<span class="text-muted fw-semibold">Author:</span>
|
||||
<?= esc($authorNote) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($reviewerNote !== ''): ?>
|
||||
<div class="small mt-1 border-top pt-1">
|
||||
<span class="text-muted fw-semibold">Reviewer:</span>
|
||||
<?= esc($reviewerNote) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-nowrap">v<?= esc((string) ($draft['version'] ?? 1)) ?></td>
|
||||
<td class="text-nowrap"><?= esc(!empty($draft['created_at']) ? local_datetime($draft['created_at'], 'M j, Y g:i A') : '—') ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$badgeData = $statusBadges[$st] ?? ['label' => $st, 'class' => 'bg-secondary text-white'];
|
||||
$badgeStyle = !empty($badgeData['style']) ? ' style="' . esc($badgeData['style']) . '"' : '';
|
||||
?>
|
||||
<span class="badge <?= esc($badgeData['class']) ?> js-status-badge" data-status="<?= esc($st) ?>"<?= $badgeStyle ?>>
|
||||
<?= esc($badgeData['label']) ?>
|
||||
</span>
|
||||
<div class="small text-muted mt-1 js-acceptance-note">
|
||||
<?php if ($st === 'accepted' && !empty($draft['acceptance_type'])): ?>
|
||||
<?= $draft['acceptance_type'] === 'minor_edits' ? 'Accepted w/ minor edits' : 'Accepted as is' ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (!empty($draft['reviewed_at'])): ?>
|
||||
<div class="small text-muted mt-1">
|
||||
Reviewed <?= esc(local_datetime($draft['reviewed_at'], 'M j, Y g:i A')) ?>
|
||||
<?php if ($adminName !== ''): ?>
|
||||
by <?= esc($adminName) ?>
|
||||
<div class="accordion exam-drafts-accordion" id="examDraftsAccordion">
|
||||
<?php foreach ($visibleClasses as $classSectionId => $classInfo): ?>
|
||||
<?php $classDraftsForSection = $classDraftGroups[$classSectionId] ?? []; ?>
|
||||
<?php $collapseId = 'classDraftGroup_' . $classSectionId; ?>
|
||||
<div class="accordion-item mb-3">
|
||||
<h2 class="accordion-header" id="heading_<?= esc($collapseId) ?>">
|
||||
<button class="accordion-button collapsed px-3" type="button" data-bs-toggle="collapse" data-bs-target="#<?= esc($collapseId) ?>" aria-expanded="false" aria-controls="<?= esc($collapseId) ?>">
|
||||
<div class="d-flex flex-column flex-lg-row w-100 justify-content-between gap-2">
|
||||
<div>
|
||||
<strong><?= esc($classInfo['class_section_name'] ?? ('Class ' . $classSectionId)) ?></strong>
|
||||
<div class="small text-muted">
|
||||
<?= esc($classInfo['student_count'] ?? 0) ?> students · <?= esc(count($classDraftsForSection)) ?> submissions
|
||||
<?php if (!empty($newSubmissionClasses[$classSectionId])): ?>
|
||||
<span class="badge bg-info text-dark ms-2">New submission</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php $formId = 'review_form_' . (int) ($draft['id'] ?? 0); ?>
|
||||
<?php $revNumber = max(1, (int) ($draft['version'] ?? 1)); ?>
|
||||
<?php if (!empty($draft['teacher_file'])): ?>
|
||||
<div>
|
||||
<a href="<?= base_url('exam-drafts/files/teacher/' . $draft['teacher_file']) ?>" target="_blank" rel="noopener">
|
||||
<?= esc('Ver' . $revNumber . ' ' . ($draft['teacher_filename'] ?? 'Submitted draft')) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<span class="text-muted small">No teacher file</span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($draft['final_file']) && strtolower((string) ($draft['status'] ?? '')) === 'accepted'): ?>
|
||||
<div class="mt-2">
|
||||
<a href="<?= base_url('exam-drafts/files/final/' . $draft['final_file']) ?>" target="_blank" rel="noopener" class="link-success small">
|
||||
<?= esc('Final ' . ($draft['final_filename'] ?? 'Final draft')) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($draft['review_files'])): ?>
|
||||
<div class="mt-2">
|
||||
<?php
|
||||
$reviewLinks = [];
|
||||
foreach ($draft['review_files'] as $rf) {
|
||||
$rev = max(1, (int) ($rf['review_revision'] ?? 1));
|
||||
$name = $rf['final_filename'] ?? 'Review file';
|
||||
$file = $rf['final_file'] ?? '';
|
||||
if ($file !== '') {
|
||||
$reviewLinks[] = '<a href="' . esc(base_url('exam-drafts/files/final/' . $file)) . '" target="_blank" rel="noopener" class="link-success small">' . esc('Ver' . $revNumber . '_' . $rev . ' ' . $name) . '</a>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?= !empty($reviewLinks) ? implode(' | ', $reviewLinks) : '' ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="mt-2">
|
||||
<?php $fileInputId = 'review_file_' . (int) ($draft['id'] ?? 0); ?>
|
||||
<input type="file" name="final_file" id="<?= esc($fileInputId) ?>" class="form-control form-control-sm" accept="<?= esc($fileAccept) ?>" form="<?= esc($formId) ?>">
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary mt-2" form="<?= esc($formId) ?>">Upload review file</button>
|
||||
</div>
|
||||
</td>
|
||||
<td style="min-width: 280px;">
|
||||
<?= form_open_multipart(base_url('administrator/exam-drafts/review'), ['class' => 'vstack gap-2', 'id' => $formId]) ?>
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="draft_id" value="<?= (int) ($draft['id'] ?? 0) ?>">
|
||||
<?php $selectedStatus = ''; ?>
|
||||
<select name="review_status" class="form-select form-select-sm" required>
|
||||
<option value="" <?= $selectedStatus === '' ? 'selected' : '' ?> disabled>— Select status —</option>
|
||||
<option value="accepted" <?= $selectedStatus === 'accepted' ? 'selected' : '' ?>>Accepted</option>
|
||||
<option value="legacy" <?= $selectedStatus === 'legacy' ? 'selected' : '' ?>>Legacy</option>
|
||||
<option value="canceled" <?= $selectedStatus === 'canceled' ? 'selected' : '' ?>>Canceled</option>
|
||||
<option value="rejected" <?= $selectedStatus === 'rejected' ? 'selected' : '' ?>>Rejected</option>
|
||||
<option value="review needed" <?= $selectedStatus === 'review needed' ? 'selected' : '' ?>>Review needed</option>
|
||||
<option value="under review" <?= $selectedStatus === 'under review' ? 'selected' : '' ?>>Under review</option>
|
||||
</select>
|
||||
<div class="small js-acceptance-group d-none">
|
||||
<span class="d-block mb-1">As is / Minor edits</span>
|
||||
<?php $acc = (string) ($draft['acceptance_type'] ?? ''); ?>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="acceptance_type" value="as_is" id="as_is_<?= (int) ($draft['id'] ?? 0) ?>" <?= $acc !== 'minor_edits' ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="as_is_<?= (int) ($draft['id'] ?? 0) ?>">As is</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="acceptance_type" value="minor_edits" id="minor_<?= (int) ($draft['id'] ?? 0) ?>" <?= $acc === 'minor_edits' ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="minor_<?= (int) ($draft['id'] ?? 0) ?>">Minor edits</label>
|
||||
</div>
|
||||
</div>
|
||||
<textarea name="reviewer_comment" class="form-control form-control-sm js-review-comment" rows="3" placeholder="Feedback for the teacher"><?= esc($draft['reviewer_comment'] ?? $draft['reviewer_comments'] ?? $draft['admin_comments'] ?? '') ?></textarea>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<span class="text-muted small js-review-status"></span>
|
||||
</div>
|
||||
<?= form_close() ?>
|
||||
</td>
|
||||
<td class="text-nowrap" style="min-width: 220px;">
|
||||
<?php
|
||||
$pdfFile = $draft['final_pdf_file'] ?? null;
|
||||
if (empty($pdfFile) && !empty($draft['final_file']) && strtolower(pathinfo($draft['final_file'], PATHINFO_EXTENSION)) === 'pdf') {
|
||||
$pdfFile = $draft['final_file'];
|
||||
}
|
||||
?>
|
||||
<?php if (!empty($pdfFile)): ?>
|
||||
<div class="mt-2 d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm btn-outline-primary" href="<?= base_url('exam-drafts/files/final/' . $pdfFile) ?>" target="_blank" rel="noopener">View</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="<?= base_url('exam-drafts/files/final/' . $pdfFile) ?>" target="_blank" rel="noopener" download>Download</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<span class="badge bg-secondary align-self-start">
|
||||
<?= esc(count($classDraftsForSection)) ?>
|
||||
<?= count($classDraftsForSection) === 1 ? 'submission' : 'submissions' ?>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="<?= esc($collapseId) ?>" class="accordion-collapse collapse" aria-labelledby="heading_<?= esc($collapseId) ?>">
|
||||
<div class="accordion-body pt-0 px-3">
|
||||
<?php if (empty($classDraftsForSection)): ?>
|
||||
<p class="text-muted mb-0">No submissions yet for this class.</p>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered align-middle mb-0 exam-drafts-table no-mgmt-sticky">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Teacher</th>
|
||||
<th>Class</th>
|
||||
<th>Title & AuthorNote</th>
|
||||
<th>Version</th>
|
||||
<th>Date-Time</th>
|
||||
<th>Status</th>
|
||||
<th>Files</th>
|
||||
<th>Reviewer Action</th>
|
||||
<th>Final version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($classDraftsForSection as $draft): ?>
|
||||
<?php
|
||||
$teacherName = trim(($draft['teacher_first'] ?? '') . ' ' . ($draft['teacher_last'] ?? ''));
|
||||
if ($teacherName === '') {
|
||||
$teacherName = ($draft['admin_id'] ?? null) === ($draft['teacher_id'] ?? null)
|
||||
? 'Admin upload'
|
||||
: 'User #' . ($draft['teacher_id'] ?? 'N/A');
|
||||
}
|
||||
$st = strtolower((string) ($draft['status'] ?? ''));
|
||||
$adminName = trim(($draft['admin_first'] ?? '') . ' ' . ($draft['admin_last'] ?? ''));
|
||||
$authorNote = $draft['author_comment'] ?? $draft['description'] ?? '';
|
||||
$reviewerNote = $draft['reviewer_comment'] ?? $draft['admin_comments'] ?? '';
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($teacherName) ?></td>
|
||||
<td><?= esc($draft['class_section_name'] ?? 'Unknown') ?></td>
|
||||
<td>
|
||||
<strong><?= esc($draft['draft_title'] ?? 'Untitled') ?></strong>
|
||||
<div class="small text-muted"><?= esc($draft['exam_type'] ?? 'N/A') ?></div>
|
||||
<?php if ($authorNote !== ''): ?>
|
||||
<div class="small mt-1">
|
||||
<span class="text-muted fw-semibold">Author:</span>
|
||||
<?= esc($authorNote) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($reviewerNote !== ''): ?>
|
||||
<div class="small mt-1 border-top pt-1">
|
||||
<span class="text-muted fw-semibold">Reviewer:</span>
|
||||
<?= esc($reviewerNote) ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-nowrap">v<?= esc((string) ($draft['version'] ?? 1)) ?></td>
|
||||
<td class="text-nowrap"><?= esc(!empty($draft['created_at']) ? local_datetime($draft['created_at'], 'M j, Y g:i A') : '—') ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$badgeData = $statusBadges[$st] ?? ['label' => $st, 'class' => 'bg-secondary text-white'];
|
||||
$badgeStyle = !empty($badgeData['style']) ? ' style="' . esc($badgeData['style']) . '"' : '';
|
||||
?>
|
||||
<span class="badge <?= esc($badgeData['class']) ?> js-status-badge" data-status="<?= esc($st) ?>"<?= $badgeStyle ?>>
|
||||
<?= esc($badgeData['label']) ?>
|
||||
</span>
|
||||
<div class="small text-muted mt-1 js-acceptance-note">
|
||||
<?php if ($st === 'accepted' && !empty($draft['acceptance_type'])): ?>
|
||||
<?= $draft['acceptance_type'] === 'minor_edits' ? 'Accepted w/ minor edits' : 'Accepted as is' ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (!empty($draft['reviewed_at'])): ?>
|
||||
<div class="small text-muted mt-1">
|
||||
Reviewed <?= esc(local_datetime($draft['reviewed_at'], 'M j, Y g:i A')) ?>
|
||||
<?php if ($adminName !== ''): ?>
|
||||
by <?= esc($adminName) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php $formId = 'review_form_' . (int) ($draft['id'] ?? 0); ?>
|
||||
<?php $revNumber = max(1, (int) ($draft['version'] ?? 1)); ?>
|
||||
<?php if (!empty($draft['teacher_file'])): ?>
|
||||
<div>
|
||||
<a href="<?= base_url('exam-drafts/files/teacher/' . $draft['teacher_file']) ?>" target="_blank" rel="noopener">
|
||||
<?= esc('Ver' . $revNumber . ' ' . ($draft['teacher_filename'] ?? 'Submitted draft')) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<span class="text-muted small">No teacher file</span>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($draft['final_file']) && strtolower((string) ($draft['status'] ?? '')) === 'accepted'): ?>
|
||||
<div class="mt-2">
|
||||
<a href="<?= base_url('exam-drafts/files/final/' . $draft['final_file']) ?>" target="_blank" rel="noopener" class="link-success small">
|
||||
<?= esc('Final ' . ($draft['final_filename'] ?? 'Final draft')) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($draft['review_files'])): ?>
|
||||
<div class="mt-2">
|
||||
<?php
|
||||
$reviewLinks = [];
|
||||
foreach ($draft['review_files'] as $rf) {
|
||||
$rev = max(1, (int) ($rf['review_revision'] ?? 1));
|
||||
$name = $rf['final_filename'] ?? 'Review file';
|
||||
$file = $rf['final_file'] ?? '';
|
||||
if ($file !== '') {
|
||||
$reviewLinks[] = '<a href="' . esc(base_url('exam-drafts/files/final/' . $file)) . '" target="_blank" rel="noopener" class="link-success small">' . esc('Ver' . $revNumber . '_' . $rev . ' ' . $name) . '</a>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?= !empty($reviewLinks) ? implode(' | ', $reviewLinks) : '' ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="mt-2">
|
||||
<?php $fileInputId = 'review_file_' . (int) ($draft['id'] ?? 0); ?>
|
||||
<input type="file" name="final_file" id="<?= esc($fileInputId) ?>" class="form-control form-control-sm" accept="<?= esc($fileAccept) ?>" form="<?= esc($formId) ?>">
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary mt-2" form="<?= esc($formId) ?>">Upload review file</button>
|
||||
</div>
|
||||
</td>
|
||||
<td style="min-width: 280px;">
|
||||
<?= form_open_multipart(base_url('administrator/exam-drafts/review'), ['class' => 'vstack gap-2', 'id' => $formId]) ?>
|
||||
<?= csrf_field() ?>
|
||||
<input type="hidden" name="draft_id" value="<?= (int) ($draft['id'] ?? 0) ?>">
|
||||
<?php $selectedStatus = ''; ?>
|
||||
<select name="review_status" class="form-select form-select-sm" required>
|
||||
<option value="" <?= $selectedStatus === '' ? 'selected' : '' ?> disabled>— Select status —</option>
|
||||
<option value="accepted" <?= $selectedStatus === 'accepted' ? 'selected' : '' ?>>Accepted</option>
|
||||
<option value="legacy" <?= $selectedStatus === 'legacy' ? 'selected' : '' ?>>Legacy</option>
|
||||
<option value="canceled" <?= $selectedStatus === 'canceled' ? 'selected' : '' ?>>Canceled</option>
|
||||
<option value="rejected" <?= $selectedStatus === 'rejected' ? 'selected' : '' ?>>Rejected</option>
|
||||
<option value="review needed" <?= $selectedStatus === 'review needed' ? 'selected' : '' ?>>Review needed</option>
|
||||
<option value="under review" <?= $selectedStatus === 'under review' ? 'selected' : '' ?>>Under review</option>
|
||||
</select>
|
||||
<div class="small js-acceptance-group d-none">
|
||||
<span class="d-block mb-1">As is / Minor edits</span>
|
||||
<?php $acc = (string) ($draft['acceptance_type'] ?? ''); ?>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="acceptance_type" value="as_is" id="as_is_<?= (int) ($draft['id'] ?? 0) ?>" <?= $acc !== 'minor_edits' ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="as_is_<?= (int) ($draft['id'] ?? 0) ?>">As is</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" name="acceptance_type" value="minor_edits" id="minor_<?= (int) ($draft['id'] ?? 0) ?>" <?= $acc === 'minor_edits' ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="minor_<?= (int) ($draft['id'] ?? 0) ?>">Minor edits</label>
|
||||
</div>
|
||||
</div>
|
||||
<textarea name="reviewer_comment" class="form-control form-control-sm js-review-comment" rows="3" placeholder="Feedback for the teacher"><?= esc($draft['reviewer_comment'] ?? $draft['reviewer_comments'] ?? $draft['admin_comments'] ?? '') ?></textarea>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<span class="text-muted small js-review-status"></span>
|
||||
</div>
|
||||
<?= form_close() ?>
|
||||
</td>
|
||||
<td class="text-nowrap" style="min-width: 220px;">
|
||||
<?php
|
||||
$pdfFile = $draft['final_pdf_file'] ?? null;
|
||||
if (empty($pdfFile) && !empty($draft['final_file']) && strtolower(pathinfo($draft['final_file'], PATHINFO_EXTENSION)) === 'pdf') {
|
||||
$pdfFile = $draft['final_file'];
|
||||
}
|
||||
?>
|
||||
<?php if (!empty($pdfFile)): ?>
|
||||
<div class="mt-2 d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm btn-outline-primary" href="<?= base_url('exam-drafts/files/final/' . $pdfFile) ?>" target="_blank" rel="noopener">View</a>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="<?= base_url('exam-drafts/files/final/' . $pdfFile) ?>" target="_blank" rel="noopener" download>Download</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -319,6 +357,12 @@ $fileAccept = implode(',', array_map(static fn ($x) => '.' . $x, $allowedExtensi
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const submissionsTab = document.getElementById('submissions-tab');
|
||||
if (submissionsTab) {
|
||||
submissionsTab.addEventListener('click', () => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
const statusBadges = <?= json_encode($statusBadges, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) ?>;
|
||||
const csrfTokenName = <?= json_encode(csrf_token(), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) ?>;
|
||||
const csrfCookieNames = <?= json_encode(array_values(array_filter([
|
||||
|
||||
@@ -121,6 +121,21 @@
|
||||
<input class="form-check-input" type="checkbox" name="notify_exam_draft" id="notifyExamDraft" value="1">
|
||||
<label class="form-check-label small" for="notifyExamDraft">Include</label>
|
||||
</div>
|
||||
<?php
|
||||
$examDraftDeadlineConfig = $examDraftDeadlineConfig ?? '';
|
||||
$examDraftDeadlineFormatted = $examDraftDeadlineFormatted ?? '';
|
||||
?>
|
||||
<div class="small fw-normal text-muted mt-2 text-wrap">
|
||||
<span class="text-uppercase" style="font-size:0.65rem;">exam_draft_deadline</span><br>
|
||||
<?php if ($examDraftDeadlineConfig !== ''): ?>
|
||||
<?= esc($examDraftDeadlineConfig) ?>
|
||||
<?php if ($examDraftDeadlineFormatted !== ''): ?>
|
||||
<span class="text-muted"> → <?= esc($examDraftDeadlineFormatted) ?></span>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<span class="text-warning">Not set</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text-center">
|
||||
Homework
|
||||
|
||||
@@ -183,6 +183,14 @@
|
||||
</div>
|
||||
<div class="form-text small text-muted">Add a custom Surah or Arabic target.</div>
|
||||
</div>
|
||||
<?php elseif ($slug === 'islamic'): ?>
|
||||
<div class="px-2 py-2 border-top">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" placeholder="Type subject or topic" data-custom-input data-subject="<?= esc($slug) ?>">
|
||||
<button type="button" class="btn btn-outline-secondary" data-custom-entry data-subject="<?= esc($slug) ?>">Add</button>
|
||||
</div>
|
||||
<div class="form-text small text-muted">Add a subject or unit not listed above (e.g. Seerah, Fiqh, Akhlaq).</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -385,6 +393,9 @@
|
||||
if (isQuran) {
|
||||
return isCustom ? 'Custom' : 'Surah';
|
||||
}
|
||||
if (subject === 'islamic' && isCustom) {
|
||||
return 'Custom';
|
||||
}
|
||||
return parts.join(' – ');
|
||||
};
|
||||
|
||||
@@ -445,7 +456,10 @@
|
||||
if (!input) return;
|
||||
const customValue = input.value.trim();
|
||||
if (customValue === '') return;
|
||||
const unitValue = buildUnitDisplay(subject, '', '', { isQuran: subject === 'quran', isCustom: true });
|
||||
const unitValue = buildUnitDisplay(subject, '', '', {
|
||||
isQuran: subject === 'quran',
|
||||
isCustom: subject === 'quran' || subject === 'islamic',
|
||||
});
|
||||
appendUnitChapterRow(subject, unitValue, customValue);
|
||||
input.value = '';
|
||||
hideMenus();
|
||||
|
||||
Reference in New Issue
Block a user