Files
alrahma_sunday_school/app/Views/teacher/drafts.php
T
2026-04-08 19:45:47 -04:00

232 lines
12 KiB
PHP

<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<?php
$statusBadges = $statusBadges ?? [];
$drafts = $drafts ?? [];
$legacyExams = $legacyExams ?? [];
$assignments = $assignments ?? [];
$selectedClassSection = $selectedClassSection ?? 0;
$examTypes = $examTypes ?? [];
$schoolYear = $schoolYear ?? '';
$semester = $semester ?? '';
$maxUploadBytes = $maxUploadBytes ?? (12 * 1024 * 1024);
?>
<div class="container-xxl py-5">
<div class="container">
<h1 class="mb-4">Exam drafts</h1>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success"><?= esc(session()->getFlashdata('success')) ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger"><?= esc(session()->getFlashdata('error')) ?></div>
<?php endif; ?>
<div class="card mb-4">
<div class="card-body">
<?= form_open_multipart(base_url('teacher/exam-drafts'), ['class' => 'row g-3']) ?>
<?= csrf_field() ?>
<div class="col-md-6">
<label class="form-label" for="exam_type">Exam type <span class="text-danger">*</span></label>
<select name="exam_type" id="exam_type" class="form-select" required>
<option value="">— Select —</option>
<?php foreach ($examTypes as $t): ?>
<option value="<?= esc($t) ?>" <?= old('exam_type') === $t ? 'selected' : '' ?>><?= esc($t) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-8">
<label class="form-label" for="author_comment">Author comment</label>
<textarea name="author_comment" id="author_comment" class="form-control" rows="2" placeholder="Optional note for reviewers"><?= esc(old('author_comment') ?? '') ?></textarea>
</div>
<div class="col-md-8">
<label class="form-label" for="draft_file">File (Word) <span class="text-danger">*</span></label>
<input type="file" name="draft_file" id="draft_file" class="form-control" accept=".doc,.docx" required>
<div class="form-text">Max <?= esc(number_format($maxUploadBytes / 1048576, 1)) ?> MB.</div>
</div>
<div class="col-12 d-flex flex-wrap gap-2">
<button type="submit" class="btn btn-primary">Submit for review</button>
</div>
<?= form_close() ?>
<?php if ($schoolYear !== '' || $semester !== ''): ?>
<p class="text-muted small mb-0 mt-2">School year: <?= esc($schoolYear) ?> · Semester: <?= esc($semester) ?></p>
<?php endif; ?>
</div>
</div>
<?php
$renderBadge = static function (string $status, array $badges): string {
$b = $badges[$status] ?? ['label' => $status, 'class' => 'bg-secondary text-white'];
$style = !empty($b['style']) ? ' style="' . esc($b['style']) . '"' : '';
return '<span class="badge ' . esc($b['class']) . ' js-status-badge" data-status="' . esc($status) . '"' . $style . '>' . esc($b['label']) . '</span>';
};
?>
<h2 class="h5 mb-3">Your submissions</h2>
<?php if (!empty($drafts)): ?>
<div class="table-responsive">
<table class="table table-striped align-middle">
<thead>
<tr>
<th>Class</th>
<th>Title / type</th>
<th>Ver.</th>
<th>Status</th>
<th>File link</th>
<th>Reviewer comment</th>
<th>Last Update</th>
</tr>
</thead>
<tbody>
<?php foreach ($drafts as $d): ?>
<?php
$st = strtolower((string) ($d['status'] ?? ''));
$badgeHtml = $renderBadge($st, $statusBadges);
?>
<tr data-draft-id="<?= (int) ($d['id'] ?? 0) ?>">
<td><?= esc($d['class_section_name'] ?? '') ?></td>
<td><?= esc($d['draft_title'] ?? $d['exam_type'] ?? '') ?></td>
<td><?= esc((string) ($d['version'] ?? '')) ?></td>
<td><?= $badgeHtml ?></td>
<td>
<?php $revNumber = max(1, (int) ($d['version'] ?? 1)); ?>
<?php if (!empty($d['teacher_file'])): ?>
<div>
<a href="<?= base_url('exam-drafts/files/teacher/' . $d['teacher_file']) ?>" target="_blank" rel="noopener">
<?= esc('Ver' . $revNumber . ' ' . ($d['teacher_filename'] ?? 'Submitted draft')) ?>
</a>
</div>
<?php endif; ?>
<?php if (!empty($d['final_file'])): ?>
<div class="mt-1">
<a href="<?= base_url('exam-drafts/files/final/' . $d['final_file']) ?>" target="_blank" rel="noopener" class="link-success small">
<?= esc('Final ' . ($d['final_filename'] ?? 'Final draft')) ?>
</a>
</div>
<?php endif; ?>
<?php if (!empty($d['review_files'])): ?>
<div class="mt-1">
<?php
$reviewLinks = [];
foreach ($d['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; ?>
<?php if (empty($d['teacher_file']) && empty($d['final_file'])): ?>
<?php endif; ?>
</td>
<td class="text-nowrap"><?= esc($d['reviewer_comment'] ?? $d['admin_comments'] ?? '—') ?></td>
<td><?= esc(!empty($d['updated_at']) ? local_datetime($d['updated_at'], 'm-d-Y H:i') : '') ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<p class="text-muted">No submissions yet.</p>
<?php endif; ?>
<?php if (!empty($legacyExams)): ?>
<h2 class="h5 mt-5 mb-3">Previous exams (legacy)</h2>
<div class="table-responsive">
<table class="table table-sm table-striped align-middle">
<thead>
<tr>
<th>Class</th>
<th>Title</th>
<th>Ver.</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($legacyExams as $d): ?>
<?php $st = strtolower((string) ($d['status'] ?? '')); ?>
<tr>
<td><?= esc($d['class_section_name'] ?? '') ?></td>
<td><?= esc($d['draft_title'] ?? $d['exam_type'] ?? '') ?></td>
<td><?= esc((string) ($d['version'] ?? '')) ?></td>
<td><?= $renderBadge($st, $statusBadges) ?></td>
<td>
<?php if (!empty($d['is_printable'])): ?>
<a class="btn btn-sm btn-outline-primary" href="<?= base_url('teacher/exam-drafts/print/' . (int) ($d['id'] ?? 0)) ?>" target="_blank" rel="noopener">Print</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<?= $this->endSection() ?>
<script>
document.addEventListener('DOMContentLoaded', () => {
const statusBadges = <?= json_encode($statusBadges, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) ?>;
const rows = new Map();
document.querySelectorAll('tr[data-draft-id]').forEach((row) => {
const id = row.getAttribute('data-draft-id');
if (id) {
rows.set(id, row);
}
});
const updateRow = (row, status, acceptanceType) => {
const badge = row.querySelector('.js-status-badge');
if (badge) {
const badgeData = statusBadges[status] || { label: status, class: 'bg-secondary text-white' };
badge.textContent = badgeData.label || status;
badge.className = `badge ${badgeData.class} js-status-badge`;
if (badgeData.style) {
badge.setAttribute('style', badgeData.style);
} else {
badge.removeAttribute('style');
}
badge.dataset.status = status;
}
const note = row.querySelector('.js-acceptance-note');
if (note) {
if (status === 'accepted' && acceptanceType) {
note.textContent = acceptanceType === 'minor_edits' ? 'With minor edits' : 'As is';
} else {
note.textContent = '—';
}
}
};
const poll = () => {
fetch('<?= base_url('teacher/exam-drafts/status') ?>', { headers: { 'X-Requested-With': 'XMLHttpRequest' } })
.then((resp) => resp.ok ? resp.json() : null)
.then((data) => {
if (!data || !Array.isArray(data.drafts)) {
return;
}
data.drafts.forEach((draft) => {
const row = rows.get(String(draft.id));
if (row) {
updateRow(row, draft.status, draft.acceptance_type);
}
});
})
.catch(() => {});
};
if (rows.size > 0) {
poll();
setInterval(poll, 15000);
}
});
</script>