Files
alrahma_sunday_school/app/Views/teacher/class_progress_submit.php
T
2026-03-30 18:46:04 -04:00

473 lines
20 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?= $this->extend('layout/main_layout') ?>
<?= $this->section('content') ?>
<?php
$isEdit = (bool) ($isEdit ?? false);
$formAction = $formAction ?? base_url('teacher/progress/store');
$submitLabel = $submitLabel ?? 'Submit Progress';
$hasClass = !empty($classSectionId);
$assignedClassName = $classSectionName ?? '';
$sundayOptions = $sundayOptions ?? [];
$defaultWeekStart = $defaultWeekStart ?? ($sundayOptions[0] ?? '');
$weekStartSelected = set_value('week_start', $defaultWeekStart);
$weekEndValue = set_value('week_end', $existingWeekEnd ?? '');
$existingReports = $existingReports ?? [];
if (!$weekEndValue && $weekStartSelected) {
try {
$dt = new \DateTime($weekStartSelected);
$dt->modify('+6 days');
$weekEndValue = $dt->format('Y-m-d');
} catch (\Exception $e) {
$weekEndValue = '';
}
}
$weekEndLabel = '';
if ($weekEndValue) {
try {
$weekEndLabel = (new \DateTime($weekEndValue))->format('M d, Y');
} catch (\Exception $e) {
$weekEndLabel = 'Week end';
}
} else {
$weekEndLabel = 'Select a week';
}
?>
<div class="py-4">
<div class="d-flex flex-wrap align-items-center justify-content-between mb-3">
<div>
<h3 class="mb-0">
<?php if ($isEdit): ?>
<?= esc($classSectionName ? "Edit {$classSectionName} Progress" : 'Edit Class Progress') ?>
<?php else: ?>
<?= esc($classSectionName ? "Class {$classSectionName} Progress Submission" : 'Class Progress Submission') ?>
<?php endif; ?>
</h3>
<div class="text-muted">
<?= $isEdit ? 'Update your weekly progress submission.' : 'Submit weekly progress for a single subject' ?>
</div>
</div>
<a href="<?= base_url('teacher/progress/history') ?>" class="btn btn-outline-secondary">My Submissions</a>
</div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success"><?= esc(session()->getFlashdata('success')) ?></div>
<?php endif; ?>
<?php $overwritePrompt = session()->getFlashdata('confirm_overwrite'); ?>
<?php if (session()->getFlashdata('warning') && ! $overwritePrompt): ?>
<div class="alert alert-warning"><?= esc(session()->getFlashdata('warning')) ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger"><?= esc(session()->getFlashdata('error')) ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('errors')): ?>
<div class="alert alert-danger">
<ul class="mb-0">
<?php foreach (session()->getFlashdata('errors') as $error): ?>
<li><?= esc($error) ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form action="<?= esc($formAction) ?>" method="post" enctype="multipart/form-data" class="needs-validation" novalidate>
<?= csrf_field() ?>
<input type="hidden" name="class_section_id" value="<?= esc($classSectionId ?? '') ?>">
<input type="hidden" name="confirm_overwrite" id="confirmOverwriteInput" value="0">
<div class="row g-3">
<div class="col">
<div class="card shadow-sm mb-3">
<div class="card-header bg-white d-flex flex-wrap align-items-center justify-content-between gap-3">
<strong class="mb-0">Date Selection</strong>
<?php if ($isEdit): ?>
<div class="text-muted small">
<?php
try {
$displayStart = (new \DateTime($weekStartSelected))->format('M d, Y');
} catch (\Exception $e) {
$displayStart = $weekStartSelected;
}
?>
Week of <?= esc($displayStart ?: 'N/A') ?>
</div>
<input type="hidden" name="week_start" value="<?= esc($weekStartSelected) ?>">
<?php else: ?>
<div class="d-flex align-items-center gap-2">
<select id="weekStartSelect" name="week_start" class="form-select form-select-sm" required>
<option value="">Select week</option>
<?php foreach ($sundayOptions as $sunday): ?>
<?php
try {
$startDt = new \DateTime($sunday);
$displayStart = $startDt->format('M d, Y');
} catch (\Exception $e) {
$displayStart = $sunday;
}
?>
<option value="<?= esc($sunday) ?>" <?= $sunday === $weekStartSelected ? 'selected' : '' ?>>
<?= esc($displayStart) ?>
</option>
<?php endforeach; ?>
</select>
<div class="invalid-feedback">Week start is required.</div>
</div>
<?php endif; ?>
</div>
<div class="card-body">
<input type="hidden" name="week_end" id="weekEndInput" value="<?= esc($weekEndValue) ?>" required>
</div>
</div>
</div>
</div>
<div class="row g-3 mt-1">
<?php
$subjectSections = $subjectSections ?? [];
$subjectCurriculum = $subjectCurriculum ?? [];
?>
<?php foreach ($subjectSections as $slug => $section): ?>
<?php
$unitValues = old("unit_$slug") ?? ($existingReports[$slug]['unit_values'] ?? []);
$chapterValues = old("chapter_$slug") ?? ($existingReports[$slug]['chapter_values'] ?? []);
$coveredValue = old("covered_$slug", $existingReports[$slug]['covered'] ?? '');
$homeworkValue = old("homework_$slug", $existingReports[$slug]['homework'] ?? '');
$rowsCount = max(count($unitValues), count($chapterValues));
?>
<div class="col-lg-6">
<div class="border border-dark rounded-3 p-3 h-100 subject-section">
<div class="d-flex align-items-center justify-content-between mb-3">
<h4 class="mb-0"><?= esc($section['label'] ?? $slug) ?></h4>
</div>
<?php $curriculumOptions = $subjectCurriculum[$slug] ?? []; ?>
<?php
$preparedEntries = array_values(array_filter(array_map(function ($option) {
$chapterName = trim($option['chapter_name'] ?? '');
if ($chapterName === '') {
return null;
}
return [
'unit_number' => $option['unit_number'] ?? '',
'unit_title' => trim($option['unit_title'] ?? ''),
'chapter_name' => $chapterName,
];
}, $curriculumOptions)));
?>
<div class="mb-2 d-flex justify-content-between align-items-center">
<div class="d-flex align-items-center gap-2">
<div class="position-relative">
<button type="button"
class="btn btn-sm btn-outline-dark"
data-add-unit-chapter
data-subject="<?= esc($slug) ?>">
<?= $slug === 'quran' ? '+ Add Surah, Arabic Subject' : '+ Add Unit, Chapter' ?>
</button>
<div class="subject-curriculum-list position-absolute d-none border rounded shadow-sm bg-white mt-1" id="curriculumList-<?= esc($slug) ?>" style="min-width: 220px; z-index: 5;">
<?php if (empty($preparedEntries)): ?>
<div class="p-2 text-muted small">No saved entries.</div>
<?php else: ?>
<?php foreach ($preparedEntries as $entry): ?>
<?php
$unitNumber = $entry['unit_number'] ?? '';
$unitTitle = $entry['unit_title'] ?? '';
$chapterName = $entry['chapter_name'] ?? '';
$displayParts = [];
if ($slug === 'islamic') {
if ($unitNumber) $displayParts[] = 'Unit ' . $unitNumber;
if ($unitTitle !== '') $displayParts[] = $unitTitle;
$prefix = $displayParts ? implode(' ', $displayParts) . ' / ' : '';
$display = $prefix . $chapterName;
} else {
$display = 'Surah: ' . $chapterName;
}
?>
<button type="button"
class="dropdown-item text-start"
data-curriculum-entry
data-subject="<?= esc($slug) ?>"
data-unit-number="<?= esc($unitNumber) ?>"
data-unit-title="<?= esc($unitTitle) ?>"
data-chapter="<?= esc($chapterName) ?>">
<?= esc($display) ?>
</button>
<?php endforeach; ?>
<?php endif; ?>
<?php if ($slug === 'quran'): ?>
<div class="px-2 py-2 border-top">
<div class="input-group input-group-sm">
<input type="text" class="form-control" placeholder="Custom Surah" 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 custom Surah or Arabic target.</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<div class="unit-chapter-rows mb-3" id="unitChapterRows-<?= esc($slug) ?>">
<?php for ($i = 0; $i < $rowsCount; $i++): ?>
<div class="row g-2 align-items-end mb-2 unit-chapter-entry">
<div class="col">
<input type="text" name="unit_<?= esc($slug) ?>[]" class="form-control form-control-sm" placeholder="Unit name" value="<?= esc($unitValues[$i] ?? '') ?>" readonly>
</div>
<div class="col">
<input type="text" name="chapter_<?= esc($slug) ?>[]" class="form-control form-control-sm" placeholder="Chapter" value="<?= esc($chapterValues[$i] ?? '') ?>" readonly>
</div>
<div class="col-auto">
<button type="button" class="btn btn-outline-danger btn-sm" data-remove-unit-chapter aria-label="Remove entry">X</button>
</div>
</div>
<?php endfor; ?>
</div>
<div class="mb-3">
<label class="form-label mb-1">What has been covered?</label>
<textarea name="covered_<?= esc($slug) ?>" class="form-control" rows="4" required placeholder="What was taught? Key topics, activities, memorization, etc."><?= esc($coveredValue) ?></textarea>
</div>
<div class="mb-3">
<label class="form-label mb-1">Assigned homework:</label>
<textarea name="homework_<?= esc($slug) ?>" class="form-control" rows="3" placeholder="Homework, practice quizzes, review pages"><?= esc($homeworkValue) ?></textarea>
</div>
<div class="mb-3">
<label class="form-label mb-1">Attachment (optional):</label>
<input type="file" name="attachment_<?= esc($slug) ?>[]" class="form-control" accept=".pdf,.jpg,.jpeg,.png" multiple>
<div class="form-text small">Upload worksheets, quizzes, or reference files for <?= esc(strtolower($section['label'] ?? 'this subject')) ?>. You can select multiple files.</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="row mt-3">
<div class="col">
<div class="card shadow-sm">
<div class="card-body d-flex flex-column">
<button class="btn btn-primary w-100 mt-auto" type="submit" <?= $hasClass ? '' : 'disabled' ?>><?= esc($submitLabel) ?></button>
<?php if (! $hasClass): ?>
<div class="text-muted small mt-2">
You are not assigned to a class. Contact the administrator to submit progress.
</div>
<?php else: ?>
<div class="text-muted small mt-2">Make sure week dates and subject information are accurate before submitting.</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</form>
</div>
<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<?php
$submitSuccess = session()->getFlashdata('success');
$submitError = session()->getFlashdata('error');
$overwriteWarning = session()->getFlashdata('warning');
$overwritePrompt = session()->getFlashdata('confirm_overwrite');
?>
<?php if ($submitSuccess || $submitError): ?>
<div class="modal fade" id="submissionStatusModal" tabindex="-1" aria-labelledby="submissionStatusLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="submissionStatusLabel">
<?= $submitSuccess ? 'Submission Successful' : 'Submission Failed' ?>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?= esc($submitSuccess ?: $submitError) ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if ($overwritePrompt && $overwriteWarning): ?>
<div class="modal fade" id="overwriteConfirmModal" tabindex="-1" aria-labelledby="overwriteConfirmLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="overwriteConfirmLabel">Override Existing Report</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<?= esc($overwriteWarning) ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="confirmOverwriteButton">Override</button>
</div>
</div>
</div>
</div>
<?php endif; ?>
<script>
(() => {
'use strict';
const forms = document.querySelectorAll('.needs-validation');
Array.from(forms).forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
const weekStartSelect = document.getElementById('weekStartSelect');
const weekEndInput = document.getElementById('weekEndInput');
const updateWeekEnd = (value) => {
if (!weekEndInput) return;
if (!value) {
weekEndInput.value = '';
return;
}
const startDate = new Date(value);
if (Number.isNaN(startDate.valueOf())) {
weekEndInput.value = '';
return;
}
const endDate = new Date(startDate);
endDate.setDate(endDate.getDate() + 6);
weekEndInput.value = endDate.toISOString().slice(0, 10);
};
if (weekStartSelect) {
weekStartSelect.addEventListener('change', () => updateWeekEnd(weekStartSelect.value));
updateWeekEnd(weekStartSelect.value);
}
const buildRow = (slug, unitValue = '', chapterValue = '') => {
const row = document.createElement('div');
row.className = 'row g-2 align-items-end mb-2 unit-chapter-entry';
row.innerHTML = `
<div class="col">
<input type="text" name="unit_${slug}[]" class="form-control form-control-sm" placeholder="Unit name" readonly />
</div>
<div class="col">
<input type="text" name="chapter_${slug}[]" class="form-control form-control-sm" placeholder="Chapter" readonly />
</div>
<div class="col-auto">
<button type="button" class="btn btn-outline-danger btn-sm" data-remove-unit-chapter aria-label="Remove entry">X</button>
</div>
`;
const inputs = row.querySelectorAll('input');
if (inputs[0]) {
inputs[0].value = unitValue;
}
if (inputs[1]) {
inputs[1].value = chapterValue;
}
return row;
};
const appendUnitChapterRow = (slug, unitValue = '', chapterValue = '') => {
const container = document.getElementById(`unitChapterRows-${slug}`);
if (!container) return;
container.appendChild(buildRow(slug, unitValue, chapterValue));
};
const buildUnitDisplay = (subject, unitNumber, unitTitle, { isQuran = false, isCustom = false } = {}) => {
const parts = [];
if (unitNumber) {
parts.push(`Unit ${unitNumber}`);
}
if (unitTitle) {
parts.push(unitTitle);
}
if (isQuran) {
return isCustom ? 'Custom' : 'Surah';
}
return parts.join(' ');
};
const hideMenus = () => {
document.querySelectorAll('.subject-curriculum-list').forEach(menu => menu.classList.add('d-none'));
};
document.addEventListener('click', () => hideMenus());
document.querySelectorAll('[data-add-unit-chapter]').forEach(button => {
const subject = button.dataset.subject;
if (!subject) return;
const menu = document.getElementById(`curriculumList-${subject}`);
if (menu) {
menu.addEventListener('click', event => event.stopPropagation());
}
button.addEventListener('click', event => {
event.stopPropagation();
if (!menu) return;
const shouldShow = menu.classList.contains('d-none');
hideMenus();
if (shouldShow) {
menu.classList.remove('d-none');
activeMenus.add(menu);
}
});
});
document.querySelectorAll('[data-curriculum-entry]').forEach(entry => {
entry.addEventListener('click', event => {
event.stopPropagation();
const subject = entry.dataset.subject;
const unitNumber = entry.dataset.unitNumber || '';
const unitTitle = entry.dataset.unitTitle || '';
const chapterValue = entry.dataset.chapter || '';
if (!subject) return;
const unitValue = buildUnitDisplay(subject, unitNumber, unitTitle, { isQuran: subject === 'quran' });
appendUnitChapterRow(subject, unitValue, chapterValue);
hideMenus();
});
});
document.addEventListener('click', event => {
const button = event.target.closest('[data-remove-unit-chapter]');
if (!button) return;
const row = button.closest('.unit-chapter-entry');
if (row) {
row.remove();
}
});
document.querySelectorAll('[data-custom-entry]').forEach(button => {
button.addEventListener('click', event => {
event.stopPropagation();
const subject = button.dataset.subject;
if (!subject) return;
const input = document.querySelector(`[data-custom-input][data-subject="${subject}"]`);
if (!input) return;
const customValue = input.value.trim();
if (customValue === '') return;
const unitValue = buildUnitDisplay(subject, '', '', { isQuran: subject === 'quran', isCustom: true });
appendUnitChapterRow(subject, unitValue, customValue);
input.value = '';
hideMenus();
});
});
const statusModalEl = document.getElementById('submissionStatusModal');
if (statusModalEl && typeof bootstrap !== 'undefined') {
const statusModal = new bootstrap.Modal(statusModalEl);
statusModal.show();
}
const overwriteModalEl = document.getElementById('overwriteConfirmModal');
if (overwriteModalEl && typeof bootstrap !== 'undefined') {
const overwriteModal = new bootstrap.Modal(overwriteModalEl);
overwriteModal.show();
const confirmButton = document.getElementById('confirmOverwriteButton');
const confirmInput = document.getElementById('confirmOverwriteInput');
if (confirmButton && confirmInput) {
confirmButton.addEventListener('click', () => {
confirmInput.value = '1';
const form = confirmButton.closest('form') || document.querySelector('form.needs-validation');
if (form) {
form.submit();
}
});
}
}
})();
</script>
<?= $this->endSection() ?>