@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
@if ($canCreateStudent) + Add New Student @endif @if (request('staff_id') && $staffName)
Filtered By Staff

Showing students linked to {{ $staffName->first_name }} {{ $staffName->last_name }}.

Return Back
@elseif (request('staffScheduleId'))
Filtered By Schedule

Showing students linked to schedule #{{ request('staffScheduleId') }}.

Return Back
@endif
@if ($isFinishedListFilter) @php $currentYear = date('Y'); $selectedYear = request('finished_year', $currentYear); $selectedQuarter = request('finished_quarter', ceil(date('n') / 3)); @endphp
@foreach ([1 => 'Q1', 2 => 'Q2', 3 => 'Q3', 4 => 'Q4'] as $qNum => $qLabel) {{ $qLabel }} @endforeach
@endif
Filters
@php $tableFilters = []; $tableFilterLabels = []; if (!$isWaitingListFilter && !$isFrozenListFilter && !$isFinishedListFilter && !$isAssignedListFilter && !$hasRenewalFilter) { $tableFilters = [ 'student_type' => [ 'new' => 'New', 'old' => 'Old', 'demo' => 'Demo', 'current' => 'Current', ], ]; $tableFilterLabels = ['student_type' => 'Student Type']; } $tableControlsPreserveQuery = []; if ($isWaitingListFilter) { $tableControlsPreserveQuery = [ 'waiting_list' => 1, 'wl_department' => request('wl_department'), 'wl_track' => request('wl_track'), ]; } elseif ($hasRenewalFilter) { $tableControlsPreserveQuery = ['renewal_filter' => $renewalFilter]; } @endphp @if ($isWaitingListFilter) @endif
@foreach ($students as $student) @php $meta = $studentMeta($student); $isNewStudent = $student->courseStudents->isEmpty(); @endphp {{ $student->first_name }} {{ $student->student_code ?? 'N/A' }} @if ($meta['hasDelayedFeedback']) @endif {{ $student->first_name }} {{ $student->last_name }} @if ($isNewStudent) New Student @endif @if (!$isWaitingListFilter) {{ $meta['levelName'] }} {{ $meta['sessionName'] }} @endif @if (!$isWaitingListFilter) {{ $meta['trackName'] }} {{ $meta['categoryName'] }} @endif @if ($isWaitingListFilter) @php $firstInvoice = $student->invoices->first(); $extraInvoices = $student->invoices->skip(1); $invoiceTrack = $firstInvoice?->track?->name_en ?? 'N/A'; $invoiceCategory = $firstInvoice?->track?->categories?->name_en ?? 'N/A'; $invoiceCreator = $firstInvoice?->createdBy?->staff; $creatorName = $invoiceCreator ? trim($invoiceCreator->first_name . ' ' . $invoiceCreator->last_name) : ($firstInvoice?->createdBy?->full_name ?? 'N/A'); $creatorStaffId = $invoiceCreator?->id; $creatorDept = $invoiceCreator?->department?->name ?? 'N/A'; $invoiceDate = $firstInvoice?->created_at?->format('M d, Y') ?? 'N/A'; @endphp {{ $invoiceTrack }} {{ $invoiceCategory }} @if ($creatorStaffId) {{ $creatorName }} @else {{ $creatorName }} @endif @if ($extraInvoices->isNotEmpty()) @endif {{ $creatorDept }} {{ $invoiceDate }}
@can('retention_students_update') @endcan
{{-- Collapse rows for extra invoices --}} @if ($extraInvoices->isNotEmpty()) @foreach ($extraInvoices as $inv) @php $invCreator = $inv->createdBy?->staff; $invCreatorName = $invCreator ? trim($invCreator->first_name . ' ' . $invCreator->last_name) : ($inv->createdBy?->full_name ?? 'N/A'); $invCreatorStaffId = $invCreator?->id; @endphp @endforeach
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' }}
@endif @else {{-- Normal (non-waiting-list) cells --}} {{-- track & category already rendered above --}} @unless ($hideInstructorAndSupervisorColumns) @if ($meta['instructorId'] && $meta['instructorName'] !== 'N/A') {{ $meta['instructorName'] }} @else {{ $meta['instructorName'] }} @endif @endunless @forelse ($meta['uniquePrimaryLeaders'] as $leaderStaff) {{ $leaderStaff->full_name ?: ($leaderStaff->first_name . ' ' . $leaderStaff->last_name) }} @empty N/A @endforelse @forelse ($meta['uniquePrimaryAdmins'] as $adminUser) {{ $adminUser->staff->full_name ?? $adminUser->full_name ?? 'Admin' }} @empty N/A @endforelse @forelse ($meta['uniqueSecondaryLeaders'] as $leaderStaff) {{ $leaderStaff->full_name ?: ($leaderStaff->first_name . ' ' . $leaderStaff->last_name) }} @empty N/A @endforelse @forelse ($meta['uniqueSecondaryAdmins'] as $adminUser) {{ $adminUser->staff->full_name ?? $adminUser->full_name ?? 'Admin' }} @empty N/A @endforelse @unless ($hideInstructorAndSupervisorColumns) @if ($meta['supervisorId'] && $meta['supervisorName'] !== 'N/A') {{ $meta['supervisorName'] }} @else {{ $meta['supervisorName'] }} @endif @endunless @unless ($isAcademicSelfScoped) {{ $meta['departmentName'] }} @if ($meta['addedById'] && $meta['addedByName'] !== 'N/A') {{ $meta['addedByName'] }} @else {{ $meta['addedByName'] }} @endif @endunless @if ($showTesterColumns) {{ $meta['trackTypeName'] }} {{ $meta['programTypeName'] }} @endif @if ($isFinishedListFilter || $isRenewedStudentsFilter || $isOldDataFilter) {{ $meta['lastSessionDate'] }} @endif
@if ($meta['feedbackAction']['show_misplaced'])
@csrf
@endif @if ($meta['feedbackAction']['show_add']) {{ $meta['feedbackAction']['label'] }} @elseif ($meta['feedbackAction']['show_view']) @endif @can('retention_students_update') @endcan
@endif {{-- end @else (non-waiting-list) --}} @endforeach
@forelse ($students as $student) @php $meta = $studentMeta($student); $isNewStudent = $student->courseStudents->isEmpty(); @endphp @if ($isWaitingListFilter) @php $firstInvoice = $student->invoices->first(); $extraInvoices = $student->invoices->skip(1); $wlTrack = $firstInvoice?->track?->name_en ?? 'N/A'; $wlCategory = $firstInvoice?->track?->categories?->name_en ?? 'N/A'; $wlCreator = $firstInvoice?->createdBy?->staff; $wlCreatorName = $wlCreator ? trim($wlCreator->first_name . ' ' . $wlCreator->last_name) : ($firstInvoice?->createdBy?->full_name ?? 'N/A'); $wlCreatorId = $wlCreator?->id; $wlDept = $wlCreator?->department?->name ?? 'N/A'; $wlDate = $firstInvoice?->created_at?->format('M d, Y') ?? 'N/A'; @endphp
{{ $student->first_name }}
{{ $student->first_name }} {{ $student->last_name }} Code: {{ $student->student_code ?? 'N/A' }}
Program {{ $wlTrack }}
Category {{ $wlCategory }}
Invoice Creator @if ($wlCreatorId) {{ $wlCreatorName }} @else {{ $wlCreatorName }} @endif
Department {{ $wlDept }}
Invoice Date {{ $wlDate }}
@if ($extraInvoices->isNotEmpty())
@foreach ($extraInvoices as $inv) @php $ec = $inv->createdBy?->staff; $ecName = $ec ? trim($ec->first_name . ' ' . $ec->last_name) : ($inv->createdBy?->full_name ?? 'N/A'); @endphp
Program: {{ $inv->track?->name_en ?? 'N/A' }}
Category: {{ $inv->track?->categories?->name_en ?? 'N/A' }}
Creator: @if ($ec?->id) {{ $ecName }} @else {{ $ecName }} @endif
Date: {{ $inv->created_at?->format('M d, Y') }}
@endforeach
@endif
@can('retention_students_update') @endcan
@else
@unless ($hideInstructorAndSupervisorColumns)
Instructor @if ($meta['instructorId'] && $meta['instructorName'] !== 'N/A') {{ $meta['instructorName'] }} @else {{ $meta['instructorName'] }} @endif
@else
Session {{ $meta['sessionName'] }}
@endunless
Program {{ $meta['trackName'] }}
Level {{ $meta['levelName'] }}
@unless ($isAcademicSelfScoped)
Department {{ $meta['departmentName'] }}
Added By @if ($meta['addedById'] && $meta['addedByName'] !== 'N/A') {{ $meta['addedByName'] }} @else {{ $meta['addedByName'] }} @endif
@endunless
@if ($meta['feedbackAction']['show_misplaced'])
@csrf
@endif @if ($meta['feedbackAction']['show_add']) {{ $meta['feedbackAction']['label'] }} @elseif ($meta['feedbackAction']['show_view']) @endif @can('retention_students_update') @endcan
@endif {{-- end @else (non-waiting-list card) --}} @empty
No students found.

Try changing the filters or search term, or add a new student if needed.

@if ($canCreateStudent) + Add New Student @endif
@endforelse
@foreach ($students as $student) @php $meta = $studentMeta($student); $feedbackItems = $meta['feedbackAction']['view_feedbacks'] ?? collect(); @endphp @if ($feedbackItems->isNotEmpty()) @endif @endforeach @if ($students->count() && method_exists($students, 'links'))
{{ $students->links() }}
@endif
@endsection @push('styles') @endpush @push('scripts') @endpush