@extends('layout.layout') @section('content') @include('components.alert') @php $authStaff = Auth::user()->staff; $isAcademicSelfScoped = $is_academic_self_scope ?? false; $isAcademicTeacher = $is_academic_teacher ?? false; $isAcademicTester = $is_academic_tester ?? false; $hideInstructorAndSupervisorColumns = $isAcademicSelfScoped; $persistentQuery = collect([ 'staff_id' => request('staff_id'), 'staffScheduleId' => request('staffScheduleId'), 'student_type' => request('student_type'), 'waiting_list' => request('waiting_list'), 'frozen_list' => request('frozen_list'), 'finished_list' => request('finished_list'), 'finished_year' => request('finished_year'), 'finished_quarter' => request('finished_quarter'), 'assigned_list' => request('assigned_list'), 'renewal_filter' => request('renewal_filter'), ]) ->filter(fn($value) => filled($value)) ->all(); $filtersAction = route('students.index', $persistentQuery); $isWaitingListFilter = request('waiting_list') == 1; $isFrozenListFilter = request('frozen_list') == 1; $isFinishedListFilter = request('finished_list') == 1; $isAssignedListFilter = request('assigned_list') == 1; $isCurrentStudentType = request('student_type') === 'current'; $renewalFilter = request('renewal_filter'); $isDueRenewalFilter = $renewalFilter === 'due'; $isRenewedStudentsFilter = $renewalFilter === 'renewed'; $isOldDataFilter = $renewalFilter === 'old_data'; $hasRenewalFilter = filled($renewalFilter); $allStudentsTabQuery = collect($persistentQuery) ->except(['waiting_list', 'frozen_list', 'finished_list', 'finished_year', 'finished_quarter', 'assigned_list', 'renewal_filter']) ->all(); $allStudentsBaseTabQuery = collect($allStudentsTabQuery)->except(['student_type'])->all(); $allStudentsTabUrl = route('students.index', $allStudentsBaseTabQuery); $currentStudentsTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['student_type' => 'current'])); $waitingListTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['waiting_list' => 1])); $frozenListTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['frozen_list' => 1])); $finishedListTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['finished_list' => 1])); $assignedListTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['assigned_list' => 1])); $dueRenewalTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['renewal_filter' => 'due'])); $renewedStudentsTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['renewal_filter' => 'renewed'])); $oldDataTabUrl = route('students.index', array_merge($allStudentsBaseTabQuery, ['renewal_filter' => 'old_data'])); $showTesterColumns = request('staff_id') && optional($staffName?->jobTitle)->slug === 'tester'; if ($isAcademicTester) { $showTesterColumns = false; } $headers = [ 'Photo', 'Code', 'Name', 'Level', 'Session', 'Program', 'Category', 'Instructor', 'Team Leader', 'Admin', 'Secondary Team Leader', 'Secondary Admin', 'Supervisor', 'Department', 'Added By', ]; if ($isWaitingListFilter) { $headers = [ 'Photo', 'Code', 'Name', 'Program', 'Category', 'Invoice Creator', 'Department', 'Invoice Date', ]; } if ($hideInstructorAndSupervisorColumns && !$isWaitingListFilter) { $headers = array_values(array_filter($headers, fn($header) => !in_array($header, ['Instructor', 'Supervisor', 'Department', 'Added By'], true))); } if ($showTesterColumns) { $headers = array_merge($headers, ['Program Type', 'Program Type']); } if ($isFinishedListFilter || $isRenewedStudentsFilter || $isOldDataFilter) { array_splice($headers, count($headers), 0, ['Finished Date']); } $headers[] = 'Actions'; $canCreateStudent = Auth::user()->can('retention_students_create'); @endphp @php $studentMeta = function ($student) use ($authStaff, $isAcademicSelfScoped, $isAcademicTeacher, $isAcademicTester) { $lead = $student->leads->first(); $courseStudent = $student->courseStudents->first(); $course = $courseStudent?->course; $manager = $course?->staff?->manager; $departmentName = $lead?->creator?->staff?->department?->name ?? ($student->createdBy?->staff?->department?->name ?? 'N/A'); $addedByName = $lead?->creator?->full_name ?? ($student->createdBy?->full_name ?? 'N/A'); $trackTypeName = $lead?->trackType?->name ?? ($student->trackType?->name ?? 'N/A'); $programTypeName = $lead?->pricingplantype?->name ?? ($student->pricingPlanType?->name ?? 'N/A'); $levelName = $course?->trackLevel?->name_en ?? 'N/A'; $sessionName = $course?->session ?? 'N/A'; $trackName = $course?->track?->name_en ?? 'N/A'; $categoryName = $course?->category?->name_en ?? 'N/A'; $instructorName = trim(($course?->staff?->first_name ?? '') . ' ' . ($course?->staff?->last_name ?? '')) ?: 'N/A'; $instructorId = $course?->staff?->id ?? '#'; ; $supervisorName = $manager?->full_name ?: trim(($manager?->first_name ?? '') . ' ' . ($manager?->last_name ?? '')) ?: 'N/A'; $supervisorId = $manager?->id ?? '#'; ; $addedById = $lead?->creator?->staff?->id ?? $student->createdBy?->staff?->id; $primaryAdmins = collect(); $primaryLeaders = collect(); $secondaryAdmins = collect(); $secondaryLeaders = collect(); foreach ($student->courseStudents as $cs) { if ($cs->course) { // Primary Admins (from courseAdmins / admin_assigned_students) foreach ($cs->course->courseAdmins as $ca) { if ($ca->admin) { $primaryAdmins->push($ca->admin); if ($ca->admin->staff && $ca->admin->staff->manager) { $primaryLeaders->push($ca->admin->staff->manager); } } } // Secondary Admins (from course_secondary_admins) foreach ($cs->course->secondaryAdmins as $sa) { $secondaryAdmins->push($sa); if ($sa->staff && $sa->staff->manager) { $secondaryLeaders->push($sa->staff->manager); } } } } $uniquePrimaryAdmins = $primaryAdmins->unique('id'); $uniquePrimaryLeaders = $primaryLeaders->unique('id'); $uniqueSecondaryAdmins = $secondaryAdmins->unique('id'); $uniqueSecondaryLeaders = $secondaryLeaders->unique('id'); $feedbackCourseStudent = $student->courseStudents ->filter(fn($item) => $item->course) ->when($isAcademicSelfScoped && $authStaff, function ($collection) use ($authStaff) { return $collection->filter(fn($item) => (int) $item->course?->staff_id === (int) $authStaff->id); }) ->sortByDesc(function ($item) { $sessions = collect($item->course?->scheduledSessions ?? []); $lastSession = $sessions->sortByDesc(fn($session) => ($session->session_date ?? '') . ' ' . ($session->end_time ?? ''))->first(); return ($lastSession?->session_date ?? $item->course?->end_date ?? $item->course?->start_date ?? now()->toDateString()); }) ->first() ?? $courseStudent; $feedbackCourse = $feedbackCourseStudent?->course; $feedbackSessions = collect($feedbackCourse?->scheduledSessions ?? [])->sortBy(function ($session) { return ($session->session_date ?? '') . '-' . str_pad((string) ($session->session_number ?? 0), 4, '0', STR_PAD_LEFT); })->values(); $existingCourseFeedbacks = $student->teacherFeedbacks ->when($authStaff, fn($collection) => $collection->where('teacher_id', $authStaff->id)) ->when($feedbackCourse, fn($collection) => $collection->where('staff_schedule_id', $feedbackCourse->id)) ->values(); $feedbackAction = [ 'show_misplaced' => false, 'misplaced_session_id' => null, 'misplaced_course_id' => null, 'show_add' => false, 'show_view' => false, 'url' => null, 'label' => null, 'title' => null, 'type' => null, 'is_overdue' => false, 'view_feedbacks' => collect(), ]; if ($isAcademicTeacher && $authStaff && $feedbackCourse) { $lastPastSession = $feedbackSessions ->filter(function ($session) { return \Carbon\Carbon::parse($session->session_date . ' ' . $session->end_time)->isPast(); }) ->sortByDesc(function ($session) { return ($session->session_date ?? '') . '-' . str_pad((string) ($session->session_number ?? 0), 4, '0', STR_PAD_LEFT); }) ->first(); if ($lastPastSession && in_array((int) $lastPastSession->session_number, [1, 2], true)) { $hasMisplacedUrgent = collect($lastPastSession->urgents ?? []) ->contains(function ($urgent) use ($student) { return (int) $urgent->student_id === (int) $student->id && (int) $urgent->created_by === (int) Auth::id() && trim((string) $urgent->message) === 'Misplaced Request'; }); if (! $hasMisplacedUrgent) { $feedbackAction['show_misplaced'] = true; $feedbackAction['misplaced_session_id'] = $lastPastSession->id; $feedbackAction['misplaced_course_id'] = $feedbackCourse->id; } } $submittedTypes = $existingCourseFeedbacks->pluck('type')->all(); $pastSessionsCount = $feedbackSessions->filter(function ($session) { return \Carbon\Carbon::parse($session->session_date . ' ' . $session->end_time)->isPast(); })->count(); $nextFeedback = null; $targetSession = null; if (!in_array('initial', $submittedTypes, true)) { $nextFeedback = 'initial'; $targetSession = $feedbackSessions->first(); } elseif ($pastSessionsCount >= 4 && !in_array('mid', $submittedTypes, true)) { $nextFeedback = 'mid'; $targetSession = $feedbackSessions->skip(3)->first(); } elseif ($pastSessionsCount >= 8 && !in_array('final', $submittedTypes, true)) { $nextFeedback = 'final'; $targetSession = $feedbackSessions->skip(7)->first(); } if ($nextFeedback && $targetSession) { $sessionEnd = \Carbon\Carbon::parse($targetSession->session_date . ' ' . $targetSession->end_time); $feedbackAction = array_merge($feedbackAction, [ 'show_add' => true, 'show_view' => false, 'url' => route('students.feedback.create', [ 'id' => $student->id, 'staff_schedule_id' => $feedbackCourse->id, 'session_id' => $targetSession->id, ]), 'label' => ucfirst($nextFeedback) . ' Feedback', 'title' => ucfirst($nextFeedback) . ' Feedback', 'type' => $nextFeedback, 'is_overdue' => now()->gt($sessionEnd->copy()->addHours(12)), 'view_feedbacks' => collect(), ]); } else { $viewType = collect(['final', 'mid', 'initial'])->first(fn($type) => $existingCourseFeedbacks->where('type', $type)->isNotEmpty()); if ($viewType) { $feedbackAction['show_view'] = true; $feedbackAction['title'] = 'View Feedback'; $feedbackAction['type'] = $viewType; $feedbackAction['view_feedbacks'] = $existingCourseFeedbacks->where('type', $viewType)->values(); } } } elseif ($isAcademicTester && $authStaff && $feedbackCourse) { $demoFeedback = $existingCourseFeedbacks->where('type', 'demo')->values(); $targetSession = $feedbackSessions->first(); if ($demoFeedback->isEmpty() && $targetSession) { $sessionEnd = \Carbon\Carbon::parse($targetSession->session_date . ' ' . $targetSession->end_time); $feedbackAction = array_merge($feedbackAction, [ 'show_add' => true, 'show_view' => false, 'url' => route('students.feedback.demo.create', [ 'id' => $student->id, 'staff_schedule_id' => $feedbackCourse->id, 'session_id' => $targetSession->id, ]), 'label' => 'Performance Report', 'title' => 'Add Performance Report', 'type' => 'demo', 'is_overdue' => now()->gt($sessionEnd->copy()->addHours(24)), 'view_feedbacks' => collect(), ]); } elseif ($demoFeedback->isNotEmpty()) { $feedbackAction['show_view'] = true; $feedbackAction['title'] = 'View Feedback'; $feedbackAction['type'] = 'demo'; $feedbackAction['view_feedbacks'] = $demoFeedback; } } $hasDelayedFeedback = false; if ($isAcademicSelfScoped) { $hasDelayedFeedback = (bool) $feedbackAction['is_overdue']; } else { foreach ($student->courseStudents as $studentCourse) { if (!$studentCourse->course || !$studentCourse->course->scheduledSessions) { continue; } foreach ($studentCourse->course->scheduledSessions as $session) { $feedbackType = match ($session->session_number) { 1 => 'initial', 4 => 'mid', 8 => 'final', default => null, }; if (!$feedbackType) { continue; } $sessionEndDateTime = \Carbon\Carbon::parse($session->session_date . ' ' . $session->end_time); $hasFeedback = $student->teacherFeedbacks ->where('staff_schedule_id', $studentCourse->course->id) ->where('type', $feedbackType) ->isNotEmpty(); if (now()->greaterThan($sessionEndDateTime->copy()->addHours(12)) && !$hasFeedback) { $hasDelayedFeedback = true; break 2; } } } } return [ 'departmentName' => $departmentName, 'addedByName' => $addedByName, 'trackTypeName' => $trackTypeName, 'programTypeName' => $programTypeName, 'levelName' => $levelName, 'sessionName' => $sessionName, 'trackName' => $trackName, 'categoryName' => $categoryName, 'instructorName' => $instructorName, 'instructorId' => $instructorId, 'uniquePrimaryLeaders' => $uniquePrimaryLeaders, 'uniquePrimaryAdmins' => $uniquePrimaryAdmins, 'uniqueSecondaryLeaders' => $uniqueSecondaryLeaders, 'uniqueSecondaryAdmins' => $uniqueSecondaryAdmins, 'supervisorName' => $supervisorName, 'supervisorId' => $supervisorId, 'addedById' => $addedById, 'hasDelayedFeedback' => $hasDelayedFeedback, 'lastSessionDate' => $student->last_session_date ?? 'N/A', 'feedbackAction' => $feedbackAction, ]; }; @endphp
Showing students linked to {{ $staffName->first_name }} {{ $staffName->last_name }}.
Showing students linked to schedule #{{ request('staffScheduleId') }}.
| Program | Category | Invoice Creator | Department | Invoice Date |
|---|---|---|---|---|
| {{ $inv->track?->name_en ?? 'N/A' }} | {{ $inv->track?->categories?->name_en ?? 'N/A' }} | @if ($invCreatorStaffId) {{ $invCreatorName }} @else {{ $invCreatorName }} @endif | {{ $invCreator?->department?->name ?? 'N/A' }} | {{ $inv->created_at?->format('M d, Y') ?? 'N/A' }} |
Try changing the filters or search term, or add a new student if needed.
@if ($canCreateStudent) + Add New Student @endif