user(); $course = Course::where('slug', $courseSlug)->firstOrFail(); $lesson = Lesson::where('slug', $lessonSlug)->where('type', 'quiz')->firstOrFail(); // Check if already completed $progress = UserProgress::where('user_id', $user->id) ->where('lesson_id', $lesson->id) ->first(); $previousResut = null; if ($progress && $progress->completed_at) { $previousResut = $progress->metadata['score'] ?? 0; } // Parse questions from metadata // Assuming structure: metadata->questions = [{ id, question, options[], correct_answer }] // We do NOT send 'correct_answer' to frontend $questions = collect($lesson->metadata['questions'] ?? [])->map(function ($q) { return [ 'id' => $q['id'], 'question' => $q['question'], 'options' => $q['options'], ]; }); // Use same layout data as CoursePlayer (simplified modules list) // Ideally refactor this shared logic or use a Service $modules = $course->modules()->with('lessons')->get()->map(function ($module) use ($user) { return [ 'id' => $module->id, 'title' => $module->title, 'lessons' => $module->lessons->map(function ($l) { return [ 'id' => $l->id, 'title' => $l->title, 'slug' => $l->slug, 'type' => $l->type, 'is_completed' => false // Simplified for now ]; }) ]; }); return Inertia::render('Courses/Exam', [ 'course' => [ 'title' => $course->title, 'slug' => $course->slug, ], 'modules' => $modules, 'lesson' => [ 'id' => $lesson->id, 'title' => $lesson->title, 'slug' => $lesson->slug, 'questions' => $questions, ], 'previousResult' => $previousResut, ]); } /** * Handle exam submission. */ public function store(Request $request, string $courseSlug, string $lessonSlug) { $lesson = Lesson::where('slug', $lessonSlug)->firstOrFail(); $user = $request->user(); $answers = $request->input('answers', []); // [question_id => selected_option] $questions = $lesson->metadata['questions'] ?? []; $score = 0; $total = count($questions); $correctAnswers = 0; foreach ($questions as $q) { $userAnswer = $answers[$q['id']] ?? null; if ($userAnswer === $q['correct_answer']) { $correctAnswers++; } } $minPassPercentage = 70; // Hardcoded requirement for certificate $accuracy = ($total > 0) ? round(($correctAnswers / $total) * 100) : 0; $passed = $accuracy >= $minPassPercentage; // Save progress with score UserProgress::updateOrCreate( ['user_id' => $user->id, 'lesson_id' => $lesson->id], [ 'completed_at' => $passed ? now() : null, // Only mark complete if passed? Or mark complete but with failing score? Let's say only if passed. 'metadata' => [ 'score' => $accuracy, 'answers' => $answers, // Store user answers if needed for review 'passed' => $passed ] ] ); if ($passed) { $user->increment('xp_points', 100); } return back()->with('flash', [ 'score' => $accuracy, 'passed' => $passed, 'message' => $passed ? 'Selamat! Anda lulus ujian.' : 'Maaf, nilai anda belum mencukupi. Silahkan coba lagi.' ]); } }