@extends('layouts.portal') @php use App\Support\ExamText; use App\Support\Share; $voided = $a->status === 'voided'; $passed = ! $voided && $a->passed; $verdict = $voided ? 'void' : ($passed ? 'pass' : 'fail'); $pct = (float) $a->percent; $mins = intdiv((int) $a->time_spent_seconds, 60); $secs = (int) $a->time_spent_seconds % 60; $timeTaken = $a->time_spent_seconds ? ($mins >= 60 ? intdiv($mins, 60).'h '.($mins % 60).'m' : $mins.'m '.str_pad((string) $secs, 2, '0', STR_PAD_LEFT).'s') : '—'; $domains = collect($a->domain_scores ?? [])->map(fn ($d, $k) => $d + ['name' => $k])->sortBy('percent')->values(); $weak = $domains->filter(fn ($d) => $d['percent'] < $exam->pass_percent)->take(2); $used = (int) ($elig['attempts_used'] ?? $a->attempt_no); $left = $exam->max_attempts ? max(0, $exam->max_attempts - $used) : null; $events = $a->violations > 0 || $a->auto_submitted ? $a->events()->get() : collect(); $evLabels = ['tab_hidden' => 'Switched to another tab or window', 'window_blur' => 'Exam window lost focus', 'fullscreen_exit' => 'Left full screen', 'copy' => 'Copy attempts', 'paste' => 'Paste attempts', 'context_menu' => 'Right-click attempts']; $evCounts = $events->whereIn('type', array_keys($evLabels))->groupBy('type')->map->count(); $autoNote = $events->firstWhere('type', 'auto_submit')?->meta['note'] ?? null; if ($autoNote === 'Time expired') { $autoNote = null; } $cred = $passed ? $a->credential : null; $issuance = $cred?->badge; $badge = $issuance?->badge; $enrolled = $exam->course && $a->user && $a->user->isEnrolledInCourse($exam->course_id); $shC = $cred ? Share::credential($cred) : null; $shB = $issuance ? Share::badge($issuance) : null; @endphp @section('title', 'Exam result') @section('subtitle', $exam->title.' · attempt '.$a->attempt_no.' · '.($a->submitted_at?->format('d M Y, g:i A') ?? '—')) @section('actions') My exams @if($a->isFinished()) Score report (PDF)@endif @endsection @section('content')
{{ $voided ? 'Attempt voided' : ($passed ? 'Congratulations' : 'Not passed this time') }}

@if($voided)This attempt was voided @elseif($passed)You passed {{ $exam->title }} @else You did not reach the pass mark @endif

@if($voided){{ $a->void_reason ?: 'An administrator voided this attempt.' }} Contact your trainer or the academy office if you believe this is a mistake. @elseif($passed)You scored {{ rtrim(rtrim(number_format($pct, 2), '0'), '.') }}% against a pass mark of {{ $exam->pass_percent }}%.{{ $cred ? ' Your certificate and digital badge have been issued below.' : '' }} @else You scored {{ rtrim(rtrim(number_format($pct, 2), '0'), '.') }}%; the pass mark is {{ $exam->pass_percent }}%.@if($weak->isNotEmpty()) Focus your revision on {{ $weak->pluck('name')->join(', ', ' and ') }}.@endif @endif

@if($a->status === 'expired') Time ran out; saved answers were graded@endif @if($a->auto_submitted && $a->status !== 'expired') Submitted automatically@endif {{ $timeTaken }} of {{ $exam->duration_minutes }} min Attempt {{ $a->attempt_no }}{{ $exam->max_attempts ? ' of '.$exam->max_attempts : '' }}
@unless($voided) @endunless
@if($voided)
Why was this voided?
{{ $a->void_reason ?: 'The attempt did not meet the exam rules.' }} A voided attempt does not count towards your score.@if($canRetake) You may sit the exam again.@endif
@endif @unless($voided)
Score{{ rtrim(rtrim(number_format((float) $a->score, 2), '0'), '.') }} / {{ rtrim(rtrim(number_format((float) $a->max_score, 2), '0'), '.') }}marks earned
Result{{ $passed ? 'Passed' : 'Not passed' }}pass mark {{ $exam->pass_percent }}%
Time taken{{ $timeTaken }}of {{ $exam->duration_minutes }} minutes
Attempt{{ $a->attempt_no }}{{ $exam->max_attempts ? ' / '.$exam->max_attempts : '' }}{{ $left === null ? 'unlimited attempts' : $left.' left' }}
@endunless @if($passed)

Your credential

@if($cred)@endif
@if($cred)
@if($badge){{ $badge->name }} digital badge@endif

{{ $cred->title }}

{{ $badge ? $badge->name.' badge · ' : '' }}Credential ID {{ $cred->credential_id }} · Issued {{ $cred->issued_at?->format('d M Y') }}

Share your achievement

@else
Your certificate and badge are being prepared. They will appear under Certificates & badges and you will receive an email when they are ready.
@endif
@endif @if(! $passed && ! $voided)

Retaking this exam

@if($canRetake)

You can sit this exam again{{ $left === null ? '.' : ' — '.$left.' '.\Illuminate\Support\Str::plural('attempt', $left).' left.' }} A new attempt draws a fresh set of questions with shuffled answer options.

Review rules & retake @elseif(! empty($elig['next_at']))

Cooldown in effect. You can retake this exam ({{ $elig['next_at']->format('d M Y, g:i A') }}). Use the time to revise the domains below.

@else

No retake available. {{ $elig['reason'] ?? 'You have used all attempts for this exam.' }} Speak to your trainer if you need an extra attempt.

@endif
Attempts used
{{ $used }}{{ $exam->max_attempts ? ' of '.$exam->max_attempts : '' }}
Cooldown
{{ $exam->cooldown_hours ? $exam->cooldown_hours.' hours between attempts' : 'None' }}
@endif @if($domains->isNotEmpty() && ! $voided)

Performance by domain

Green marks reach the {{ $exam->pass_percent }}% pass mark
@foreach($domains as $d) @php $dp = (float) $d['percent']; $tone = $dp >= $exam->pass_percent ? 'green' : ($dp >= $exam->pass_percent - 20 ? 'amber' : 'red'); @endphp
{{ $d['name'] }}
{{ $d['correct'] }} of {{ $d['total'] }} correct
{{ round($dp) }}%
@endforeach
@endif @if(($evCounts->isNotEmpty() || $autoNote) && ! $voided)

Integrity summary

@if($a->violations){{ $a->violations }} {{ \Illuminate\Support\Str::plural('flag', $a->violations) }}@endif
@if($evCounts->isNotEmpty())

These events are recorded for every proctored exam and may be reviewed by the academy before a certificate is confirmed.

@endif @if($autoNote)
{{ $autoNote }}. Answers saved before that moment were graded.
@endif
@endif

Question review

@if($review)
@endif
@if($review) @foreach($review as $r) @php $state = ! $r['answered'] ? 'skip' : ($r['is_correct'] ? 'ok' : 'no'); @endphp
Question {{ $r['no'] }}@if($r['domain']){{ $r['domain'] }}@endif
{{ ['ok' => 'Correct', 'no' => 'Incorrect', 'skip' => 'Not answered'][$state] }}
{{ ExamText::html($r['question']) }}
Your answer
@if($r['given']){{ collect($r['given'])->map(fn ($t) => $t)->join(' · ') }}@else No answer given@endif
@if($state !== 'ok')
Correct answer
{{ collect($r['correct'])->join(' · ') }}
@endif
@if($r['explanation'])

Why: {{ $r['explanation'] }}

@endif
@endforeach @else
@if($voided)Answers are not shown for voided attempts. @elseif($exam->show_review === 'none')The answer review is switched off for this exam. Your score and domain breakdown above show where to focus. @elseif($exam->show_review === 'after_pass' && ! $passed)Question-by-question answers are released only to candidates who pass this exam. Use the domain breakdown above to plan your revision, then retake when you are ready. @else The answer review is not available for this attempt. @endif
@endif

What to do next

@if($enrolled && $exam->course)
Revise the course
{{ $exam->course->title }}: lessons, class materials and quizzes
@endif @foreach($labs as $lab)
{{ $lab->title }}
Hands-on lab · {{ $lab->duration_minutes }} min · {{ ucfirst($lab->difficulty) }}
@endforeach @if($passed)
Add it to your portfolio
Show employers your verified credential
Browse open roles
Apply with your verified certificate
@endif
Certificates & badges
Everything you have earned so far
@endsection @if($review) @push('scripts') @endpush @endif