AVP-87 Multiple Class updated not showing for multiple students in parent portal
This commit is contained in:
@@ -29,18 +29,12 @@ class ParentProgressController extends BaseController
|
||||
|
||||
public function index()
|
||||
{
|
||||
$sectionIds = $this->getParentSectionIds();
|
||||
$sectionOptions = $this->buildSectionOptions($sectionIds);
|
||||
$students = $this->getParentStudents();
|
||||
$sectionIds = array_values(array_unique(array_filter(array_map(
|
||||
static fn (array $student): int => (int) ($student['class_section_id'] ?? 0),
|
||||
$students
|
||||
))));
|
||||
$subjectSections = ClassProgressController::SUBJECT_SECTIONS;
|
||||
$selectedSectionId = (int) $this->request->getGet('class_section_id');
|
||||
$validSectionIds = array_keys($sectionOptions);
|
||||
|
||||
if ($selectedSectionId === 0 && ! empty($validSectionIds)) {
|
||||
$selectedSectionId = $validSectionIds[0];
|
||||
}
|
||||
if ($selectedSectionId && ! in_array($selectedSectionId, $validSectionIds, true)) {
|
||||
$selectedSectionId = $validSectionIds[0] ?? null;
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
if (! empty($sectionIds)) {
|
||||
@@ -50,23 +44,32 @@ class ParentProgressController extends BaseController
|
||||
->join('users u', 'u.id = class_progress_reports.teacher_id', 'left')
|
||||
->whereIn('class_progress_reports.class_section_id', $sectionIds);
|
||||
|
||||
if ($selectedSectionId) {
|
||||
$builder->where('class_progress_reports.class_section_id', $selectedSectionId);
|
||||
}
|
||||
|
||||
$rows = $builder
|
||||
->orderBy('week_start', 'DESC')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
$reportGroups = $this->groupReportsByWeek($rows);
|
||||
$studentReportGroups = [];
|
||||
foreach ($students as $student) {
|
||||
$studentId = (int) ($student['student_id'] ?? 0);
|
||||
if ($studentId === 0) {
|
||||
continue;
|
||||
}
|
||||
$classSectionId = (int) ($student['class_section_id'] ?? 0);
|
||||
$studentRows = $classSectionId
|
||||
? array_values(array_filter(
|
||||
$rows,
|
||||
static fn (array $row): bool => (int) ($row['class_section_id'] ?? 0) === $classSectionId
|
||||
))
|
||||
: [];
|
||||
$studentReportGroups[$studentId] = $this->groupReportsByWeek($studentRows);
|
||||
}
|
||||
|
||||
return view('parent/class_progress_list', [
|
||||
'reportGroups' => $reportGroups,
|
||||
'students' => $students,
|
||||
'studentReportGroups' => $studentReportGroups,
|
||||
'subjectSections' => $subjectSections,
|
||||
'classSectionOptions' => $sectionOptions,
|
||||
'selectedSectionId' => $selectedSectionId,
|
||||
'hasSections' => ! empty($sectionIds),
|
||||
'hasStudents' => ! empty($students),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -198,20 +201,53 @@ class ParentProgressController extends BaseController
|
||||
return $options;
|
||||
}
|
||||
|
||||
protected function getParentStudents(): array
|
||||
{
|
||||
$parentId = (int) session()->get('user_id');
|
||||
if ($parentId === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = $this->db->table('enrollments e')
|
||||
->select('e.student_id, e.class_section_id, e.updated_at, e.created_at, s.firstname, s.lastname, cs.class_section_name')
|
||||
->join('students s', 's.id = e.student_id')
|
||||
->join('classSection cs', 'cs.class_section_id = e.class_section_id', 'left')
|
||||
->where('e.parent_id', $parentId)
|
||||
->where('e.is_withdrawn', 0)
|
||||
->orderBy('e.updated_at', 'DESC')
|
||||
->orderBy('e.created_at', 'DESC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$students = [];
|
||||
foreach ($rows as $row) {
|
||||
$studentId = (int) ($row['student_id'] ?? 0);
|
||||
if ($studentId === 0 || isset($students[$studentId])) {
|
||||
continue;
|
||||
}
|
||||
$students[$studentId] = $row;
|
||||
}
|
||||
|
||||
return array_values($students);
|
||||
}
|
||||
|
||||
protected function groupReportsByWeek(array $rows): array
|
||||
{
|
||||
$reportGroups = [];
|
||||
foreach ($rows as $row) {
|
||||
$row['status_label'] = ClassProgressController::STATUS_OPTIONS[$row['status']] ?? 'Unknown';
|
||||
$key = $row['week_start'] ?? '';
|
||||
if ($key === '') {
|
||||
$weekStart = $row['week_start'] ?? '';
|
||||
$sectionId = (int) ($row['class_section_id'] ?? 0);
|
||||
if ($weekStart === '' || $sectionId === 0) {
|
||||
continue;
|
||||
}
|
||||
$key = $weekStart . ':' . $sectionId;
|
||||
if (! isset($reportGroups[$key])) {
|
||||
$reportGroups[$key] = [
|
||||
'week_start' => $row['week_start'] ?? '',
|
||||
'week_end' => $row['week_end'] ?? '',
|
||||
'class_section_name' => $row['class_section_name'] ?? '',
|
||||
'class_section_id' => $sectionId,
|
||||
'reports' => [],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -7,79 +7,105 @@
|
||||
<div class="text-muted">Review the weekly reports your child’s teachers submit.</div>
|
||||
</div>
|
||||
<div class="text-end text-muted small">
|
||||
Reports are grouped by Sunday; click any row to read the full details.
|
||||
Reports are grouped by student; click a name to expand weekly details.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (! $hasSections): ?>
|
||||
<?php if (! $hasStudents): ?>
|
||||
<div class="alert alert-info">
|
||||
We couldn’t find any current enrollment for your account. Once your child is assigned to a Sunday class, their teacher’s progress reports will appear here.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (empty($reportGroups)): ?>
|
||||
<div class="alert alert-secondary">No reports submitted yet.</div>
|
||||
<?php else: ?>
|
||||
<div class="card shadow-sm">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Week</th>
|
||||
<th>Subjects</th>
|
||||
<th class="text-end">Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($reportGroups as $group): ?>
|
||||
<?php
|
||||
$start = $group['week_start'] ?? '';
|
||||
$end = $group['week_end'] ?? '';
|
||||
$weekLabel = $start ? date('M d, Y', strtotime($start)) : '-';
|
||||
if ($end) {
|
||||
$weekLabel .= ' – ' . date('M d, Y', strtotime($end));
|
||||
}
|
||||
$reports = $group['reports'] ?? [];
|
||||
$exampleReport = $reports ? reset($reports) : null;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold"><?= esc($weekLabel) ?></div>
|
||||
<?php if (!empty($group['class_section_name'])): ?>
|
||||
<div class="text-muted small">Class: <?= esc($group['class_section_name']) ?></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<?php foreach ($subjectSections as $slug => $section): ?>
|
||||
<?php
|
||||
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
|
||||
$report = $reports[$subjectName] ?? null;
|
||||
$statusLabel = $report ? ($report['status_label'] ?? 'Unknown') : 'No submission';
|
||||
$badgeClass = $report ? 'bg-secondary' : 'bg-light text-muted';
|
||||
?>
|
||||
<div class="border rounded-3 p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<strong class="small mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
|
||||
<span class="badge <?= esc($badgeClass) ?>"><?= esc($statusLabel) ?></span>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
<?= $report ? esc($report['unit_title'] ?: '-') : 'No submission' ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<?php if ($exampleReport): ?>
|
||||
<a href="<?= base_url('parent/progress/view/' . $exampleReport['id']) ?>" class="btn btn-sm btn-outline-primary">View Weekly Details</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php if (! empty($students)): ?>
|
||||
<div class="accordion" id="parentProgressAccordion">
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<?php
|
||||
$studentId = (int) ($student['student_id'] ?? 0);
|
||||
$studentName = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
|
||||
$studentName = $studentName !== '' ? $studentName : 'Student';
|
||||
$className = $student['class_section_name'] ?? '';
|
||||
$collapseId = 'student-progress-' . $studentId;
|
||||
$headingId = 'student-progress-heading-' . $studentId;
|
||||
$reportGroups = $studentReportGroups[$studentId] ?? [];
|
||||
?>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="<?= esc($headingId) ?>">
|
||||
<button class="accordion-button collapsed" 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-md-row align-items-md-center gap-1 gap-md-3">
|
||||
<span class="fw-semibold"><?= esc($studentName) ?></span>
|
||||
<?php if ($className !== ''): ?>
|
||||
<span class="text-muted small">Class: <?= esc($className) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="<?= esc($collapseId) ?>" class="accordion-collapse collapse" aria-labelledby="<?= esc($headingId) ?>" data-bs-parent="#parentProgressAccordion">
|
||||
<div class="accordion-body">
|
||||
<?php if (empty($reportGroups)): ?>
|
||||
<div class="alert alert-secondary mb-0">No reports submitted yet.</div>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Week</th>
|
||||
<th>Subjects</th>
|
||||
<th class="text-end">Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($reportGroups as $group): ?>
|
||||
<?php
|
||||
$start = $group['week_start'] ?? '';
|
||||
$end = $group['week_end'] ?? '';
|
||||
$weekLabel = $start ? date('M d, Y', strtotime($start)) : '-';
|
||||
if ($end) {
|
||||
$weekLabel .= ' – ' . date('M d, Y', strtotime($end));
|
||||
}
|
||||
$reports = $group['reports'] ?? [];
|
||||
$exampleReport = $reports ? reset($reports) : null;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold"><?= esc($weekLabel) ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<?php foreach ($subjectSections as $slug => $section): ?>
|
||||
<?php
|
||||
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
|
||||
$report = $reports[$subjectName] ?? null;
|
||||
$statusLabel = $report ? ($report['status_label'] ?? 'Unknown') : 'No submission';
|
||||
$badgeClass = $report ? 'bg-secondary' : 'bg-light text-muted';
|
||||
?>
|
||||
<div class="border rounded-3 p-2">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<strong class="small mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong>
|
||||
<span class="badge <?= esc($badgeClass) ?>"><?= esc($statusLabel) ?></span>
|
||||
</div>
|
||||
<div class="small text-muted">
|
||||
<?= $report ? esc($report['unit_title'] ?: '-') : 'No submission' ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<?php if ($exampleReport): ?>
|
||||
<a href="<?= base_url('parent/progress/view/' . $exampleReport['id']) ?>" class="btn btn-sm btn-outline-primary">View Weekly Details</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -250,6 +250,30 @@
|
||||
modalInstance.show();
|
||||
};
|
||||
|
||||
const renderNameCell = (user) => {
|
||||
const td = document.createElement('td');
|
||||
const fullName = `${user?.firstname ?? ''} ${user?.lastname ?? ''}`.trim();
|
||||
const label = fullName !== '' ? fullName : '—';
|
||||
const roleList = Array.isArray(user?.roles)
|
||||
? user.roles.map((role) => (role || '').toString().toLowerCase())
|
||||
: [];
|
||||
const isParent = roleList.includes('parent');
|
||||
const uid = Number(user?.id || 0);
|
||||
|
||||
if (isParent && uid > 0) {
|
||||
const link = document.createElement('a');
|
||||
link.href = '#';
|
||||
link.className = 'text-decoration-none';
|
||||
link.setAttribute('data-family-guardian-id', String(uid));
|
||||
link.textContent = label;
|
||||
td.appendChild(link);
|
||||
return td;
|
||||
}
|
||||
|
||||
td.textContent = label;
|
||||
return td;
|
||||
};
|
||||
|
||||
const renderTable = () => {
|
||||
if (!tableBody) return;
|
||||
|
||||
@@ -280,9 +304,7 @@
|
||||
accountCell.textContent = user.account_id ?? '';
|
||||
row.appendChild(accountCell);
|
||||
|
||||
const nameCell = document.createElement('td');
|
||||
nameCell.textContent = `${user.firstname ?? ''} ${user.lastname ?? ''}`.trim();
|
||||
row.appendChild(nameCell);
|
||||
row.appendChild(renderNameCell(user));
|
||||
|
||||
const emailCell = document.createElement('td');
|
||||
emailCell.textContent = user.email ?? '';
|
||||
|
||||
Reference in New Issue
Block a user