microtecflix/src/components/AdminContentManager.tsx

748 lines
30 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import {
GraduationCap, Plus, Edit, Trash2, FolderPlus, FilePlus, ChevronRight,
ArrowLeft, Film, Youtube, RefreshCw, Layers, CheckCircle
} from 'lucide-react';
interface Lesson {
id: string;
moduleId: string;
title: string;
videoUrl: string;
videoType: 'youtube' | 'direct';
order: number;
content: 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;
}
interface AdminContentManagerProps {
token: string | null;
}
export default function AdminContentManager({ token }: AdminContentManagerProps) {
const [courses, setCourses] = useState<Course[]>([]);
const [selectedCourse, setSelectedCourse] = useState<Course | null>(null);
const [modules, setModules] = useState<Module[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Forms states
const [showCourseForm, setShowCourseForm] = useState(false);
const [editingCourse, setEditingCourse] = useState<Course | null>(null);
const [courseForm, setCourseForm] = useState({
title: '', description: '', thumbnail: '', category: '', isLocked: false, price: 0
});
const [showModuleForm, setShowModuleForm] = useState(false);
const [editingModule, setEditingModule] = useState<Module | null>(null);
const [moduleForm, setModuleForm] = useState({ title: '', order: 1 });
const [showLessonForm, setShowLessonForm] = useState(false);
const [editingLesson, setEditingLesson] = useState<Lesson | null>(null);
const [activeModuleForLesson, setActiveModuleForLesson] = useState<string | null>(null);
const [lessonForm, setLessonForm] = useState({
title: '', videoUrl: '', videoType: 'youtube' as 'youtube' | 'direct', order: 1, content: ''
});
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 });
}
} catch (err) {
console.error('Error saving course:', err);
}
};
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
});
setShowCourseForm(true);
};
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);
};
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: '' });
}
} 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: ''
});
setShowLessonForm(true);
};
const handleEditLesson = (lesson: Lesson) => {
setEditingLesson(lesson);
setLessonForm({
title: lesson.title,
videoUrl: lesson.videoUrl,
videoType: lesson.videoType,
order: lesson.order,
content: lesson.content
});
setShowLessonForm(true);
};
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 (
<div className="flex flex-col items-center justify-center min-h-[50vh] text-zinc-400 space-y-4">
<RefreshCw className="w-8 h-8 text-[#E50914] animate-spin" />
<p className="text-sm font-semibold">Carregando catálogo de treinamentos...</p>
</div>
);
}
return (
<div className="space-y-8">
{/* Top Header */}
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between border-b border-white/10 pb-5 gap-4">
<div>
<h1 className="text-2xl md:text-3xl font-display font-extrabold text-white tracking-tight flex items-center space-x-2">
<GraduationCap className="w-8 h-8 text-[#E50914]" />
<span>Gestão de Cursos, Módulos e Aulas</span>
</h1>
<p className="text-xs text-zinc-500 mt-1">Crie cursos, adicione módulos e configure links de vídeo (YouTube ou Upload Direto).</p>
</div>
{!selectedCourse && !showCourseForm && (
<button
onClick={() => { setEditingCourse(null); setCourseForm({ title: '', description: '', thumbnail: '', category: '' }); setShowCourseForm(true); }}
className="glass-btn-primary text-white font-bold text-xs px-4 py-2.5 rounded-lg flex items-center justify-center space-x-2 cursor-pointer self-start sm:self-auto"
>
<Plus className="w-4 h-4" />
<span>Adicionar Novo Curso</span>
</button>
)}
</div>
{/* --- RENDER COURSE FORM --- */}
{showCourseForm && (
<div className="glass-card p-6 rounded-2xl space-y-6">
<div className="flex items-center justify-between border-b border-white/5 pb-4">
<h3 className="text-lg font-bold text-white">
{editingCourse ? 'Editar Detalhes do Curso' : 'Criar Novo Curso'}
</h3>
<button
onClick={() => setShowCourseForm(false)}
className="text-zinc-500 hover:text-zinc-300 text-xs font-semibold"
>
Cancelar
</button>
</div>
<form onSubmit={handleSaveCourse} className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase tracking-wider">Título do Curso</label>
<input
type="text"
required
value={courseForm.title}
onChange={(e) => 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"
/>
</div>
<div className="space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase tracking-wider">Categoria / Trilha</label>
<input
type="text"
required
value={courseForm.category}
onChange={(e) => 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"
/>
</div>
<div className="md:col-span-2 space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase tracking-wider">Imagem de Capa (Thumbnail URL)</label>
<input
type="url"
required
value={courseForm.thumbnail}
onChange={(e) => setCourseForm({ ...courseForm, thumbnail: e.target.value })}
placeholder="https://images.unsplash.com/... ou link de imagem direta"
className="w-full glass-input rounded-lg p-3 text-sm text-white focus:outline-none"
/>
</div>
<div className="space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase tracking-wider">Preço do Curso para Desbloqueio (R$)</label>
<input
type="number"
step="0.01"
value={courseForm.price}
onChange={(e) => setCourseForm({ ...courseForm, price: Number(e.target.value) })}
placeholder="Ex: 89.90"
className="w-full glass-input rounded-lg p-3 text-sm text-white focus:outline-none font-mono"
/>
</div>
<div className="space-y-2 flex flex-col justify-center">
<label className="text-xs text-zinc-400 font-bold uppercase tracking-wider mb-2">Status de Bloqueio</label>
<label className="inline-flex items-center space-x-3 cursor-pointer">
<input
type="checkbox"
checked={courseForm.isLocked}
onChange={(e) => setCourseForm({ ...courseForm, isLocked: e.target.checked })}
className="rounded bg-zinc-900 border-white/10 text-[#E50914] focus:ring-[#E50914] focus:ring-offset-0 w-4 h-4"
/>
<span className="text-sm font-semibold text-zinc-300">Curso Trancado (Requer pagamento ou desbloqueio manual)</span>
</label>
</div>
<div className="md:col-span-2 space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase tracking-wider">Descrição Detalhada</label>
<textarea
required
value={courseForm.description}
onChange={(e) => setCourseForm({ ...courseForm, description: e.target.value })}
placeholder="Fale brevemente sobre o objetivo deste treinamento, o que o aluno vai aprender..."
className="w-full h-24 glass-input rounded-lg p-3 text-sm text-white focus:outline-none resize-none"
/>
</div>
<div className="md:col-span-2 flex justify-end">
<button
type="submit"
className="glass-btn-primary text-white text-xs font-bold px-6 py-3 rounded-lg cursor-pointer"
>
{editingCourse ? 'Salvar Alterações' : 'Criar Curso'}
</button>
</div>
</form>
</div>
)}
{/* --- RENDER COURSE DETAIL / CURRICULUM MANAGER --- */}
{selectedCourse ? (
<div className="space-y-6">
{/* Active Course Breadcrumb */}
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 glass-card p-4 rounded-xl">
<button
onClick={() => setSelectedCourse(null)}
className="flex items-center space-x-1.5 text-zinc-400 hover:text-white transition-colors text-xs font-bold"
>
<ArrowLeft className="w-4 h-4" />
<span>Voltar para Catálogo Completo</span>
</button>
<div className="flex items-center space-x-3">
<span className="text-zinc-600 text-xs font-bold">Curso Selecionado:</span>
<span className="text-white text-xs font-bold bg-[#E50914] px-2.5 py-1 rounded">
{selectedCourse.title}
</span>
</div>
<div className="flex space-x-2">
<button
onClick={() => { setEditingModule(null); setModuleForm({ title: '', order: modules.length + 1 }); setShowModuleForm(true); }}
className="glass-btn-secondary text-white text-xs font-bold px-3 py-1.5 rounded flex items-center space-x-1"
>
<FolderPlus className="w-3.5 h-3.5 text-zinc-400" />
<span>Criar Módulo</span>
</button>
</div>
</div>
{/* --- MODULE FORM DIALOG --- */}
{showModuleForm && (
<div className="glass-card p-6 rounded-2xl border-[#E50914]/30 space-y-4">
<h4 className="text-sm font-bold text-white uppercase tracking-wider">
{editingModule ? 'Editar Módulo' : 'Adicionar Novo Módulo'}
</h4>
<form onSubmit={handleSaveModule} className="flex flex-col sm:flex-row gap-4 items-end">
<div className="flex-1 space-y-1">
<label className="text-[10px] text-zinc-500 font-bold uppercase">Título do Módulo</label>
<input
type="text"
required
value={moduleForm.title}
onChange={(e) => setModuleForm({ ...moduleForm, title: e.target.value })}
placeholder="Ex: Módulo 1 - Fundamentos"
className="w-full glass-input rounded-lg p-2.5 text-xs text-white focus:outline-none"
/>
</div>
<div className="w-24 space-y-1">
<label className="text-[10px] text-zinc-500 font-bold uppercase">Ordem</label>
<input
type="number"
required
value={moduleForm.order}
onChange={(e) => setModuleForm({ ...moduleForm, order: Number(e.target.value) })}
className="w-full glass-input rounded-lg p-2.5 text-xs text-white focus:outline-none"
/>
</div>
<div className="flex space-x-2">
<button type="submit" className="glass-btn-primary text-white text-xs font-bold px-4 py-2.5 rounded-lg">
Salvar
</button>
<button type="button" onClick={() => setShowModuleForm(false)} className="text-xs text-zinc-500 px-2">
Cancelar
</button>
</div>
</form>
</div>
)}
{/* --- LESSON FORM DIALOG --- */}
{showLessonForm && (
<div className="glass-card p-6 rounded-2xl space-y-6">
<div className="flex items-center justify-between border-b border-white/5 pb-4">
<h4 className="text-sm font-bold text-white uppercase tracking-wider">
{editingLesson ? 'Editar Aula' : 'Adicionar Nova Aula'}
</h4>
<button type="button" onClick={() => setShowLessonForm(false)} className="text-xs text-zinc-500">
Cancelar
</button>
</div>
<form onSubmit={handleSaveLesson} className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="md:col-span-2 space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase">Título da Aula</label>
<input
type="text"
required
value={lessonForm.title}
onChange={(e) => setLessonForm({ ...lessonForm, title: e.target.value })}
placeholder="Ex: Como configurar SSH no Servidor Linux"
className="w-full glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
/>
</div>
<div className="space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase">Ordem Numérica</label>
<input
type="number"
required
value={lessonForm.order}
onChange={(e) => setLessonForm({ ...lessonForm, order: Number(e.target.value) })}
className="w-full glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
/>
</div>
<div className="space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase">Tipo de Vídeo</label>
<select
value={lessonForm.videoType}
onChange={(e) => setLessonForm({ ...lessonForm, videoType: e.target.value as 'youtube' | 'direct' })}
className="w-full glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
>
<option value="youtube">YouTube Embed (Privado/Não Listado)</option>
<option value="direct">Upload Direto / Link HTML5 MP4</option>
</select>
</div>
<div className="md:col-span-2 space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase">
{lessonForm.videoType === 'youtube'
? 'Link do Vídeo no YouTube (ou ID do vídeo)'
: 'Link URL do arquivo de vídeo direto (.mp4 / HLS)'}
</label>
<input
type="text"
required
value={lessonForm.videoUrl}
onChange={(e) => setLessonForm({ ...lessonForm, videoUrl: e.target.value })}
placeholder={lessonForm.videoType === 'youtube'
? 'Ex: https://www.youtube.com/watch?v=K8w3m_pM6lA'
: 'Ex: https://meuservidor.com/aulas/aula1.mp4'}
className="w-full glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
/>
</div>
<div className="md:col-span-3 space-y-2">
<label className="text-xs text-zinc-400 font-bold uppercase font-sans">Recursos Extras & Material de Apoio (Opcional)</label>
<textarea
value={lessonForm.content}
onChange={(e) => setLessonForm({ ...lessonForm, content: e.target.value })}
placeholder="Cole códigos de exemplo, links de arquivos zip ou notas de apoio aqui..."
className="w-full h-24 glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
/>
</div>
<div className="md:col-span-3 flex justify-end">
<button type="submit" className="glass-btn-primary text-white font-bold text-xs px-6 py-2.5 rounded-lg">
{editingLesson ? 'Salvar Aula' : 'Criar Aula'}
</button>
</div>
</form>
</div>
)}
{/* Curriculum Index (Modules & Lessons list) */}
<div className="space-y-4">
{modules.length === 0 ? (
<div className="p-8 text-center glass-card rounded-xl text-zinc-500">
<Layers className="w-8 h-8 mx-auto text-zinc-600 mb-2" />
<p className="text-sm font-semibold">Nenhum módulo cadastrado neste curso.</p>
<button
onClick={() => { setEditingModule(null); setModuleForm({ title: '', order: 1 }); setShowModuleForm(true); }}
className="mt-3 text-xs text-[#E50914] font-bold"
>
Criar primeiro módulo agora
</button>
</div>
) : (
modules.map((mod, modIdx) => (
<div key={mod.id} className="glass-card rounded-xl overflow-hidden">
{/* Module Header Panel */}
<div className="glass-accordion-header px-4 py-3 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
<div className="flex items-center space-x-2">
<span className="bg-zinc-800 border border-zinc-700 text-[#E50914] text-[10px] font-extrabold px-1.5 py-0.5 rounded">
M{mod.order}
</span>
<h4 className="font-sans font-extrabold text-sm text-zinc-100 tracking-tight">
{mod.title}
</h4>
</div>
<div className="flex items-center space-x-2">
{/* Add Lesson */}
<button
onClick={() => handleNewLesson(mod.id, mod.lessons.length)}
className="bg-zinc-800 text-zinc-300 hover:text-white hover:bg-zinc-700 text-[10px] font-bold px-2 py-1 rounded flex items-center space-x-1 border border-zinc-700 transition-colors"
>
<FilePlus className="w-3 h-3 text-[#E50914]" />
<span>Nova Aula</span>
</button>
{/* Edit Module */}
<button
onClick={() => handleEditModule(mod)}
className="text-zinc-500 hover:text-zinc-300 p-1"
title="Editar Módulo"
>
<Edit className="w-3.5 h-3.5" />
</button>
{/* Delete Module */}
<button
onClick={() => handleDeleteModule(mod.id)}
className="text-zinc-500 hover:text-red-400 p-1"
title="Excluir Módulo"
>
<Trash2 className="w-3.5 h-3.5" />
</button>
</div>
</div>
{/* Lessons Listing inside Module */}
<div className="divide-y divide-white/5 bg-black/10">
{mod.lessons.length === 0 ? (
<div className="p-4 text-xs text-zinc-600 italic text-center">Nenhuma aula cadastrada neste módulo.</div>
) : (
mod.lessons.map(lesson => (
<div key={lesson.id} className="px-6 py-3 flex items-center justify-between text-xs hover:bg-zinc-900/10 transition-colors">
<div className="flex items-center space-x-3 min-w-0">
<span className="text-zinc-500 font-mono font-bold w-4 text-right">#{lesson.order}</span>
{lesson.videoType === 'youtube' ? (
<Youtube className="w-4 h-4 text-red-500 flex-shrink-0" />
) : (
<Film className="w-4 h-4 text-emerald-500 flex-shrink-0" />
)}
<span className="font-semibold text-zinc-300 truncate max-w-sm sm:max-w-md md:max-w-lg">
{lesson.title}
</span>
</div>
<div className="flex items-center space-x-2 ml-4">
{/* Edit */}
<button
onClick={() => handleEditLesson(lesson)}
className="text-zinc-500 hover:text-white p-1"
title="Editar Aula"
>
<Edit className="w-3.5 h-3.5" />
</button>
{/* Delete */}
<button
onClick={() => handleDeleteLesson(lesson.id)}
className="text-zinc-500 hover:text-red-400 p-1"
title="Excluir Aula"
>
<Trash2 className="w-3.5 h-3.5" />
</button>
</div>
</div>
))
)}
</div>
</div>
))
)}
</div>
</div>
) : (
/* --- LIST ALL COURSES IN CATALOGUE --- */
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{courses.map(course => (
<div
key={course.id}
className="glass-card rounded-2xl overflow-hidden flex flex-col justify-between"
>
<div>
{/* Thumbnail */}
<div className="relative w-full aspect-video">
<img src={course.thumbnail} alt={course.title} className="w-full h-full object-cover" referrerPolicy="no-referrer" />
<span className="absolute top-3 left-3 bg-[#E50914]/85 text-white text-[10px] font-black px-2 py-0.5 rounded uppercase tracking-wider glass-badge">
{course.category}
</span>
</div>
{/* Info */}
<div className="p-5 space-y-2">
<h3 className="font-display font-bold text-base text-white tracking-tight line-clamp-1">{course.title}</h3>
<p className="text-xs text-zinc-500 leading-relaxed line-clamp-3">{course.description}</p>
</div>
</div>
{/* Actions Footer */}
<div className="p-5 border-t border-white/5 bg-white/3 flex items-center justify-between">
<button
onClick={() => handleSelectCourse(course)}
className="glass-btn-secondary text-white text-xs font-bold px-3 py-2 rounded flex items-center space-x-1 cursor-pointer"
>
<span>Grade Curricular</span>
<ChevronRight className="w-3.5 h-3.5" />
</button>
<div className="flex space-x-1.5">
<button
onClick={() => handleEditCourse(course)}
className="p-2 text-zinc-400 hover:text-white rounded bg-zinc-800/30 hover:bg-zinc-800 border border-zinc-850 transition-all"
title="Editar Curso"
>
<Edit className="w-4 h-4" />
</button>
<button
onClick={() => handleDeleteCourse(course.id)}
className="p-2 text-zinc-400 hover:text-red-400 rounded bg-zinc-800/30 hover:bg-zinc-800 border border-zinc-850 transition-all"
title="Excluir Curso"
>
<Trash2 className="w-4 h-4" />
</button>
</div>
</div>
</div>
))}
</div>
)}
</div>
);
}