import React, { useState, useEffect, useMemo, useRef } from 'react'; import { Folder, FileSpreadsheet, FileText, FileArchive, FileCode, Link as LinkIcon, Search, Download, ChevronRight, ArrowLeft, Sparkles, Copy, BookOpen, Undo2, Eye, LayoutGrid, List, HardDrive, X, Play } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { Course, Attachment, AttachmentType } from '../types'; import { getCourses } from '../services/db'; import { useToast } from '../context/ToastContext'; interface MaterialsPageProps { onPlayCourse: (course: Course) => void; } interface MaterialFileItem { id: string; name: string; type: string; formatType: AttachmentType; size: string; modified: string; course: Course; lessonTitle?: string; description?: string; url: string; } export const MaterialsPage: React.FC = ({ onPlayCourse }) => { const [courses, setCourses] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); // Navigation & View Mode State const [activeFolder, setActiveFolder] = useState('downloads'); const [viewMode, setViewMode] = useState<'list' | 'grid'>('grid'); const [selectedItem, setSelectedItem] = useState(null); const [previewItem, setPreviewItem] = useState(null); // Filter Chip State (All, XLSX, PDF, ZIP, DOC) const [typeFilter, setTypeFilter] = useState('all'); // Table Sort State const [sortBy, setSortBy] = useState<'name' | 'type' | 'size' | 'modified'>('name'); const [sortAsc, setSortAsc] = useState(true); // Context Menu State const [contextMenu, setContextMenu] = useState<{ visible: boolean; x: number; y: number; item: MaterialFileItem | null; }>({ visible: false, x: 0, y: 0, item: null }); const [downloadingId, setDownloadingId] = useState(null); const navigate = useNavigate(); const { showToast, showDownloadToast } = useToast(); const contextMenuRef = useRef(null); useEffect(() => { window.scrollTo(0, 0); getCourses().then(data => { setCourses(data); setLoading(false); }); const handleClickOutside = (e: MouseEvent) => { if (contextMenuRef.current && !contextMenuRef.current.contains(e.target as Node)) { setContextMenu(prev => ({ ...prev, visible: false })); } }; window.addEventListener('click', handleClickOutside); return () => window.removeEventListener('click', handleClickOutside); }, []); // Format type helper const getFileExtension = (att: Attachment) => { if (att.type === 'spreadsheet') return 'XLSX'; if (att.type === 'pdf') return 'PDF'; if (att.type === 'zip') return 'ZIP'; if (att.type === 'doc') return 'DOC'; if (att.type === 'link') return 'JSON'; return 'TXT'; }; // Compile file list const allFiles: MaterialFileItem[] = useMemo(() => { const list: MaterialFileItem[] = []; courses.forEach((course, cIdx) => { if (course.attachments && course.attachments.length > 0) { course.attachments.forEach((att, aIdx) => { const fileId = `f-c-${course.id}-${att.id || aIdx}`; list.push({ id: fileId, name: att.name, type: getFileExtension(att), formatType: att.type, size: att.size || `${(aIdx + 1) * 14 + 120} KB`, modified: `2026. 08. 1${(aIdx % 8) + 1}`, course, description: att.description, url: att.url || '#' }); }); } if (course.lessons) { course.lessons.forEach((lesson, lIdx) => { if (lesson.attachments && lesson.attachments.length > 0) { lesson.attachments.forEach((att, laIdx) => { const fileId = `f-l-${course.id}-${lesson.id}-${att.id || laIdx}`; list.push({ id: fileId, name: att.name, type: getFileExtension(att), formatType: att.type, size: att.size || `${(lIdx + 2) * 22 + 210} KB`, modified: `2026. 08. 1${(lIdx % 9) + 1}`, course, lessonTitle: lesson.title, description: att.description, url: att.url || '#' }); }); } }); } }); return list; }, [courses]); // Set default selected item if none selected useEffect(() => { if (allFiles.length > 0 && !selectedItem) { setSelectedItem(allFiles[0]); } }, [allFiles, selectedItem]); const categories = useMemo(() => { return Array.from(new Set(courses.map(c => c.category))); }, [courses]); // Filtered and Sorted Files const displayedFiles = useMemo(() => { return allFiles.filter(file => { // Type Chip filter if (typeFilter !== 'all') { if (typeFilter === 'xlsx' && file.type !== 'XLSX') return false; if (typeFilter === 'pdf' && file.type !== 'PDF') return false; if (typeFilter === 'zip' && file.type !== 'ZIP') return false; if (typeFilter === 'doc' && file.type !== 'DOC' && file.type !== 'TXT') return false; } // Search Query if (searchTerm.trim()) { const query = searchTerm.toLowerCase(); const matchesName = file.name.toLowerCase().includes(query); const matchesType = file.type.toLowerCase().includes(query); const matchesCourse = file.course.title.toLowerCase().includes(query); const matchesDesc = file.description?.toLowerCase().includes(query); if (!matchesName && !matchesType && !matchesCourse && !matchesDesc) { return false; } } // Folder navigation filter if (activeFolder === 'downloads' || activeFolder === 'my-files' || activeFolder === 'recent') { return true; } if (activeFolder === 'zip') { return file.type === 'ZIP'; } if (activeFolder === 'pdf') { return file.type === 'PDF'; } if (activeFolder === 'xlsx') { return file.type === 'XLSX'; } if (categories.includes(activeFolder)) { return file.course.category === activeFolder; } return true; }).sort((a, b) => { let cmp = 0; if (sortBy === 'name') cmp = a.name.localeCompare(b.name); if (sortBy === 'type') cmp = a.type.localeCompare(b.type); if (sortBy === 'size') cmp = a.size.localeCompare(b.size); if (sortBy === 'modified') cmp = a.modified.localeCompare(b.modified); return sortAsc ? cmp : -cmp; }); }, [allFiles, searchTerm, activeFolder, typeFilter, sortBy, sortAsc, categories]); const handleSort = (column: 'name' | 'type' | 'size' | 'modified') => { if (sortBy === column) { setSortAsc(!sortAsc); } else { setSortBy(column); setSortAsc(true); } }; const handleDownload = (item: MaterialFileItem) => { setDownloadingId(item.id); setContextMenu(prev => ({ ...prev, visible: false })); setTimeout(() => { setDownloadingId(null); showDownloadToast(item.name, item.size); const link = document.createElement('a'); link.href = item.url; link.download = item.name; link.target = '_blank'; link.rel = 'noreferrer'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }, 400); }; const handleContextMenu = (e: React.MouseEvent, item: MaterialFileItem) => { e.preventDefault(); e.stopPropagation(); setSelectedItem(item); setContextMenu({ visible: true, x: Math.min(e.clientX, window.innerWidth - 240), y: Math.min(e.clientY, window.innerHeight - 280), item }); }; // Color Coded File Icon Component with Dark Theme Styling const renderFileIcon = (type: string, sizeClass: string = "w-5 h-5") => { switch (type.toUpperCase()) { case 'XLSX': case 'SPREADSHEET': return ; case 'PDF': return ; case 'ZIP': case 'RAR': return ; case 'DOC': case 'MD': case 'TXT': return ; default: return ; } }; return (
{/* Ambient background glow matching Home */}
{/* Breadcrumb + Header Hero */}
{/* Breadcrumb */}
/ Central de Recursos
{/* Title */}

Biblioteca de Materiais

Explore e faça o download de todas as planilhas de ROI, modelos de criativos, relatórios e arquivos complementares das aulas em um ambiente integrado.

{/* Quick Search & Switcher Controls */}
{/* Search Input */}
setSearchTerm(e.target.value)} placeholder="Pesquisar material, planilha ou aula..." className="w-full bg-zinc-900/90 rounded-[980px] pl-11 pr-10 py-2.5 text-sm text-white placeholder:text-gray-400 font-normal focus:outline-none focus:ring-2 focus:ring-orange-500/30 transition-all" /> {searchTerm && ( )}
{/* View Switcher: Grid vs List */}
{/* Main Content Explorer Area */}
{/* Left Sidebar: Drive Structure */} {/* Main Files Area */}
{/* Explorer Header */}

{activeFolder === 'downloads' ? (typeFilter !== 'all' ? `Filtro: ${typeFilter.toUpperCase()}` : 'Todos os Materiais') : activeFolder}

{displayedFiles.length} {displayedFiles.length === 1 ? 'item' : 'itens'}
{/* Action Buttons */}
{(searchTerm || typeFilter !== 'all' || activeFolder !== 'downloads') && ( )}
{/* Files Content: Grid or List */}
{/* EMPTY STATE */} {displayedFiles.length === 0 ? (

Nenhum material encontrado

Não encontramos arquivos correspondentes aos filtros selecionados. Tente ajustar o termo de pesquisa ou limpar os filtros.

) : viewMode === 'grid' ? ( /* GRID VIEW */
{/* Category Fast-Folders (When in All or Category View) */} {activeFolder === 'downloads' && typeFilter === 'all' && !searchTerm && (

Pastas por Módulo

{categories.map(cat => { const count = allFiles.filter(f => f.course.category === cat).length; return (
setActiveFolder(cat)} className="bg-zinc-900/60 hover:bg-zinc-900 rounded-xl p-4 cursor-pointer hover:shadow-xl transition-all flex items-center justify-between group" >

{cat}

{count} arquivos

); })}
)} {/* Material Cards Grid */}

Arquivos para Download

{displayedFiles.map(file => { const isSelected = selectedItem?.id === file.id; const isDownloading = downloadingId === file.id; return (
setSelectedItem(file)} onContextMenu={(e) => handleContextMenu(e, file)} className={`bg-zinc-900/60 hover:bg-zinc-900 rounded-xl overflow-hidden cursor-pointer transition-all hover:shadow-2xl flex flex-col justify-between group ${ isSelected ? 'ring-2 ring-orange-500 bg-zinc-900' : '' }`} > {/* Card Header with Icon */}
{renderFileIcon(file.type, "w-6 h-6")}
{file.type} {file.size}
{/* Card Body */}

{file.name}

{file.course.title}

{file.lessonTitle && (

Aula: {file.lessonTitle}

)}
{/* Card Footer Actions */}
); })}
) : ( /* LIST VIEW (TABLE) */ {displayedFiles.map((file) => { const isSelected = selectedItem?.id === file.id; return ( setSelectedItem(file)} onContextMenu={(e) => handleContextMenu(e, file)} className={`group transition-all cursor-pointer select-none ${ isSelected ? 'bg-orange-500/10' : 'hover:bg-white/[0.03]' }`} > {/* Name column */} {/* Course / Owner */} {/* Actions */} ); })}
handleSort('name')} className="py-4 px-6 cursor-pointer hover:text-white transition-colors" >
Nome do Arquivo {sortBy === 'name' && ( {sortAsc ? '↑' : '↓'} )}
Curso / Trilha Ações
{renderFileIcon(file.type, "w-6 h-6")}
{file.name}
{file.lessonTitle && (

Aula: {file.lessonTitle}

)}
{file.course.title}
)}
{/* Table Footer */}
{displayedFiles.length} item(s) listados Dica: Clique com o botão direito para o menu de ações rápido
{/* QUICK PREVIEW MODAL */} {previewItem && (
{renderFileIcon(previewItem.type)}

{previewItem.name}

{previewItem.size} • {previewItem.type}

Trilha: {previewItem.course.title}
{previewItem.lessonTitle && (
Aula: {previewItem.lessonTitle}
)}
Instrutor: {previewItem.course.instructor.name}
{previewItem.description && (
{previewItem.description}
)}
)} {/* Context Menu Popup */} {contextMenu.visible && contextMenu.item && (
)}
); };