import React, { useState, useEffect } from 'react'; import { GraduationCap, Plus, Edit, Trash2, FolderPlus, FilePlus, ChevronRight, ArrowLeft, Film, Youtube, RefreshCw, Layers, CheckCircle, CheckCircle2 } from 'lucide-react'; interface Lesson { id: string; moduleId: string; title: string; videoUrl: string; videoType: 'youtube' | 'direct'; order: number; content: string; thumbnailUrl?: 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; isLocked?: boolean; price?: number; certificateMode?: string; } interface AdminContentManagerProps { token: string | null; } export default function AdminContentManager({ token }: AdminContentManagerProps) { const [courses, setCourses] = useState([]); const [selectedCourse, setSelectedCourse] = useState(null); const [modules, setModules] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); // Forms states const [showCourseForm, setShowCourseForm] = useState(false); const [editingCourse, setEditingCourse] = useState(null); const [courseForm, setCourseForm] = useState({ title: '', description: '', thumbnail: '', category: '', isLocked: false, price: 0, certificateMode: 'FULL_COURSE' as 'FULL_COURSE' | 'PER_MODULE' }); const [showModuleForm, setShowModuleForm] = useState(false); const [editingModule, setEditingModule] = useState(null); const [moduleForm, setModuleForm] = useState({ title: '', order: 1 }); const [showLessonForm, setShowLessonForm] = useState(false); const [editingLesson, setEditingLesson] = useState(null); const [activeModuleForLesson, setActiveModuleForLesson] = useState(null); const [lessonForm, setLessonForm] = useState({ title: '', videoUrl: '', videoType: 'youtube' as 'youtube' | 'direct', order: 1, content: '', thumbnailUrl: '' }); const [managingActivityForModule, setManagingActivityForModule] = useState(null); const [showActivityModal, setShowActivityModal] = useState(false); const [activeModuleForActivity, setActiveModuleForActivity] = useState(null); const [activityQuestions, setActivityQuestions] = useState<{question: string, options: string[], correctIndex: number}[]>([]); const [uploadingImage, setUploadingImage] = useState(false); const handleImageUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const formData = new FormData(); formData.append('file', file); setUploadingImage(true); try { const res = await fetch('/api/admin/upload', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` }, body: formData }); const data = await res.json(); if (res.ok && data.url) { setCourseForm(prev => ({ ...prev, thumbnail: data.url })); } else { alert(data.error || 'Erro ao fazer upload da imagem'); } } catch (err) { console.error(err); alert('Erro de conexão ao fazer upload'); } finally { setUploadingImage(false); } }; useEffect(() => { fetchCourses(); }, []); const fetchCourses = async () => { setIsLoading(true); try { const res = await fetch('/api/courses', { headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { const data = await res.json(); setCourses(data); } } catch (err) { console.error('Error fetching courses:', err); } finally { setIsLoading(false); } }; const fetchCourseModulesAndLessons = async (courseId: string) => { setIsLoading(true); try { const res = await fetch(`/api/courses/${courseId}`, { headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { const data = await res.json(); setModules(data.modules); } } catch (err) { console.error('Error loading modules:', err); } finally { setIsLoading(false); } }; const handleSelectCourse = (course: Course) => { setSelectedCourse(course); fetchCourseModulesAndLessons(course.id); }; // --- COURSE CRUD --- const handleSaveCourse = async (e: React.FormEvent) => { e.preventDefault(); const method = editingCourse ? 'PUT' : 'POST'; const url = editingCourse ? `/api/admin/courses/${editingCourse.id}` : '/api/admin/courses'; try { const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(courseForm) }); if (res.ok) { await fetchCourses(); setShowCourseForm(false); setEditingCourse(null); setCourseForm({ title: '', description: '', thumbnail: '', category: '', isLocked: false, price: 0, certificateMode: 'FULL_COURSE' }); } else { const errData = await res.json(); alert(`Erro ao salvar curso: ${errData.error || 'Falha na resposta do servidor'}`); } } catch (err) { console.error('Error saving course:', err); alert('Erro de rede ao salvar curso.'); } }; const handleEditCourse = (course: Course) => { setEditingCourse(course); setCourseForm({ title: course.title, description: course.description, thumbnail: course.thumbnail, category: course.category, isLocked: course.isLocked || false, price: course.price || 0, certificateMode: (course.certificateMode || 'FULL_COURSE') as 'PER_MODULE' | 'FULL_COURSE' }); setShowCourseForm(true); setTimeout(() => { document.getElementById('admin-content-top')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 50); }; const handleDeleteCourse = async (courseId: string) => { if (!window.confirm('Tem certeza que deseja excluir este curso e todo o seu conteúdo (módulos, aulas, anotações)?')) return; try { const res = await fetch(`/api/admin/courses/${courseId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { fetchCourses(); if (selectedCourse?.id === courseId) { setSelectedCourse(null); setModules([]); } } } catch (err) { console.error('Error deleting course:', err); } }; // --- MODULE CRUD --- const handleSaveModule = async (e: React.FormEvent) => { e.preventDefault(); if (!selectedCourse) return; const method = editingModule ? 'PUT' : 'POST'; const url = editingModule ? `/api/admin/modules/${editingModule.id}` : '/api/admin/modules'; const payload = editingModule ? { ...moduleForm } : { ...moduleForm, courseId: selectedCourse.id }; try { const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(payload) }); if (res.ok) { await fetchCourseModulesAndLessons(selectedCourse.id); setShowModuleForm(false); setEditingModule(null); setModuleForm({ title: '', order: 1 }); } } catch (err) { console.error('Error saving module:', err); } }; const handleEditModule = (mod: Module) => { setEditingModule(mod); setModuleForm({ title: mod.title, order: mod.order }); setShowModuleForm(true); setTimeout(() => { document.getElementById('admin-content-top')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 50); }; const handleDeleteModule = async (modId: string) => { if (!window.confirm('Excluir este módulo apagará todas as suas aulas associadas. Continuar?')) return; if (!selectedCourse) return; try { const res = await fetch(`/api/admin/modules/${modId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { fetchCourseModulesAndLessons(selectedCourse.id); } } catch (err) { console.error('Error deleting module:', err); } }; // --- LESSON CRUD --- const handleSaveLesson = async (e: React.FormEvent) => { e.preventDefault(); if (!selectedCourse) return; const method = editingLesson ? 'PUT' : 'POST'; const url = editingLesson ? `/api/admin/lessons/${editingLesson.id}` : '/api/admin/lessons'; const payload = editingLesson ? { ...lessonForm } : { ...lessonForm, moduleId: activeModuleForLesson }; try { const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(payload) }); if (res.ok) { await fetchCourseModulesAndLessons(selectedCourse.id); setShowLessonForm(false); setEditingLesson(null); setActiveModuleForLesson(null); setLessonForm({ title: '', videoUrl: '', videoType: 'youtube', order: 1, content: '', thumbnailUrl: '' }); } } catch (err) { console.error('Error saving lesson:', err); } }; const handleNewLesson = (moduleId: string, lessonsCount: number) => { setActiveModuleForLesson(moduleId); setEditingLesson(null); setLessonForm({ title: '', videoUrl: '', videoType: 'youtube', order: lessonsCount + 1, content: '', thumbnailUrl: '' }); setShowLessonForm(true); setTimeout(() => { window.scrollTo({ top: 0, behavior: 'smooth' }); }, 50); }; const handleEditLesson = (lesson: Lesson) => { setEditingLesson(lesson); setActiveModuleForLesson(lesson.moduleId); setLessonForm({ title: lesson.title, videoUrl: lesson.videoUrl, videoType: lesson.videoType, order: lesson.order, content: lesson.content || '', thumbnailUrl: lesson.thumbnailUrl || '' }); setShowLessonForm(true); setTimeout(() => { document.getElementById('admin-content-top')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 50); }; const handleManageActivity = async (moduleId: string) => { setActiveModuleForActivity(moduleId); setActivityQuestions([]); try { const res = await fetch(`/api/admin/modules/${moduleId}/activity`, { headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { const data = await res.json(); setActivityQuestions(data.questions || []); } } catch (err) { console.error('Error fetching activity:', err); } setShowActivityModal(true); }; const handleSaveActivity = async () => { if (!activeModuleForActivity) return; try { const res = await fetch(`/api/admin/modules/${activeModuleForActivity}/activity`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ questions: activityQuestions }) }); if (res.ok) { alert('Atividade salva com sucesso!'); setShowActivityModal(false); } else { alert('Erro ao salvar atividade.'); } } catch (err) { console.error('Error saving activity:', err); alert('Erro ao salvar atividade.'); } }; const handleDeleteLesson = async (lessonId: string) => { if (!window.confirm('Excluir esta aula?')) return; if (!selectedCourse) return; try { const res = await fetch(`/api/admin/lessons/${lessonId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { fetchCourseModulesAndLessons(selectedCourse.id); } } catch (err) { console.error('Error deleting lesson:', err); } }; if (isLoading && courses.length === 0) { return (

Carregando catálogo de treinamentos...

); } return (
{/* Top Header */}

Gestão de Cursos, Módulos e Aulas

Crie cursos, adicione módulos e configure links de vídeo (YouTube ou Upload Direto).

{!selectedCourse && !showCourseForm && ( )}
{/* Helper Banner for Questionnaires / Activities */} {!selectedCourse && !showCourseForm && (

Como Criar as Questões e Atividades dos Alunos?

Escolha um curso abaixo clicando no botão Gerenciar Módulos & Questões. Em seguida, em cada módulo, clique no botão verde 📝 Criar / Editar Questões para adicionar perguntas e respostas!

)} {/* --- RENDER COURSE FORM --- */} {showCourseForm && (

{editingCourse ? 'Editar Detalhes do Curso' : 'Criar Novo Curso'}

setCourseForm({ ...courseForm, title: e.target.value })} placeholder="Ex: Infraestrutura de Servidores Linux" className="w-full glass-input rounded-lg p-3 text-sm text-white focus:outline-none" />
setCourseForm({ ...courseForm, category: e.target.value })} placeholder="Ex: Redes e Servidores" className="w-full glass-input rounded-lg p-3 text-sm text-white focus:outline-none" />
setCourseForm({ ...courseForm, thumbnail: e.target.value })} placeholder="https://images.unsplash.com/... ou link de imagem direta" className="flex-1 glass-input rounded-lg p-3 text-sm text-white focus:outline-none" />
setCourseForm({ ...courseForm, price: Number(e.target.value) })} className="w-full glass-input rounded-lg p-3 text-sm text-white focus:outline-none" />