"use client"; import { useEffect, useState } from "react"; import { lmsApi, Lesson, Course, Module, UserGrade } from "@/lib/api"; import Link from "next/link"; import { ChevronLeft, ChevronRight, Menu, CheckCircle2 } from "lucide-react"; import { useAuth } from "@/context/AuthContext"; import DescriptionPlayer from "@/components/blocks/DescriptionPlayer"; import MediaPlayer from "@/components/blocks/MediaPlayer"; import QuizPlayer from "@/components/blocks/QuizPlayer"; import FillInTheBlanksPlayer from "@/components/blocks/FillInTheBlanksPlayer"; import MatchingPlayer from "@/components/blocks/MatchingPlayer"; import OrderingPlayer from "@/components/blocks/OrderingPlayer"; import ShortAnswerPlayer from "@/components/blocks/ShortAnswerPlayer"; import InteractiveTranscript from "@/components/InteractiveTranscript"; import { ListMusic } from "lucide-react"; export default function LessonPlayerPage({ params }: { params: { id: string, lessonId: string } }) { const [lesson, setLesson] = useState(null); const [course, setCourse] = useState<(Course & { modules: Module[] }) | null>(null); const [loading, setLoading] = useState(true); const [sidebarOpen, setSidebarOpen] = useState(true); const [transcriptOpen, setTranscriptOpen] = useState(true); const [currentTime, setCurrentTime] = useState(0); const [userGrade, setUserGrade] = useState(null); const { user } = useAuth(); useEffect(() => { const fetchAll = async () => { try { const [lessonData, courseData] = await Promise.all([ lmsApi.getLesson(params.lessonId), lmsApi.getCourseOutline(params.id) ]); setLesson(lessonData); setCourse(courseData); if (user) { const grades = await lmsApi.getUserGrades(user.id, params.id); const currentGrade = grades.find((g: UserGrade) => g.lesson_id === params.lessonId); setUserGrade(currentGrade || null); } } catch (err) { console.error("Failed to load lesson data", err); } finally { setLoading(false); } }; fetchAll(); }, [params.id, params.lessonId, user]); if (loading) return
Loading Experience...
; if (!lesson || !course) return
Content not found.
; const allLessons = course.modules.flatMap(m => m.lessons); const currentIndex = allLessons.findIndex(l => l.id === params.lessonId); const prevLesson = allLessons[currentIndex - 1]; const nextLesson = allLessons[currentIndex + 1]; const hasTranscription = lesson.transcription && lesson.transcription.cues && lesson.transcription.cues.length > 0; const handleSeek = (time: number) => { const videoElement = document.querySelector('video'); if (videoElement) { videoElement.currentTime = time; videoElement.play(); } }; return (
{/* Navigation Sidebar */} {/* Main Content Area */}
{hasTranscription && ( )}
{lesson.content_type === 'activity' ? 'Interactive Activity' : 'Video Lesson'}

{lesson.title}

{lesson.summary && (

Summary

"{lesson.summary}"

)} {/* Render Blocks */} {(lesson.metadata?.blocks || []).length > 0 ? (
{lesson.metadata?.blocks?.map((block) => (
{block.type === 'description' && ( )} {block.type === 'media' && ( )[block.id] || 0 : 0 } onPlay={async () => { if (user && lesson.max_attempts && (!userGrade || userGrade.attempts_count < lesson.max_attempts)) { const currentPlayCounts = (userGrade?.metadata?.play_counts as Record) || {}; const newPlayCounts = { ...currentPlayCounts, [block.id]: (currentPlayCounts[block.id] || 0) + 1 }; try { const res = await lmsApi.submitScore( user.id, params.id, params.lessonId, userGrade?.score || 0, { ...userGrade?.metadata, play_counts: newPlayCounts } ); setUserGrade(res); } catch (err) { console.error("Failed to persist play count", err); } } }} /> )} {block.type === 'quiz' && ( )[block.id] || 0 : 0 } onAttempt={async () => { if (user) { const currentAttempts = (userGrade?.metadata?.block_attempts as Record) || {}; const newAttempts = { ...currentAttempts, [block.id]: (currentAttempts[block.id] || 0) + 1 }; try { const res = await lmsApi.submitScore( user.id, params.id, params.lessonId, userGrade?.score || 0, { ...userGrade?.metadata, block_attempts: newAttempts } ); setUserGrade(res); } catch (err) { console.error("Failed to persist block attempts", err); } } }} /> )} {block.type === 'fill-in-the-blanks' && ( )} {block.type === 'matching' && ( )} {block.type === 'ordering' && ( )} {block.type === 'short-answer' && ( )}
))}
) : (

This lesson currently has no content.

)} {lesson.is_graded && (
{userGrade && lesson.max_attempts && userGrade.attempts_count >= lesson.max_attempts ? (
Locked: Maximum attempts reached ({lesson.max_attempts})
Score: {userGrade.score * 100}%

This assessment is now closed for further submissions.

) : ( <> {lesson.max_attempts && (

Attempt {userGrade ? userGrade.attempts_count : 0} of {lesson.max_attempts} used

)} )}
)}
{/* Interactive Transcript Panel */} {hasTranscription && transcriptOpen && ( )}
{/* Footer Controls */}
); }