import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import ReactMarkdown from 'react-markdown'; import { participantAPI } from '../services/api.service'; import SQLShopDemo from '../components/lessons/InteractiveContent/SQLShopDemo'; import BitBDemo from '../components/lessons/InteractiveContent/BitBDemo'; import XSSDeeplinkDemo from '../components/lessons/InteractiveContent/XSSDeeplinkDemo'; import ForumScriptDemo from '../components/lessons/InteractiveContent/ForumScriptDemo'; import SocialMediaPasswordDemo from '../components/lessons/InteractiveContent/SocialMediaPasswordDemo'; import IDORDemo from '../components/lessons/InteractiveContent/IDORDemo'; const LessonView = () => { const { eventLessonId } = useParams(); const navigate = useNavigate(); const [lesson, setLesson] = useState(null); const [currentStepIndex, setCurrentStepIndex] = useState(0); const [answers, setAnswers] = useState({}); const [feedback, setFeedback] = useState({}); const [totalScore, setTotalScore] = useState(0); const [loading, setLoading] = useState(true); const [completedInteractiveSteps, setCompletedInteractiveSteps] = useState(new Set()); useEffect(() => { loadLesson(); }, [eventLessonId]); const loadLesson = async () => { try { const response = await participantAPI.getLessonContent(eventLessonId); const lessonData = response.data.data; // Check if lesson is already completed if (lessonData.progress?.status === 'completed') { // Redirect back to event page - lesson already completed navigate('/event'); return; } setLesson(lessonData); await participantAPI.startLesson(eventLessonId); } catch (error) { console.error('Failed to load lesson:', error); } finally { setLoading(false); } }; const handleAnswer = async (questionId, answer) => { try { const response = await participantAPI.submitAnswer(eventLessonId, questionId, answer); const result = response.data.data; setFeedback(prev => ({ ...prev, [questionId]: result })); setTotalScore(result.totalScore); } catch (error) { console.error('Failed to submit answer:', error); } }; const handleComplete = async () => { try { await participantAPI.completeLesson(eventLessonId); navigate('/event'); } catch (error) { console.error('Failed to complete lesson:', error); } }; if (loading || !lesson) { return
Loading lesson...
; } const currentStep = lesson.steps[currentStepIndex]; const isLastStep = currentStepIndex === lesson.steps.length - 1; // Check if Previous button should be locked // Lock if any interactive step between 0 and current index has been completed const isPreviousLocked = Array.from(completedInteractiveSteps).some( completedIndex => completedIndex < currentStepIndex ); // Handler for Next button - mark interactive steps as completed const handleNext = () => { if (currentStep.type === 'interactive') { setCompletedInteractiveSteps(prev => new Set([...prev, currentStepIndex])); } setCurrentStepIndex(currentStepIndex + 1); }; return (

{currentStep.title}

{currentStep.type === 'content' && (
{currentStep.content}
)} {currentStep.type === 'interactive' && (
{currentStep.content && (
{currentStep.content}
)} {currentStep.interactiveComponent === 'SQLShopDemo' && ( )} {currentStep.interactiveComponent === 'BitBDemo' && ( )} {currentStep.interactiveComponent === 'XSSDeeplinkDemo' && ( )} {currentStep.interactiveComponent === 'ForumScriptDemo' && ( )} {currentStep.interactiveComponent === 'SocialMediaPasswordDemo' && ( )} {currentStep.interactiveComponent === 'IDORDemo' && ( )}
)} {currentStep.type === 'question' && (

{currentStep.question}

{currentStep.questionType === 'single_choice' && (
{currentStep.options.map(option => ( ))}
)} {currentStep.questionType === 'multiple_choice' && (
{currentStep.options.map(option => ( ))}
)} {currentStep.questionType === 'free_text' && (