import React, { useState, useEffect, useRef } from 'react'; import { X, Send, User as UserIcon, Lightbulb, Paperclip, Lock, Unlock, ListVideo, Play, Download, Sparkles, MessageSquare, CheckCircle2, Check, Share2, FileText } from 'lucide-react'; import { Course, Comment, Lesson, Attachment } from '../types'; import { useAuth } from '../context/AuthContext'; import { getComments, saveComment, saveProgress, incrementViews } from '../services/db'; import { LoginModal } from './LoginModal'; import { MaterialCard } from './MaterialCard'; interface CoursePlayerModalProps { course: Course | null; onClose: () => void; } export const CoursePlayerModal: React.FC = ({ course, onClose }) => { const { user } = useAuth(); const [comments, setComments] = useState([]); const [newComment, setNewComment] = useState(''); const [currentProgress, setCurrentProgress] = useState(0); const [currentLesson, setCurrentLesson] = useState(null); const [completedLessonIds, setCompletedLessonIds] = useState([]); const [showLoginPrompt, setShowLoginPrompt] = useState(false); const [activeTab, setActiveTab] = useState<'playlist' | 'materials' | 'discussion'>('playlist'); const [copiedLink, setCopiedLink] = useState(false); const videoRef = useRef(null); // Load course data & completed lessons from storage useEffect(() => { if (course) { incrementViews(course.id); getComments(course.id).then(setComments); setCurrentProgress(course.progress || 0); // Load completed lessons from localStorage const storageKey = `course_${course.id}_completed_lessons`; const savedCompleted = localStorage.getItem(storageKey); if (savedCompleted) { try { setCompletedLessonIds(JSON.parse(savedCompleted)); } catch (e) { setCompletedLessonIds([]); } } else if (course.progress && course.progress > 0 && course.lessons && course.lessons.length > 0) { // Initial demo completion based on progress const count = Math.ceil((course.progress / 100) * course.lessons.length); const initialCompleted = course.lessons.slice(0, count).map(l => l.id); setCompletedLessonIds(initialCompleted); localStorage.setItem(storageKey, JSON.stringify(initialCompleted)); } // Select first lesson by default if (course.lessons && course.lessons.length > 0) { setCurrentLesson(course.lessons[0]); } } }, [course]); // Persist completed lessons and recalculate progress const updateCompletedLessons = (newCompleted: string[]) => { setCompletedLessonIds(newCompleted); if (course) { localStorage.setItem(`course_${course.id}_completed_lessons`, JSON.stringify(newCompleted)); if (course.lessons && course.lessons.length > 0) { const percent = Math.round((newCompleted.length / course.lessons.length) * 100); setCurrentProgress(percent); saveProgress(course.id, percent); } } }; const toggleLessonCompleted = (lessonId: string) => { if (completedLessonIds.includes(lessonId)) { const updated = completedLessonIds.filter(id => id !== lessonId); updateCompletedLessons(updated); } else { const updated = [...completedLessonIds, lessonId]; updateCompletedLessons(updated); } }; // Video finished automatically -> mark lesson as completed const handleVideoEnded = () => { if (currentLesson && !completedLessonIds.includes(currentLesson.id)) { const updated = [...completedLessonIds, currentLesson.id]; updateCompletedLessons(updated); } // Auto-advance to next lesson if available if (course?.lessons && currentLesson) { const currentIndex = course.lessons.findIndex(l => l.id === currentLesson.id); if (currentIndex >= 0 && currentIndex < course.lessons.length - 1) { const nextLesson = course.lessons[currentIndex + 1]; if (user) { setTimeout(() => { setCurrentLesson(nextLesson); }, 1000); } } } }; // Track video progress const handleTimeUpdate = () => { if (videoRef.current) { const { currentTime, duration } = videoRef.current; if (duration > 0) { const percent = Math.round((currentTime / duration) * 100); // Automatically mark as complete when reaching 95%+ if (percent >= 95 && currentLesson && !completedLessonIds.includes(currentLesson.id)) { const updated = [...completedLessonIds, currentLesson.id]; updateCompletedLessons(updated); } } } }; const handleAddComment = async (e: React.FormEvent) => { e.preventDefault(); if (!newComment.trim() || !course) return; const comment: Comment = { id: Date.now().toString(), courseId: course.id, lessonId: currentLesson?.id, user: user?.name || 'Aluno Convidado', text: newComment, date: new Date().toLocaleDateString('pt-BR') }; await saveComment(comment); setComments([comment, ...comments]); setNewComment(''); }; const changeLesson = (lesson: Lesson) => { setCurrentLesson(lesson); }; const handleShare = () => { navigator.clipboard.writeText(window.location.href); setCopiedLink(true); setTimeout(() => setCopiedLink(false), 2500); }; // Collect all downloadable materials for this course (Global + All Lessons) const allCourseAttachments: Array<{ attachment: Attachment; source: string }> = []; if (course?.attachments) { course.attachments.forEach(att => { allCourseAttachments.push({ attachment: att, source: 'Material Geral do Curso' }); }); } if (course?.lessons) { course.lessons.forEach(l => { if (l.attachments) { l.attachments.forEach(att => { allCourseAttachments.push({ attachment: att, source: l.title }); }); } }); } const currentLessonAttachments = currentLesson?.attachments || []; // Access Control Logic const canWatch = currentLesson && Boolean(user); if (!course) return null; return (
{/* Top Bar Floating Controls */}
{course.title}
{/* Main Left Column: Video & Lesson Details */}
{/* Video Player Section */}
{canWatch ? ( ) : ( // Locked State

Aula Exclusiva (Pro)

Esta aula e seus materiais de download complementares estão disponíveis para membros. Faça login para continuar assistindo.

)}
{/* Current Lesson Header Info */}
{course.category} {currentLesson?.duration || '15m'}
{/* Mark as completed toggle button */} {currentLesson && ( )} {/* Direct Button to Materials Tab if Available */} {allCourseAttachments.length > 0 && ( )}

{currentLesson?.title || course.title}

{currentLesson?.description || course.description}

{/* Lesson Specific Quick Downloads (if present) */} {currentLessonAttachments.length > 0 && (

Downloads Desta Aula

{currentLessonAttachments.length} {currentLessonAttachments.length === 1 ? 'arquivo' : 'arquivos'}
{currentLessonAttachments.map(att => ( ))}
)} {/* Instructor Key Takeaways / Tips */} {course.tips && course.tips.length > 0 && (

Recomendações Práticas do Instrutor

    {course.tips.map((tip, i) => (
  • {tip}
  • ))}
)}
{/* Right Sidebar: Tabs for Playlist, Materials, and Discussion */}
{/* Tab Navigation */}
{/* TAB CONTENT: Playlist */} {activeTab === 'playlist' && (
Trilha de Aulas {course.duration}
{course.lessons.map((lesson, index) => { const isActive = currentLesson?.id === lesson.id; const isCompleted = completedLessonIds.includes(lesson.id); const isLocked = !user; const hasAttachments = lesson.attachments && lesson.attachments.length > 0; return (
changeLesson(lesson)} className={` group flex items-start gap-3.5 p-3.5 rounded-xl cursor-pointer transition-all border ${isActive ? 'bg-orange-500/15 border-orange-500/40 text-orange-400 shadow-md shadow-orange-500/10' : isCompleted ? 'bg-emerald-950/40 hover:bg-emerald-900/50 border-emerald-500/30 text-emerald-300 shadow-sm' : 'bg-zinc-900/80 hover:bg-zinc-800/90 border-transparent text-gray-200' } ${isLocked ? 'opacity-70' : 'opacity-100'} `} > {/* Status Icon */}
{isActive ? (
) : isCompleted ? (
) : isLocked ? (
) : (
{index + 1}
)}

{lesson.title}

{lesson.duration} {isCompleted && ( Concluída )} {lesson.isFree ? ( Grátis ) : ( Exclusiva )} {hasAttachments && ( {lesson.attachments!.length} anexo(s) )}
); })}
)} {/* TAB CONTENT: Materials & Downloads */} {activeTab === 'materials' && (

Materiais para Download

Arquivos anexados a este curso

{allCourseAttachments.length} Total
{allCourseAttachments.length === 0 ? (

Nenhum material cadastrado para este curso ainda.

) : (
{allCourseAttachments.map((item, idx) => (
{item.source}
))}
)}
)} {/* TAB CONTENT: Discussion */} {activeTab === 'discussion' && (

Dúvidas & Comentários

{/* Comment Form */}
setNewComment(e.target.value)} placeholder={user ? "Faça uma pergunta sobre a aula..." : "Faça login para comentar"} disabled={!user} className="flex-1 bg-zinc-900/90 rounded-xl px-3.5 py-2.5 text-xs text-white placeholder:text-gray-500 focus:outline-none focus:ring-1 focus:ring-orange-500" />
{/* Comments List */}
{comments.length === 0 ? (

Nenhum comentário ainda. Seja o primeiro a perguntar!

) : ( comments.map(c => (
{c.user} {c.date}

{c.text}

{c.reply && (
Instrutor:

{c.reply}

)}
)) )}
)}
setShowLoginPrompt(false)} />
); };