AVP-87 Multiple Class updated not showing for multiple students in parent portal

This commit is contained in:
root
2026-03-29 14:03:50 -04:00
parent 58445b2a48
commit b2026812d5
3 changed files with 174 additions and 90 deletions
+58 -22
View File
@@ -29,18 +29,12 @@ class ParentProgressController extends BaseController
public function index() public function index()
{ {
$sectionIds = $this->getParentSectionIds(); $students = $this->getParentStudents();
$sectionOptions = $this->buildSectionOptions($sectionIds); $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; $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 = []; $rows = [];
if (! empty($sectionIds)) { if (! empty($sectionIds)) {
@@ -50,23 +44,32 @@ class ParentProgressController extends BaseController
->join('users u', 'u.id = class_progress_reports.teacher_id', 'left') ->join('users u', 'u.id = class_progress_reports.teacher_id', 'left')
->whereIn('class_progress_reports.class_section_id', $sectionIds); ->whereIn('class_progress_reports.class_section_id', $sectionIds);
if ($selectedSectionId) {
$builder->where('class_progress_reports.class_section_id', $selectedSectionId);
}
$rows = $builder $rows = $builder
->orderBy('week_start', 'DESC') ->orderBy('week_start', 'DESC')
->findAll(); ->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', [ return view('parent/class_progress_list', [
'reportGroups' => $reportGroups, 'students' => $students,
'studentReportGroups' => $studentReportGroups,
'subjectSections' => $subjectSections, 'subjectSections' => $subjectSections,
'classSectionOptions' => $sectionOptions, 'hasStudents' => ! empty($students),
'selectedSectionId' => $selectedSectionId,
'hasSections' => ! empty($sectionIds),
]); ]);
} }
@@ -198,20 +201,53 @@ class ParentProgressController extends BaseController
return $options; 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 protected function groupReportsByWeek(array $rows): array
{ {
$reportGroups = []; $reportGroups = [];
foreach ($rows as $row) { foreach ($rows as $row) {
$row['status_label'] = ClassProgressController::STATUS_OPTIONS[$row['status']] ?? 'Unknown'; $row['status_label'] = ClassProgressController::STATUS_OPTIONS[$row['status']] ?? 'Unknown';
$key = $row['week_start'] ?? ''; $weekStart = $row['week_start'] ?? '';
if ($key === '') { $sectionId = (int) ($row['class_section_id'] ?? 0);
if ($weekStart === '' || $sectionId === 0) {
continue; continue;
} }
$key = $weekStart . ':' . $sectionId;
if (! isset($reportGroups[$key])) { if (! isset($reportGroups[$key])) {
$reportGroups[$key] = [ $reportGroups[$key] = [
'week_start' => $row['week_start'] ?? '', 'week_start' => $row['week_start'] ?? '',
'week_end' => $row['week_end'] ?? '', 'week_end' => $row['week_end'] ?? '',
'class_section_name' => $row['class_section_name'] ?? '', 'class_section_name' => $row['class_section_name'] ?? '',
'class_section_id' => $sectionId,
'reports' => [], 'reports' => [],
]; ];
} }
+91 -65
View File
@@ -7,79 +7,105 @@
<div class="text-muted">Review the weekly reports your childs teachers submit.</div> <div class="text-muted">Review the weekly reports your childs teachers submit.</div>
</div> </div>
<div class="text-end text-muted small"> <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>
</div> </div>
<?php if (! $hasSections): ?> <?php if (! $hasStudents): ?>
<div class="alert alert-info"> <div class="alert alert-info">
We couldnt find any current enrollment for your account. Once your child is assigned to a Sunday class, their teachers progress reports will appear here. We couldnt find any current enrollment for your account. Once your child is assigned to a Sunday class, their teachers progress reports will appear here.
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if (empty($reportGroups)): ?> <?php if (! empty($students)): ?>
<div class="alert alert-secondary">No reports submitted yet.</div> <div class="accordion" id="parentProgressAccordion">
<?php else: ?> <?php foreach ($students as $index => $student): ?>
<div class="card shadow-sm"> <?php
<div class="table-responsive"> $studentId = (int) ($student['student_id'] ?? 0);
<table class="table table-hover align-middle mb-0"> $studentName = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
<thead class="table-light"> $studentName = $studentName !== '' ? $studentName : 'Student';
<tr> $className = $student['class_section_name'] ?? '';
<th>Week</th> $collapseId = 'student-progress-' . $studentId;
<th>Subjects</th> $headingId = 'student-progress-heading-' . $studentId;
<th class="text-end">Details</th> $reportGroups = $studentReportGroups[$studentId] ?? [];
</tr> ?>
</thead> <div class="accordion-item">
<tbody> <h2 class="accordion-header" id="<?= esc($headingId) ?>">
<?php foreach ($reportGroups as $group): ?> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#<?= esc($collapseId) ?>" aria-expanded="false" aria-controls="<?= esc($collapseId) ?>">
<?php <div class="d-flex flex-column flex-md-row align-items-md-center gap-1 gap-md-3">
$start = $group['week_start'] ?? ''; <span class="fw-semibold"><?= esc($studentName) ?></span>
$end = $group['week_end'] ?? ''; <?php if ($className !== ''): ?>
$weekLabel = $start ? date('M d, Y', strtotime($start)) : '-'; <span class="text-muted small">Class: <?= esc($className) ?></span>
if ($end) { <?php endif; ?>
$weekLabel .= ' ' . date('M d, Y', strtotime($end)); </div>
} </button>
$reports = $group['reports'] ?? []; </h2>
$exampleReport = $reports ? reset($reports) : null; <div id="<?= esc($collapseId) ?>" class="accordion-collapse collapse" aria-labelledby="<?= esc($headingId) ?>" data-bs-parent="#parentProgressAccordion">
?> <div class="accordion-body">
<tr> <?php if (empty($reportGroups)): ?>
<td> <div class="alert alert-secondary mb-0">No reports submitted yet.</div>
<div class="fw-semibold"><?= esc($weekLabel) ?></div> <?php else: ?>
<?php if (!empty($group['class_section_name'])): ?> <div class="table-responsive">
<div class="text-muted small">Class: <?= esc($group['class_section_name']) ?></div> <table class="table table-hover align-middle mb-0">
<?php endif; ?> <thead class="table-light">
</td> <tr>
<td> <th>Week</th>
<div class="d-flex flex-column gap-2"> <th>Subjects</th>
<?php foreach ($subjectSections as $slug => $section): ?> <th class="text-end">Details</th>
<?php </tr>
$subjectName = $section['db_subject'] ?? $section['label'] ?? $slug; </thead>
$report = $reports[$subjectName] ?? null; <tbody>
$statusLabel = $report ? ($report['status_label'] ?? 'Unknown') : 'No submission'; <?php foreach ($reportGroups as $group): ?>
$badgeClass = $report ? 'bg-secondary' : 'bg-light text-muted'; <?php
?> $start = $group['week_start'] ?? '';
<div class="border rounded-3 p-2"> $end = $group['week_end'] ?? '';
<div class="d-flex justify-content-between align-items-center"> $weekLabel = $start ? date('M d, Y', strtotime($start)) : '-';
<strong class="small mb-0"><?= esc($section['label'] ?? $subjectName) ?></strong> if ($end) {
<span class="badge <?= esc($badgeClass) ?>"><?= esc($statusLabel) ?></span> $weekLabel .= ' ' . date('M d, Y', strtotime($end));
</div> }
<div class="small text-muted"> $reports = $group['reports'] ?? [];
<?= $report ? esc($report['unit_title'] ?: '-') : 'No submission' ?> $exampleReport = $reports ? reset($reports) : null;
</div> ?>
</div> <tr>
<?php endforeach; ?> <td>
</div> <div class="fw-semibold"><?= esc($weekLabel) ?></div>
</td> </td>
<td class="text-end"> <td>
<?php if ($exampleReport): ?> <div class="d-flex flex-column gap-2">
<a href="<?= base_url('parent/progress/view/' . $exampleReport['id']) ?>" class="btn btn-sm btn-outline-primary">View Weekly Details</a> <?php foreach ($subjectSections as $slug => $section): ?>
<?php endif; ?> <?php
</td> $subjectName = $section['db_subject'] ?? $section['label'] ?? $slug;
</tr> $report = $reports[$subjectName] ?? null;
<?php endforeach; ?> $statusLabel = $report ? ($report['status_label'] ?? 'Unknown') : 'No submission';
</tbody> $badgeClass = $report ? 'bg-secondary' : 'bg-light text-muted';
</table> ?>
</div> <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> </div>
<?php endif; ?> <?php endif; ?>
</div> </div>
+25 -3
View File
@@ -250,6 +250,30 @@
modalInstance.show(); 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 = () => { const renderTable = () => {
if (!tableBody) return; if (!tableBody) return;
@@ -280,9 +304,7 @@
accountCell.textContent = user.account_id ?? ''; accountCell.textContent = user.account_id ?? '';
row.appendChild(accountCell); row.appendChild(accountCell);
const nameCell = document.createElement('td'); row.appendChild(renderNameCell(user));
nameCell.textContent = `${user.firstname ?? ''} ${user.lastname ?? ''}`.trim();
row.appendChild(nameCell);
const emailCell = document.createElement('td'); const emailCell = document.createElement('td');
emailCell.textContent = user.email ?? ''; emailCell.textContent = user.email ?? '';