db = \Config\Database::connect(); $this->configModel = new ConfigurationModel(); $this->studentClassModel = new StudentClassModel(); $this->invoiceModel = new InvoiceModel(); $this->userRoleModel = new UserRoleModel(); $this->teacherClassModel = new TeacherClassModel(); $this->semesterScoreModel = new SemesterScoreModel(); $this->scoreCommentModel = new ScoreCommentModel(); $this->attendanceRecordModel = new AttendanceRecordModel(); $this->attendanceDayModel = new AttendanceDayModel(); $this->classSectionModel = new ClassSectionModel(); $this->calendarModel = new CalendarModel(); // Fetch Enrollment and Refund Deadlines from Configuration $this->schoolYear = $this->configModel->getConfig('school_year'); $this->semester = $this->configModel->getConfig('semester'); $this->lastDayOfRegistration = $this->configModel->getConfig('enrollment_deadline') ?? 'Not set'; $this->refundDeadline = $this->configModel->getConfig('refund_deadline') ?? 'Not set'; // Get class_id and store it in session $this->classSectionId = $this->classSectionId(); session()->set('class_section_id', $this->classSectionId); } public function index() { $userRole = $this->getUserRole(); // Assume this function gets the user role switch (strtolower($userRole)) { case 'administrator': return $this->administrator(); case 'admin': return $this->admin(); case 'teacher': return $this->teacher(); case 'student': return $this->student(); case 'parent': case 'authorized_user': return $this->parentDashboard(); default: return $this->guest(); } } public function classSectionId() { // Get user_id from the session $user_id = session()->get('user_id'); if (!$user_id) { return null; } // Teacher class sections only apply to the teacher role; other roles have no teacher_class rows. if (strtolower(trim((string) $this->getUserRole())) !== 'teacher') { return null; } // Get all class assignments for this teacher in the current term $assignments = $this->teacherClassModel->getClassAssignmentsByUserId( (int)$user_id, (string)$this->schoolYear, (string)$this->semester ); $ids = array_map(static fn($a) => (int)($a['class_section_id'] ?? 0), $assignments); $ids = array_values(array_filter(array_unique($ids))); if (empty($ids)) { log_message('warning', "No class section found for user ID: $user_id"); return null; } $current = (int)(session()->get('class_section_id') ?? 0); $chosen = in_array($current, $ids, true) ? $current : $ids[0]; session()->set([ 'class_section_id' => $chosen, 'class_section_ids' => $ids, ]); return $chosen; } public function administrator() { return view('administrator/administratordashboard'); } public function admin() { return view('/landing_page/admin_dashboard'); } public function teacher() { $userId = (int)(session()->get('user_id') ?? 0); $assignments = $this->teacherClassModel->getClassAssignmentsByUserId( $userId, (string)$this->schoolYear, (string)$this->semester ); $availableIds = array_map(static fn($a) => (int)($a['class_section_id'] ?? 0), $assignments); $availableIds = array_values(array_filter(array_unique($availableIds))); $requestedId = (int)($this->request->getGet('class_section_id') ?? 0); $activeId = null; if ($requestedId && in_array($requestedId, $availableIds, true)) { $activeId = $requestedId; } elseif (!empty($availableIds)) { $activeId = in_array((int)$this->classSectionId, $availableIds, true) ? (int)$this->classSectionId : $availableIds[0]; } if ($activeId) { session()->set('class_section_id', $activeId); } $activeName = null; foreach ($assignments as $a) { if ((int)$a['class_section_id'] === (int)$activeId) { $activeName = $a['class_section_name']; break; } } $normalizedSemester = ucfirst(strtolower(trim((string)($this->semester ?? '')))); $classSectionIds = array_values(array_filter(array_unique(array_map(static fn($a) => (int)($a['class_section_id'] ?? 0), $assignments)), static fn($id) => $id > 0)); $dashboardSummary = $this->buildTeacherDashboardSummary($classSectionIds, $normalizedSemester); return view('/landing_page/teacher_dashboard', [ 'class_section_id' => $activeId, 'active_class_name' => $activeName, 'classes' => $assignments, 'jobs' => $assignments, 'jobCount' => count($assignments), 'scoreSummary' => $dashboardSummary['scoreSummary'], 'commentSummary' => $dashboardSummary['commentSummary'], 'attendanceSummary' => $dashboardSummary['attendanceSummary'], 'deadlineEvents' => $dashboardSummary['deadlineEvents'], 'participationSummary' => $dashboardSummary['participationSummary'], 'attendanceStatus' => $dashboardSummary['attendanceStatus'], 'dashboardNotifications' => $dashboardSummary['notifications'], 'school_year' => (string)$this->schoolYear, 'semester' => (string)$this->semester, ]); } private function buildTeacherDashboardSummary(array $classSectionIds, string $semester): array { $normalizedSemester = ucfirst(strtolower(trim((string)$semester))); if ($normalizedSemester === '' || !in_array($normalizedSemester, ['Fall', 'Spring'], true)) { $normalizedSemester = 'Fall'; } $scoreField = ($normalizedSemester === 'Spring') ? 'final_exam_score' : 'midterm_exam_score'; $scoreLabel = ($normalizedSemester === 'Spring') ? 'Final Exam' : 'Midterm'; $summary = [ 'scoreSummary' => [ 'completionPct' => 0, 'missing' => 0, 'expected' => 0, 'filled' => 0, 'fieldLabel' => $scoreLabel, ], 'commentSummary' => [ 'total' => 0, 'pendingReview' => 0, 'reviewed' => 0, 'byType' => [], ], 'attendanceSummary' => [ 'recorded' => 0, 'students' => 0, 'completionPct' => 0, 'avgAbsences' => 0, ], 'participationSummary' => [ 'filled' => 0, 'missing' => 0, 'completionPct' => 0, 'expected' => 0, ], 'deadlineEvents' => [], ]; if (!empty($classSectionIds)) { $studentRows = $this->db->table('student_class sc') ->select('sc.student_id, sc.class_section_id') ->join('students s', 's.id = sc.student_id', 'inner') ->whereIn('sc.class_section_id', $classSectionIds) ->where('s.is_active', 1) ->where('sc.school_year', (string)$this->schoolYear) ->get() ->getResultArray(); $studentIds = []; foreach ($studentRows as $row) { $studentId = (int)($row['student_id'] ?? 0); $sectionId = (int)($row['class_section_id'] ?? 0); if ($studentId <= 0 || $sectionId <= 0) { continue; } $studentIds[] = $studentId; } $uniqueStudentIds = array_values(array_unique($studentIds)); } else { $uniqueStudentIds = []; } $totalStudents = count($uniqueStudentIds); $summary['attendanceSummary']['students'] = $totalStudents; $scoreRows = []; if (!empty($classSectionIds)) { $scoreRows = $this->semesterScoreModel ->select('student_id, class_section_id, midterm_exam_score, final_exam_score, participation_score') ->whereIn('class_section_id', $classSectionIds) ->where('semester', $normalizedSemester) ->where('school_year', (string)$this->schoolYear) ->findAll(); } $scoreTypesConfig = [ 'participation' => ['label' => 'Participation', 'field' => 'participation_score'], ]; if ($normalizedSemester === 'Fall') { $scoreTypesConfig = array_merge([ 'midterm' => ['label' => 'Midterm', 'field' => 'midterm_exam_score'], ], $scoreTypesConfig); } if ($normalizedSemester === 'Spring') { $scoreTypesConfig = array_merge([ 'final' => ['label' => 'Final exam', 'field' => 'final_exam_score'], ], $scoreTypesConfig); } $filledCounts = array_fill_keys(array_keys($scoreTypesConfig), 0); foreach ($scoreRows as $row) { foreach ($scoreTypesConfig as $key => $cfg) { $value = trim((string)($row[$cfg['field']] ?? '')); if ($value !== '') { $filledCounts[$key]++; } } } $expectedScoreCount = $totalStudents > 0 ? $totalStudents : count($scoreRows); $scoreDetails = []; foreach ($scoreTypesConfig as $key => $cfg) { $filled = $filledCounts[$key] ?? 0; $missing = max(0, $expectedScoreCount - $filled); $completionPct = $expectedScoreCount > 0 ? (int)round(min(100, ($filled / $expectedScoreCount) * 100)) : 0; $scoreDetails[$key] = [ 'label' => $cfg['label'], 'field' => $cfg['field'], 'filled' => $filled, 'missing' => $missing, 'expected' => $expectedScoreCount, 'completionPct' => $completionPct, ]; } $scoreTypeByField = []; if ($normalizedSemester === 'Fall') { $scoreTypeByField['midterm_exam_score'] = 'midterm'; } if ($normalizedSemester === 'Spring') { $scoreTypeByField['final_exam_score'] = 'final'; } $activeScoreType = $scoreTypeByField[$scoreField] ?? 'midterm'; $activeScoreDetails = $scoreDetails[$activeScoreType] ?? $scoreDetails['midterm']; $summary['scoreSummary'] = [ 'completionPct' => $activeScoreDetails['completionPct'], 'missing' => $activeScoreDetails['missing'], 'expected' => $activeScoreDetails['expected'], 'filled' => $activeScoreDetails['filled'], 'fieldLabel' => $scoreLabel, 'types' => $scoreDetails, ]; $participationMetrics = $scoreDetails['participation']; $summary['participationSummary'] = [ 'filled' => $participationMetrics['filled'], 'missing' => $participationMetrics['missing'], 'completionPct' => $participationMetrics['completionPct'], 'expected' => $participationMetrics['expected'], ]; if (!empty($uniqueStudentIds)) { $commentRows = $this->scoreCommentModel ->select('student_id, score_type, comment, comment_review') ->whereIn('student_id', $uniqueStudentIds) ->where('semester', $normalizedSemester) ->where('school_year', (string)$this->schoolYear) ->findAll(); } else { $commentRows = []; } $expectedCommentTypes = array_values(array_filter([ 'ptap', $normalizedSemester === 'Fall' ? 'midterm' : null, $normalizedSemester === 'Spring' ? 'final' : null, ])); $commentStats = []; $commentsByStudent = []; foreach ($commentRows as $row) { $sid = (int)($row['student_id'] ?? 0); $type = strtolower(trim((string)($row['score_type'] ?? ''))); if ($type === '') { $type = 'general'; } if (!isset($commentStats[$type])) { $commentStats[$type] = ['pending' => 0, 'reviewed' => 0]; } $commentText = trim((string)($row['comment'] ?? '')); $reviewValue = trim((string)($row['comment_review'] ?? '')); if ($sid > 0 && $commentText !== '') { $commentsByStudent[$sid][$type] = $commentText; } if ($commentText === '') { continue; } if ($reviewValue === '') { $commentStats[$type]['pending']++; } else { $commentStats[$type]['reviewed']++; } } foreach ($expectedCommentTypes as $type) { if (!isset($commentStats[$type])) { $commentStats[$type] = ['pending' => 0, 'reviewed' => 0]; } } $missingComments = 0; $missingDetail = []; foreach ($uniqueStudentIds as $sid) { foreach ($expectedCommentTypes as $type) { $text = $commentsByStudent[$sid][$type] ?? ''; if ($text === '') { $missingDetail[$type] = ($missingDetail[$type] ?? 0) + 1; $missingComments++; } } } $commentTypes = []; foreach ($expectedCommentTypes as $type) { $stats = $commentStats[$type]; $filled = $stats['pending'] + $stats['reviewed']; $completionPct = $totalStudents > 0 ? (int)round(min(100, ($filled / $totalStudents) * 100)) : 0; $commentTypes[$type] = [ 'label' => ucfirst($type) . ' comments', 'pending' => $stats['pending'], 'reviewed' => $stats['reviewed'], 'filled' => $filled, 'missing' => $missingDetail[$type] ?? 0, 'expected' => $totalStudents, 'completionPct' => $completionPct, ]; } $totalPending = array_sum(array_column($commentTypes, 'pending')); $totalReviewed = array_sum(array_column($commentTypes, 'reviewed')); $totalFilled = array_sum(array_column($commentTypes, 'filled')); $totalExpected = array_sum(array_column($commentTypes, 'expected')); $commentCompletionPct = $totalExpected > 0 ? (int)round(min(100, ($totalFilled / $totalExpected) * 100)) : 0; $summary['commentSummary'] = [ 'total' => $totalFilled, 'pendingReview' => $totalPending, 'reviewed' => $totalReviewed, 'missing' => $missingComments, 'missingDetail' => $missingDetail, 'completionPct' => $commentCompletionPct, 'types' => $commentTypes, ]; $attendanceRows = []; if (!empty($classSectionIds)) { $attendanceRows = $this->attendanceRecordModel ->select('student_id, class_section_id, total_absence') ->whereIn('class_section_id', $classSectionIds) ->where('semester', $normalizedSemester) ->where('school_year', (string)$this->schoolYear) ->findAll(); } $attendanceSet = []; $totalAbsences = 0; foreach ($attendanceRows as $record) { $studentId = (int)($record['student_id'] ?? 0); $sectionId = (int)($record['class_section_id'] ?? 0); if ($studentId <= 0 || $sectionId <= 0) { continue; } $key = "{$sectionId}:{$studentId}"; $attendanceSet[$key] = true; $totalAbsences += (int)($record['total_absence'] ?? 0); } $attendanceRecorded = count($attendanceSet); $attendancePct = $totalStudents > 0 ? (int)round(min(100, ($attendanceRecorded / $totalStudents) * 100)) : 0; $avgAbsence = $attendanceRecorded > 0 ? round($totalAbsences / $attendanceRecorded, 1) : 0; $summary['attendanceSummary'] = [ 'recorded' => $attendanceRecorded, 'students' => $totalStudents, 'completionPct' => $attendancePct, 'avgAbsences' => $avgAbsence, ]; $timezone = new DateTimeZone(date_default_timezone_get() ?: 'UTC'); $today = (new DateTimeImmutable('now', $timezone))->format('Y-m-d'); $attendanceStatus = $this->buildAttendanceSubmissionStatus($classSectionIds, $normalizedSemester, $today); $summary['deadlineEvents'] = $this->calendarModel ->where('notify_teacher', 1) ->where('school_year', (string)$this->schoolYear) ->where('semester', $normalizedSemester) ->where('date >=', $today) ->orderBy('date', 'ASC') ->limit(5) ->findAll(); $summary['attendanceStatus'] = $attendanceStatus; if ($attendanceStatus['submitted'] === false && !empty($classSectionIds)) { $summary['attendanceSummary']['completionPct'] = 0; $summary['attendanceSummary']['recorded'] = 0; } $summary['notifications'] = $this->buildDashboardNotifications($summary); return $summary; } private function buildDashboardNotifications(array $summary): array { $notifications = []; $baseScoreLink = base_url('/teacher/scores'); $buildScoreLink = static function (?string $focus) use ($baseScoreLink) { if (empty($focus)) { return $baseScoreLink; } return $baseScoreLink . '?focus=' . urlencode($focus); }; $determineFocus = static function (array $event): string { $eventTypeText = strtolower(trim((string)($event['event_type'] ?? ''))); if ($eventTypeText !== '' && str_contains($eventTypeText, 'draft')) { return 'comments'; } $text = strtolower(trim(($event['title'] ?? '') . ' ' . ($event['description'] ?? ''))); if ($text === '') { return 'scores'; } if (str_contains($text, 'comment') || str_contains($text, 'ptap')) { return 'comments'; } return 'scores'; }; $calendarLink = base_url('/teacher/calendar'); $attendanceLink = base_url('/teacher/showupdate_attendance'); $timezone = new DateTimeZone(date_default_timezone_get() ?: 'UTC'); $todayDate = (new DateTimeImmutable('now', $timezone))->setTime(0, 0); $today = $todayDate->format('Y-m-d'); $calendarNotificationConfig = [ '1st Semester Scores' => 14, '2nd Semester Scores' => 14, 'Final' => 14, 'Final Exam Draft' => 42, 'Midterm' => 14, 'Midterm Exam Draft' => 42, ]; $activeDeadline = false; foreach ($summary['deadlineEvents'] ?? [] as $event) { $eventTypeRaw = trim((string)($event['event_type'] ?? '')); if ($eventTypeRaw === '') { continue; } $matchedType = null; $thresholdDays = null; foreach ($calendarNotificationConfig as $type => $days) { if (strcasecmp($eventTypeRaw, $type) === 0) { $matchedType = $type; $thresholdDays = $days; break; } } if ($matchedType === null || $thresholdDays === null) { continue; } $rawDate = $event['date'] ?? ''; if ($rawDate === '') { continue; } try { $eventDateTime = new DateTimeImmutable($rawDate, $timezone); } catch (\Exception $e) { continue; } $eventDateTime = $eventDateTime->setTime(0, 0); $daysUntil = (int)$todayDate->diff($eventDateTime)->format('%r%a'); if ($daysUntil <= 0) { $activeDeadline = true; $eventFocus = $determineFocus($event); $notifications[] = [ 'type' => 'danger', 'message' => sprintf( "Deadline today: %s is due. Submit the remaining entries before the day ends.", $matchedType ), 'link' => $buildScoreLink($eventFocus), 'linkText' => 'Submit now', ]; continue; } if ($daysUntil > $thresholdDays) { continue; } $relativeText = $daysUntil === 1 ? ' (tomorrow)' : " (in {$daysUntil} days)"; $notifications[] = [ 'type' => 'warning', 'message' => sprintf( "%s is due on %s%s. Review it on the calendar so you don’t miss it.", $matchedType, $eventDateTime->format('M j, Y'), $relativeText ), 'link' => $calendarLink, 'linkText' => 'View deadline', ]; } if (!$activeDeadline) { $scoreLabel = $summary['scoreSummary']['fieldLabel'] ?? 'Score'; if (!empty($summary['scoreSummary']['missing'] ?? 0)) { $notifications[] = [ 'type' => 'warning', 'message' => sprintf( "You have %s %s entries missing on the scores page. Please finish submitting them.", (int)$summary['scoreSummary']['missing'], $scoreLabel ), 'link' => $buildScoreLink('scores'), 'linkText' => 'Score sheet', ]; } foreach (['midterm', 'final', 'ptap'] as $type) { $count = (int)($summary['commentSummary']['missingDetail'][$type] ?? 0); if ($count <= 0) { continue; } $notifications[] = [ 'type' => 'warning', 'message' => sprintf( "%s comment missing for %s student(s). Leave comments on the scores page.", ucfirst($type), $count ), 'link' => $buildScoreLink('comments'), 'linkText' => ucfirst($type) . ' comments', ]; } if (!empty($summary['participationSummary']['missing'] ?? 0)) { $notifications[] = [ 'type' => 'warning', 'message' => sprintf( "Participation entries are still missing for %s student(s). Please add them from the scores page.", (int)$summary['participationSummary']['missing'] ), 'link' => $buildScoreLink('scores'), 'linkText' => 'Participation', ]; } } if (!empty($summary['attendanceStatus']['missingSections'] ?? [])) { $missingNames = $summary['attendanceStatus']['missingNames'] ?? []; $label = ''; if (!empty($missingNames)) { $label = ' (' . implode(', ', array_slice($missingNames, 0, 3)) . (count($missingNames) > 3 ? '…' : '') . ')'; } $notifications[] = [ 'type' => 'danger', 'message' => "Today's attendance is still unsubmitted for {$summary['attendanceStatus']['date']}{$label}. Please submit it now.", 'link' => $attendanceLink, 'linkText' => 'Record attendance', ]; } return $notifications; } private function buildAttendanceSubmissionStatus(array $classSectionIds, string $semester, string $date): array { if (empty($classSectionIds)) { return [ 'date' => $date, 'missingSections' => [], 'missingNames' => [], 'submitted' => true, ]; } $rows = $this->attendanceDayModel ->select('class_section_id, status') ->whereIn('class_section_id', $classSectionIds) ->where('date', $date) ->where('semester', $semester) ->where('school_year', (string)$this->schoolYear) ->findAll(); $statusMap = []; foreach ($rows as $row) { $csId = (int)($row['class_section_id'] ?? 0); if ($csId <= 0) { continue; } $statusMap[$csId] = strtolower(trim((string)($row['status'] ?? ''))); } $missingSections = []; foreach ($classSectionIds as $classSectionId) { $status = $statusMap[$classSectionId] ?? ''; if (!in_array($status, ['submitted', 'published', 'finalized'], true)) { $missingSections[] = $classSectionId; } } $missingNames = []; if (!empty($missingSections)) { $sectionRows = $this->classSectionModel ->select('class_section_id, class_section_name') ->whereIn('class_section_id', $missingSections) ->findAll(); foreach ($sectionRows as $row) { $name = trim((string)($row['class_section_name'] ?? '')); if ($name === '') { $name = (string)($row['class_section_id'] ?? ''); } $missingNames[] = $name; } } return [ 'date' => $date, 'missingSections' => $missingSections, 'missingNames' => $missingNames, 'submitted' => empty($missingSections), ]; } public function student() { return view('/landing_page/student_dashboard'); } public function parentDashboard() { $parentId = session()->get('user_id'); $userType = $_SESSION['user_type']; // Map user type to roles if ($userType === 'primary') { // If user type is 'Primary', they are the firstparent $parentId = $parentId; } elseif ($userType === 'secondary') { // If user type is 'Secondary', find the parent_id from the parents table $parentData = $this->db->table('parents') ->select('parent_id') ->where('secondparent_user_id', $parentId) ->get() ->getRowArray(); if ($parentData) { $parentId = $parentData['parent_id']; } } elseif ($userType === 'tertiary') { // If user type is 'Tertiary', find the parent_id from the authorized_users table $authUserData = $this->db->table('authorized_users') ->select('user_id as parent_id') ->where('authorized_user_id', $parentId) ->get() ->getRowArray(); if ($authUserData) { $parentId = $authUserData['parent_id']; } } // If no firstparent ID is found, show an error or redirect if (!$parentId) { return redirect()->back()->with( 'error', 'Unable to retrieve student data. Please contact support.' ); } // Fetch Notifications (only active, non-expired, non-deleted) $notifications = $this->db->table('notifications') ->select([ 'notifications.id', 'notifications.title', 'notifications.message', 'notifications.target_group', 'notifications.created_at', 'notifications.expires_at', 'user_notifications.user_id', "CASE WHEN user_notifications.user_id IS NOT NULL THEN 'personal' ELSE 'broadcast' END as notification_type" ]) ->join( 'user_notifications', 'user_notifications.notification_id = notifications.id AND user_notifications.user_id = ' . (int) $parentId, 'left' ) ->groupStart() ->where('notifications.target_group', 'parent') ->orWhere('user_notifications.user_id', $parentId) ->groupEnd() ->where('notifications.deleted_at IS NULL') // Exclude soft-deleted notifications ->groupStart() ->where('notifications.expires_at IS NULL') ->orWhere('notifications.expires_at > NOW()') // Exclude expired ->groupEnd() ->orderBy('notifications.created_at', 'DESC') ->get() ->getResultArray(); // Fetch Student Information (no filtering needed by school year or semester) $students = $this->db->table('students') ->where('parent_id', $parentId) ->get() ->getResultArray(); foreach ($students as &$student) { // Get class_section_name and treat it as grade $classSection = $this->studentClassModel->getClassSectionsByStudentId($student['id'], $this->schoolYear); $student['class_section'] = $classSection; $student['grade'] = $classSection; // grade same as section } unset($student); // Fetch Attendance Records (filtered by most recent school year and semester) $attendanceData = $this->db->table('attendance_data') ->select('attendance_data.*, students.firstname, students.lastname') ->join('students', 'students.id = attendance_data.student_id') ->where('students.parent_id', $parentId) // ->orWhere('students.secondparent_user_id', $parentId) ->where('attendance_data.school_year', $this->schoolYear) ->where('attendance_data.semester', $this->semester) ->orderBy('attendance_data.date', 'DESC') ->get() ->getResultArray(); // Fetch Grades (filtered by most recent school year and semester) $grades = $this->db->table('final_score') // Correct table name ->select('final_score.*, students.firstname, students.lastname') // Ensure table name is correct ->join('students', 'students.id = final_score.student_id') ->where('students.parent_id', $parentId) // ->orWhere('students.secondparent_user_id', $parentId) ->where('final_score.school_year', $this->schoolYear) // Ensure correct table column names ->where('final_score.semester', $this->semester) ->orderBy('final_score.created_at', 'DESC') ->get() ->getResultArray(); // Fetch Enrollments (filtered by most recent school year and semester) $enrollments = $this->db->table('enrollments') ->select('enrollments.*, classes.class_name') ->join('students', 'students.id = enrollments.student_id') ->join('classes', 'classes.id = enrollments.class_section_id') // Ensure this join is correct ->where('students.parent_id', $parentId) // ->orWhere('students.secondparent_user_id', $parentId) ->where('enrollments.school_year', $this->schoolYear) ->where('enrollments.semester', $this->semester) ->orderBy('enrollments.enrollment_date', 'DESC') ->get() ->getResultArray(); // Fetch latest invoice balance $paymentBalance = $this->invoiceModel->getLatestInvoiceTotalAmount($parentId); // Pass data to the view, including the deadlines return view('/landing_page/parent_dashboard', [ 'notifications' => $notifications, 'students' => $students, 'attendance' => $attendanceData, 'grades' => $grades, 'enrollments' => $enrollments, 'lastDayOfRegistration' => $this->lastDayOfRegistration, // Add the enrollment deadline to the view 'withdrawalDeadline' => $this->refundDeadline, // Add the refund deadline to the view 'paymentBalance' => $paymentBalance, // 🔹 New ]); } public function guest() { return view('/landing_page/guest_dashboard'); } protected function getUserRole() { $active = session()->get('active_role'); if ($active !== null && $active !== '') { return (string) $active; } return (string) (session()->get('role') ?? 'guest'); } protected function getUserRoleFromDatabase($user_id) { // Fetching user role from the database $role = $this->userRoleModel->getRoleByUserId($user_id); return $role ?? 'guest'; } }