import React, { useState, useEffect } from 'react'; import { ArrowLeft, BookOpen, ChevronRight, FileText, CheckCircle2, Circle, MessageSquare, AlertCircle, Award } from 'lucide-react'; import VideoPlayer from './VideoPlayer'; import CourseActivity from './CourseActivity'; interface LessonProgress { watchedPercentage: number; completed: boolean; } interface Lesson { id: string; moduleId: string; title: string; videoUrl: string; videoType: 'youtube' | 'direct'; order: number; content: string; progress: LessonProgress; note: string; } interface Module { id: string; courseId: string; title: string; order: number; lessons: Lesson[]; } interface Course { id: string; title: string; description: string; thumbnail: string; category: string; } interface CourseViewProps { courseId: string; token: string | null; onBack: () => void; } export default function CourseView({ courseId, token, onBack }: CourseViewProps) { const [course, setCourse] = useState(null); const [modules, setModules] = useState([]); const [activeLesson, setActiveLesson] = useState(null); const [noteContent, setNoteContent] = useState(''); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle'); const [activeActivityModuleId, setActiveActivityModuleId] = useState(null); useEffect(() => { fetchCourseDetails(); }, [courseId]); const fetchCourseDetails = async () => { setIsLoading(true); setError(null); try { const res = await fetch(`/api/courses/${courseId}`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!res.ok) { throw new Error('Falha ao carregar detalhes do curso'); } const data = await res.json(); setCourse(data.course); setModules(data.modules); // Default to the first lesson of the first module if (data.modules && data.modules.length > 0) { const firstMod = data.modules[0]; if (firstMod.lessons && firstMod.lessons.length > 0) { const firstLsn = firstMod.lessons[0]; setActiveLesson(firstLsn); setNoteContent(firstLsn.note || ''); } } } catch (err: any) { setError(err.message || 'Erro inesperado.'); } finally { setIsLoading(false); } }; const handleSelectLesson = (lesson: Lesson) => { setActiveLesson(lesson); setNoteContent(lesson.note || ''); setSaveStatus('idle'); }; const handleProgressUpdate = async (watchedPercentage: number) => { if (!activeLesson) return; try { const res = await fetch(`/api/lessons/${activeLesson.id}/progress`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ watchedPercentage }) }); if (res.ok) { const data = await res.json(); // Update local state for lesson progress setModules(prev => prev.map(mod => { return { ...mod, lessons: mod.lessons.map(lsn => { if (lsn.id === activeLesson.id) { return { ...lsn, progress: { watchedPercentage: Math.max(lsn.progress.watchedPercentage, watchedPercentage), completed: data.completed || lsn.progress.completed } }; } return lsn; }) }; })); // Also update the active lesson progress locally setActiveLesson(prev => { if (!prev) return null; return { ...prev, progress: { watchedPercentage: Math.max(prev.progress.watchedPercentage, watchedPercentage), completed: data.completed || prev.progress.completed } }; }); } } catch (err) { console.error('Error saving progress:', err); } }; const handleSaveNote = async () => { if (!activeLesson) return; setSaveStatus('saving'); try { const res = await fetch(`/api/lessons/${activeLesson.id}/notes`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ content: noteContent }) }); if (res.ok) { setSaveStatus('saved'); // Update local modules array so state matches setModules(prev => prev.map(mod => { return { ...mod, lessons: mod.lessons.map(lsn => { if (lsn.id === activeLesson.id) { return { ...lsn, note: noteContent }; } return lsn; }) }; })); setTimeout(() => setSaveStatus('idle'), 3000); } else { setSaveStatus('error'); } } catch (err) { setSaveStatus('error'); } }; if (isLoading) { return (

Preparando seu ambiente de estudos...

); } if (error || !course) { return (

Oops! Algo deu errado

{error || 'Não foi possível carregar as informações deste curso.'}

); } if (activeActivityModuleId) { return ( setActiveActivityModuleId(null)} onCompleted={(passed) => { if (passed) { // Re-fetch course details to update any unlocked certificates if applicable fetchCourseDetails(); } }} /> ); } return (
{/* Back Header */}
{course.category}
{/* Main Grid: Player on left, lessons sidebar on right */}
{/* Left Hand: Video & Notes */}
{activeLesson ? (

{activeLesson.title}

{/* Lesson Description Content */} {activeLesson.content && (

Recursos & Descrição da Aula

{activeLesson.content}

)} {/* Notes & Doubts panel */}

Suas Anotações e Dúvidas

{saveStatus === 'saving' && Salvando...} {saveStatus === 'saved' && Salvo com sucesso!} {saveStatus === 'error' && Erro ao salvar.}