@extends('backend.admin_backend.admin_dashboard') @section('admin') @php /* |-------------------------------------------------------------------------- | ================================================================ | AGM SMARTSCHOOL - PROFESSIONAL RESULT ANALYSIS DASHBOARD | ================================================================ | | IMPORTANT: | We are using the Result "total" column for this analysis. | | Your Result table already stores: | CA1 + CA2 + CA3 + Exam -> Final Total | | Therefore, we DO NOT recalculate the final result here. | We simply analyze the final "total" already stored in the database. | | Since total is out of 100: | | Average Score = Percentage Performance | | Example: | Average total = 72.5 | Percentage performance = 72.5% | |-------------------------------------------------------------------------- */ use App\Models\Student; use App\Models\StudentClasses; use App\Models\Teacher; use App\Models\Subject; use App\Models\Result; use App\Models\CbtTest; use App\Models\CbtAttempt; use App\Models\Term; use App\Models\AcademicSession; use Illuminate\Support\Facades\DB; /* |-------------------------------------------------------------------------- | ================================================================ | 1. BASIC SCHOOL INFORMATION | ================================================================ |-------------------------------------------------------------------------- */ $totalstudent = Student::count(); $totalsubject = Subject::count(); $totalclass = StudentClasses::count(); $totalteachers = Teacher::count(); /* |-------------------------------------------------------------------------- | ================================================================ | 2. CURRENT TERM AND CURRENT SESSION | ================================================================ |-------------------------------------------------------------------------- | | We use the current term/session as the default values in the | Analysis Filter. | |-------------------------------------------------------------------------- */ $currentTerm = Term::where('is_current', 1)->first(); $currentSession = AcademicSession::where('is_current', 1)->first(); $currentTermName = $currentTerm ? $currentTerm->name : null; $currentSessionName = $currentSession ? $currentSession->name : null; /* |-------------------------------------------------------------------------- | ================================================================ | 3. ANALYSIS FILTER VALUES | ================================================================ |-------------------------------------------------------------------------- | | The administrator can select: | | - Academic Session | - Term | - Class | | If nothing is selected, the dashboard automatically uses: | | Current Session | Current Term | All Classes | |-------------------------------------------------------------------------- */ $analysisSession = request('analysis_session', $currentSessionName); $analysisTerm = request('analysis_term', $currentTermName); $analysisClass = request('analysis_class', 'all'); /* |-------------------------------------------------------------------------- | ================================================================ | 4. LOAD FILTER OPTIONS | ================================================================ |-------------------------------------------------------------------------- */ $analysisSessions = AcademicSession::orderByDesc('name')->get(); $analysisTerms = Term::orderBy('id')->get(); $analysisClasses = StudentClasses::orderBy('class_name')->get(); /* |-------------------------------------------------------------------------- | ================================================================ | 5. GET RESULT DATA FOR THE SELECTED FILTER | ================================================================ |-------------------------------------------------------------------------- | | We only analyze results belonging to: | | Selected Session | Selected Term | Selected Class (if selected) | |-------------------------------------------------------------------------- */ $analysisResultsQuery = Result::with([ 'student', 'subject', 'studentClass' ]) ->where('session', $analysisSession) ->where('term', $analysisTerm); /* |-------------------------------------------------------------------------- | If administrator selected a specific class, | restrict the analysis to that class. |-------------------------------------------------------------------------- */ if ($analysisClass !== 'all' && !empty($analysisClass)) { $analysisResultsQuery->where( 'student_classes_id', $analysisClass ); } /* |-------------------------------------------------------------------------- | Execute the query. |-------------------------------------------------------------------------- */ $analysisResults = $analysisResultsQuery->get(); /* |-------------------------------------------------------------------------- | ================================================================ | 6. BASIC RESULT COUNTS | ================================================================ |-------------------------------------------------------------------------- */ $totalResultRecords = $analysisResults->count(); $totalStudentsAssessed = $analysisResults ->pluck('student_id') ->unique() ->count(); $totalSubjectsAssessed = $analysisResults ->pluck('subject_id') ->unique() ->count(); /* |-------------------------------------------------------------------------- | ================================================================ | 7. ALL STUDENTS IN SELECTED CLASS | ================================================================ |-------------------------------------------------------------------------- | | This is different from "Students Assessed". | | Example: | | Class has 40 students. | Only 35 students have results. | | Total Students = 40 | Students Assessed = 35 | | This helps the administrator identify incomplete results. | |-------------------------------------------------------------------------- */ $studentsQuery = Student::query(); if ($analysisClass !== 'all' && !empty($analysisClass)) { $studentsQuery->where( 'student_classes_id', $analysisClass ); } $totalStudentsInFilter = $studentsQuery->count(); /* |-------------------------------------------------------------------------- | ================================================================ | 8. OVERALL AVERAGE SCORE | ================================================================ |-------------------------------------------------------------------------- | | We calculate the average of all final result totals. | | Example: | | 70 + 80 + 60 = 210 | | 210 / 3 = 70 | | Overall performance = 70% | |-------------------------------------------------------------------------- */ $overallAverage = $analysisResults->count() > 0 ? round($analysisResults->avg('total'), 2) : 0; /* |-------------------------------------------------------------------------- | Because final total is already out of 100, | the average itself represents percentage performance. |-------------------------------------------------------------------------- */ $overallPercentage = $overallAverage; /* |-------------------------------------------------------------------------- | ================================================================ | 9. HIGHEST AND LOWEST SCORE | ================================================================ |-------------------------------------------------------------------------- */ $highestScore = $analysisResults->count() > 0 ? round($analysisResults->max('total'), 2) : 0; $lowestScore = $analysisResults->count() > 0 ? round($analysisResults->min('total'), 2) : 0; /* |-------------------------------------------------------------------------- | ================================================================ | 10. PASS AND FAIL ANALYSIS | ================================================================ |-------------------------------------------------------------------------- | | We use 40 as the pass mark. | | You can change this later if your school uses another pass mark. | |-------------------------------------------------------------------------- */ $passMark = 40; /* |-------------------------------------------------------------------------- | Count passed result records. |-------------------------------------------------------------------------- */ $passedResultRecords = $analysisResults ->filter(function ($result) use ($passMark) { return (float) $result->total >= $passMark; }) ->count(); /* |-------------------------------------------------------------------------- | Count failed result records. |-------------------------------------------------------------------------- */ $failedResultRecords = $analysisResults ->filter(function ($result) use ($passMark) { return (float) $result->total < $passMark; }) ->count(); /* |-------------------------------------------------------------------------- | Pass percentage |-------------------------------------------------------------------------- */ $passPercentage = $totalResultRecords > 0 ? round( ($passedResultRecords / $totalResultRecords) * 100, 2 ) : 0; /* |-------------------------------------------------------------------------- | Fail percentage |-------------------------------------------------------------------------- */ $failPercentage = $totalResultRecords > 0 ? round( ($failedResultRecords / $totalResultRecords) * 100, 2 ) : 0; /* |-------------------------------------------------------------------------- | ================================================================ | 11. STUDENT OVERALL PERFORMANCE | ================================================================ |-------------------------------------------------------------------------- | | IMPORTANT: | | We do NOT simply rank individual subject scores. | | Instead, we group all subjects belonging to each student. | | Example: | | John: | Mathematics = 80 | English = 70 | Biology = 90 | | John Average: | | (80 + 70 + 90) / 3 = 80 | |-------------------------------------------------------------------------- */ $studentPerformance = $analysisResults ->groupBy('student_id') ->map(function ($studentResults) { /* |-------------------------------------------------------------------------- | Calculate student's average score across all subjects. |-------------------------------------------------------------------------- */ $average = $studentResults->avg('total'); $student = $studentResults->first()->student; $class = $studentResults->first()->studentClass; return [ 'student_id' => $studentResults->first()->student_id, 'student' => $student, 'class' => $class, 'subjects' => $studentResults->count(), 'total_score' => $studentResults->sum('total'), 'average' => round($average, 2), 'percentage' => round($average, 2), ]; }) ->sortByDesc('average') ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 12. SCHOOL/STUDENT AVERAGE | ================================================================ |-------------------------------------------------------------------------- | | This is the average of each student's overall average. | | We use this figure to determine: | | Above Average Students | Below Average Students | |-------------------------------------------------------------------------- */ $studentOverallAverage = $studentPerformance->count() > 0 ? round($studentPerformance->avg('average'), 2) : 0; /* |-------------------------------------------------------------------------- | ================================================================ | 13. STUDENTS ABOVE AVERAGE | ================================================================ |-------------------------------------------------------------------------- */ $studentsAboveAverage = $studentPerformance ->filter(function ($student) use ($studentOverallAverage) { return $student['average'] > $studentOverallAverage; }) ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 14. STUDENTS BELOW AVERAGE | ================================================================ |-------------------------------------------------------------------------- */ $studentsBelowAverage = $studentPerformance ->filter(function ($student) use ($studentOverallAverage) { return $student['average'] < $studentOverallAverage; }) ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 15. STUDENTS EXACTLY AT AVERAGE | ================================================================ |-------------------------------------------------------------------------- */ $studentsAtAverage = $studentPerformance ->filter(function ($student) use ($studentOverallAverage) { return $student['average'] == $studentOverallAverage; }) ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 16. STUDENT PASS / FAIL | ================================================================ |-------------------------------------------------------------------------- | | A student is considered to have passed if their overall average | is at least the school pass mark. | |-------------------------------------------------------------------------- */ $studentsPassed = $studentPerformance ->filter(function ($student) use ($passMark) { return $student['average'] >= $passMark; }) ->count(); $studentsFailed = $studentPerformance ->filter(function ($student) use ($passMark) { return $student['average'] < $passMark; }) ->count(); $studentPassPercentage = $totalStudentsAssessed > 0 ? round( ($studentsPassed / $totalStudentsAssessed) * 100, 2 ) : 0; /* |-------------------------------------------------------------------------- | ================================================================ | 17. TOP 10 STUDENTS | ================================================================ |-------------------------------------------------------------------------- */ $topStudents = $studentPerformance ->take(10) ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 18. STUDENTS BELOW AVERAGE | ================================================================ |-------------------------------------------------------------------------- | | We show the lowest performers first. | |-------------------------------------------------------------------------- */ $lowestStudents = $studentsBelowAverage ->sortBy('average') ->take(10) ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 19. CLASS PERFORMANCE | ================================================================ |-------------------------------------------------------------------------- | | We group results by class. | | Example: | | JSS 1 = 68% | JSS 2 = 72% | JSS 3 = 75% | |-------------------------------------------------------------------------- */ $classPerformance = $analysisResults ->groupBy('student_classes_id') ->map(function ($classResults) { $class = $classResults->first()->studentClass; return [ 'id' => $classResults->first()->student_classes_id, 'class_name' => $class ? $class->class_name : 'Unknown Class', 'average' => round( $classResults->avg('total'), 2 ), 'students' => $classResults ->pluck('student_id') ->unique() ->count(), 'results' => $classResults->count(), ]; }) ->sortByDesc('average') ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 20. SUBJECT PERFORMANCE |-------------------------------------------------------------------------- | | This allows the administrator to know: | | Which subject has high performance? | Which subject needs attention? | |-------------------------------------------------------------------------- */ $subjectPerformance = $analysisResults ->groupBy('subject_id') ->map(function ($subjectResults) { $subject = $subjectResults->first()->subject; return [ 'id' => $subjectResults->first()->subject_id, 'subject_name' => $subject ? $subject->subject_name : 'Unknown Subject', 'average' => round( $subjectResults->avg('total'), 2 ), 'highest' => round( $subjectResults->max('total'), 2 ), 'lowest' => round( $subjectResults->min('total'), 2 ), 'students' => $subjectResults ->pluck('student_id') ->unique() ->count(), ]; }) ->sortByDesc('average') ->values(); /* |-------------------------------------------------------------------------- | ================================================================ | 21. GRADE DISTRIBUTION |-------------------------------------------------------------------------- | | This uses the grade already stored inside the Result table. | | Example: | | A = 20 | B = 30 | C = 25 | D = 10 | E = 5 | F = 3 | |-------------------------------------------------------------------------- */ $gradeDistribution = $analysisResults ->groupBy(function ($result) { return strtoupper( trim($result->grade ?? 'N/A') ); }) ->map(function ($gradeResults) { return $gradeResults->count(); }) ->sortKeys(); /* |-------------------------------------------------------------------------- | ================================================================ | 22. SCORE DISTRIBUTION | ================================================================ | | This groups scores into understandable performance ranges. | | 0 - 39 = Fail | 40 - 49 = Pass | 50 - 59 | 60 - 69 | 70 - 79 | 80 - 89 | 90 - 100 | |-------------------------------------------------------------------------- */ $scoreRanges = [ '0 - 39' => 0, '40 - 49' => 0, '50 - 59' => 0, '60 - 69' => 0, '70 - 79' => 0, '80 - 89' => 0, '90 - 100' => 0, ]; foreach ($analysisResults as $result) { $score = (float) $result->total; if ($score < 40) { $scoreRanges['0 - 39']++; } elseif ($score < 50) { $scoreRanges['40 - 49']++; } elseif ($score < 60) { $scoreRanges['50 - 59']++; } elseif ($score < 70) { $scoreRanges['60 - 69']++; } elseif ($score < 80) { $scoreRanges['70 - 79']++; } elseif ($score < 90) { $scoreRanges['80 - 89']++; } else { $scoreRanges['90 - 100']++; } } /* |-------------------------------------------------------------------------- | ================================================================ | 23. RESULT COMPLETION ANALYSIS |-------------------------------------------------------------------------- | | This compares: | | Students in class | VS | Students who actually have results | |-------------------------------------------------------------------------- */ $missingResultStudents = max( 0, $totalStudentsInFilter - $totalStudentsAssessed ); /* |-------------------------------------------------------------------------- | ================================================================ | 24. CBT ANALYTICS |-------------------------------------------------------------------------- | | Keep your existing CBT dashboard analysis. |-------------------------------------------------------------------------- */ $totalTests = CbtTest::where('term', $currentTermName) ->where('session', $currentSessionName) ->count(); $totalAttempts = CbtAttempt::whereHas('test', function ($q) use ($currentTermName, $currentSessionName) { $q->where('term', $currentTermName) ->where('session', $currentSessionName); }) ->count(); $completedAttempts = CbtAttempt::where( 'status', 'completed' ) ->whereHas('test', function ($q) use ($currentTermName, $currentSessionName) { $q->where('term', $currentTermName) ->where('session', $currentSessionName); }) ->count(); $inProgressAttempts = CbtAttempt::where( 'status', 'in_progress' ) ->whereHas('test', function ($q) use ($currentTermName, $currentSessionName) { $q->where('term', $currentTermName) ->where('session', $currentSessionName); }) ->count(); $passCount = CbtAttempt::where( 'status', 'completed' ) ->whereHas('test', function ($q) use ($currentTermName, $currentSessionName) { $q->where('term', $currentTermName) ->where('session', $currentSessionName); }) ->where('score', '>=', 40) ->count(); $failCount = CbtAttempt::where( 'status', 'completed' ) ->whereHas('test', function ($q) use ($currentTermName, $currentSessionName) { $q->where('term', $currentTermName) ->where('session', $currentSessionName); }) ->where('score', '<', 40) ->count(); /* |-------------------------------------------------------------------------- | ================================================================ | 25. STUDENT GROWTH PER MONTH | ================================================================ |-------------------------------------------------------------------------- */ $monthlyStudents = []; $months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; foreach ($months as $index => $month) { $monthlyStudents[] = Student::whereYear( 'created_at', date('Y') ) ->whereMonth( 'created_at', $index + 1 ) ->count(); } /* |-------------------------------------------------------------------------- | ================================================================ | 26. SELECTED CLASS NAME FOR DISPLAY | ================================================================ |-------------------------------------------------------------------------- */ $selectedClassName = 'All Classes'; if ($analysisClass !== 'all' && !empty($analysisClass)) { $selectedClass = StudentClasses::find($analysisClass); if ($selectedClass) { $selectedClassName = $selectedClass->class_name; } } @endphp {{-- ================================================================ CUSTOM DASHBOARD CSS ================================================================ --}}
{{-- ================================================================ PAGE TITLE ================================================================ --}}

Admin Dashboard

School Performance & Result Analysis
{{-- ================================================================ ================================================================ ANALYSIS FILTER ================================================================ ================================================================ --}}
Result Analysis Filter
Select the session, term and class you want to analyze.
{{-- SESSION --}}
{{-- TERM --}}
{{-- CLASS --}}
{{-- FILTER BUTTON --}}
{{-- FILTER SUMMARY --}}
Currently analyzing: {{ $selectedClassName }} | {{ $analysisTerm ?: 'No Term Selected' }} | {{ $analysisSession ?: 'No Session Selected' }}
{{-- ================================================================ NO RESULT WARNING ================================================================ --}} @if($totalResultRecords == 0)
No result data found. There are currently no results for: {{ $selectedClassName }}, {{ $analysisTerm }}, {{ $analysisSession }}.
@endif {{-- ================================================================ BASIC SCHOOL INFORMATION CARDS ================================================================ --}}
{{-- TOTAL STUDENTS --}}

Total Students

{{ $totalstudent }}

{{-- SUBJECTS --}}

Total Subjects

{{ $totalsubject }}

{{-- CLASSES --}}

Total Classes

{{ $totalclass }}

{{-- TEACHERS --}}

Total Teachers

{{ $totalteachers }}

{{-- ================================================================ RESULT ANALYSIS STAT CARDS ================================================================ --}}
{{-- OVERALL AVERAGE --}}

Overall Average

{{ number_format($overallAverage, 2) }}%

Final result performance
{{-- PASS RATE --}}

Pass Rate

{{ number_format($passPercentage, 2) }}%

Pass mark: {{ $passMark }}
{{-- STUDENTS ABOVE AVERAGE --}}

Above Average

{{ $studentsAboveAverage->count() }}

Students
{{-- BELOW AVERAGE --}}

Below Average

{{ $studentsBelowAverage->count() }}

Students needing attention
{{-- ================================================================ SECONDARY ANALYSIS CARDS ================================================================ --}}
{{-- ASSESSED STUDENTS --}}

Students Assessed

{{ $totalStudentsAssessed }}

Out of {{ $totalStudentsInFilter }} students
{{-- MISSING RESULTS --}}

Missing Results

{{ $missingResultStudents }}

Students without result records
{{-- HIGHEST SCORE --}}

Highest Score

{{ number_format($highestScore, 2) }}%

Highest recorded subject score
{{-- LOWEST SCORE --}}

Lowest Score

{{ number_format($lowestScore, 2) }}%

Lowest recorded subject score
{{-- ================================================================ PERFORMANCE SUMMARY ================================================================ --}}
Performance Summary
Automatic interpretation of the selected result data.
Average Performance

{{ number_format($overallPercentage, 2) }}%

This represents the average final score of all result records in the selected analysis.

Student Average

{{ number_format($studentOverallAverage, 2) }}%

This is the average of the individual students' overall subject averages.

Result Records

{{ number_format($totalResultRecords) }}

Total subject-result records included in this analysis.

{{-- ================================================================ CHART ROW 1 ================================================================ --}}
{{-- CLASS PERFORMANCE --}}
Class Performance Comparison
Average final score per class.
{{-- PASS VS FAIL --}}
Pass vs Fail
Based on {{ $passMark }} pass mark.
{{-- ================================================================ CHART ROW 2 ================================================================ --}}
{{-- SUBJECT PERFORMANCE --}}
Subject Performance
Average score achieved in each subject.
{{-- GRADE DISTRIBUTION --}}
Grade Distribution
Number of result records per grade.
{{-- ================================================================ CHART ROW 3 ================================================================ --}}
{{-- TOP STUDENTS --}}
Top 10 Students
Ranked according to overall average score.
{{-- ABOVE / BELOW AVERAGE --}}
Student Performance Level
Comparison against student overall average.
{{-- ================================================================ SCORE DISTRIBUTION ================================================================ --}}
Score Distribution
Shows how many subject results fall inside each score range.
{{-- ================================================================ TOP STUDENTS TABLE ================================================================ --}}
Top Performing Students
Students with the highest overall average.
@forelse($topStudents as $index => $student) @empty @endforelse
# Student Class Subjects Total Score Average Performance
{{ $index + 1 }} {{ $student['student']->name ?? 'Unknown Student' }} {{ $student['class']->class_name ?? 'Unknown' }} {{ $student['subjects'] }} {{ number_format($student['total_score'], 2) }} {{ number_format($student['average'], 2) }}% Above Average
No student result data available.
{{-- ================================================================ BELOW AVERAGE STUDENTS ================================================================ --}}
Students Below Average
These students have an overall average below the calculated student average of {{ number_format($studentOverallAverage, 2) }}% .
@forelse($lowestStudents as $index => $student) @php /* |-------------------------------------------------------------------------- | Difference shows how far the student is below | the calculated student average. |-------------------------------------------------------------------------- */ $difference = $studentOverallAverage - $student['average']; @endphp @empty @endforelse
# Student Class Subjects Average Difference From Average Status
{{ $index + 1 }} {{ $student['student']->name ?? 'Unknown Student' }} {{ $student['class']->class_name ?? 'Unknown' }} {{ $student['subjects'] }} {{ number_format($student['average'], 2) }}% {{ number_format($difference, 2) }}% Below Average
No students are currently below average.
{{-- ================================================================ SUBJECT PERFORMANCE TABLE ================================================================ --}}
Subject Performance Analysis
Helps management identify subjects that require additional academic attention.
@forelse($subjectPerformance as $index => $subject) @php /* |-------------------------------------------------------------------------- | We classify the subject based on its average. | | This is a descriptive classification, | not a ranking of students. |-------------------------------------------------------------------------- */ if ($subject['average'] >= 70) { $subjectLevel = 'Strong'; $subjectBadge = 'success'; } elseif ($subject['average'] >= 50) { $subjectLevel = 'Moderate'; $subjectBadge = 'warning'; } else { $subjectLevel = 'Needs Attention'; $subjectBadge = 'danger'; } @endphp @empty @endforelse
# Subject Students Average Highest Lowest Performance Level
{{ $index + 1 }} {{ $subject['subject_name'] }} {{ $subject['students'] }} {{ number_format($subject['average'], 2) }}% {{ number_format($subject['highest'], 2) }}% {{ number_format($subject['lowest'], 2) }}% {{ $subjectLevel }}
No subject result data available.
{{-- ================================================================ CLASS PERFORMANCE TABLE ================================================================ --}}
Class Performance Analysis
Average result performance by class.
@forelse($classPerformance as $index => $class) @empty @endforelse
# Class Students Assessed Result Records Average Performance
{{ $index + 1 }} {{ $class['class_name'] }} {{ $class['students'] }} {{ $class['results'] }} {{ number_format($class['average'], 2) }}% @if($class['average'] >= 70) Strong @elseif($class['average'] >= 50) Moderate @else Needs Attention @endif
No class result data available.
{{-- ================================================================ CBT SUMMARY ================================================================ --}}

CBT Tests

{{ $totalTests }}

Current term/session

CBT Attempts

{{ $totalAttempts }}

Total attempts

Completed CBT

{{ $completedAttempts }}

Completed attempts

CBT In Progress

{{ $inProgressAttempts }}

Active attempts
{{-- ================================================================ STUDENT GROWTH ================================================================ --}}
Student Growth
Number of students registered each month during {{ date('Y') }}.
{{-- ================================================================ CHART.JS ================================================================ --}} @endsection