@extends('layouts.app') @section('title', $module->title) @section('content') @include('partials.flash') arrow_back Back to {{ $course->title }} @php $minSeconds = $minSeconds ?? $module->effectiveMinSeconds(); $remaining = $completed ? 0 : max(0, (int) $minSeconds - (int) ($secondsSpent ?? 0)); $timerActive = ! $completed && (int) $minSeconds > 0 && $remaining > 0; // Interactive blocks (video / flip card / knowledge check / carousel / accordion) must be completed before finishing. $interactionCount = $module->blocks->whereIn('type', ['video', 'flip_card', 'knowledge_check', 'carousel', 'accordion'])->count(); $gateLocked = ! $completed && ($remaining > 0 || $interactionCount > 0); $currentIndex = $modules->search(fn ($m) => $m->id === $module->id); $typeLabel = [ 'content' => 'Content', 'knowledge_check' => 'Knowledge Check', 'final_assessment' => 'Final Assessment', 'certificate' => 'Certificate', ]; @endphp {{-- Modules stepper (interactive) --}}
@php // Frontier = first module not yet completed. Anything after it is locked. $firstIncomplete = $modules->search(fn ($m) => $m->progress_status !== 'completed'); if ($firstIncomplete === false) { $firstIncomplete = $modules->count(); } @endphp @foreach($modules as $i => $m) @php $isCurrent = $m->id === $module->id; $isDone = $m->progress_status === 'completed'; $isQuiz = in_array($m->module_type, ['knowledge_check','final_assessment'], true); $isLocked = $i > $firstIncomplete && ! $isCurrent; $to = $isQuiz ? auth()->user()->learnRoute('course.assessment.start', [$course->slug, $m->id]) : auth()->user()->learnRoute('course.module.show', [$course->slug, $m->id]); $node = $isDone ? 'bg-primary text-on-primary' : ($isCurrent ? 'bg-primary text-on-primary ring-4 ring-primary/20' : 'bg-surface border border-outline-variant text-outline'); @endphp <{{ $isLocked ? 'div' : 'a' }} @unless($isLocked) href="{{ $to }}" @endunless title="{{ $isLocked ? 'Complete the previous module first' : $m->title }}" class="step-link relative flex flex-col items-center w-[150px] shrink-0 {{ $isLocked ? 'cursor-not-allowed opacity-60' : '' }}"> {{-- connector to next node --}} @unless($loop->last) @endunless {{-- node with animated ring on the current step --}} @if($isCurrent && !$isDone) @endif @if($isDone) check @elseif($isLocked) lock @elseif($isQuiz) quiz @else {{ $i + 1 }} @endif {{-- labels --}}

{{ $i + 1 }}. {{ $m->title }}

{{ $typeLabel[$m->module_type] ?? 'Module' }}

@endforeach
{{-- Content --}}
@if($module->module_image) {{ $module->title }} @endif

Module {{ $module->module_number }}

{{ $module->title }}

@forelse($module->blocks as $block) @include('partials._content-block', ['block' => $block]) @empty
description

This module has no content yet.

@endforelse
{{-- Sticky sidebar: timer (left) + Your progress (right) in one card --}}
{{-- LEFT: timer / status --}}
@if($timerActive) @php $r = 42; $circ = 2 * M_PI * $r; @endphp
--:--
@elseif($completed) check_circle @else {{ (int) $minSeconds > 0 ? 'timer' : 'menu_book' }} @endif
{{-- RIGHT: Your progress --}}

Your progress

@if($completed)

Module completed

@elseif($timerActive)

Unlocks when the timer ends — keep this open.

@elseif((int) $minSeconds > 0)

Minimum time reached

@else

Work through the content, then mark it complete.

@endif
@if($completed) Back to course @else @if($interactionCount > 0)
interactive_space Activities 0/{{ $interactionCount }} completed
@endif
@csrf
@endif
@unless($completed) @endunless @endsection