import { useState, useMemo, useEffect } from 'react'; import { FiFilter, FiLayers, FiSearch, FiCode, FiShield, FiTrendingUp, FiChevronRight, FiGlobe, FiFeather, FiActivity, FiUsers, FiZap, FiBriefcase, FiMonitor, FiGrid } from 'react-icons/fi'; import type { Course } from '../../types/course'; import { CourseCard } from './CourseCard'; interface CourseGridProps { courses: Course[]; cartCourseIds: string[]; searchQuery: string; onAddToCart: (course: Course) => void; onOpenDetails: (course: Course) => void; onClearSearch: () => void; showBanners?: boolean; } export const CourseGrid: React.FC = ({ courses, cartCourseIds, searchQuery, onAddToCart, onOpenDetails, onClearSearch, }) => { const [selectedCategory, setSelectedCategory] = useState('Todos'); const [selectedSubcategory, setSelectedSubcategory] = useState('Todos'); const [selectedPopularArea, setSelectedPopularArea] = useState('Todos'); const [selectedLevel, setSelectedLevel] = useState('Todos'); const [categorySearch, setCategorySearch] = useState(''); const [sortBy, setSortBy] = useState<'rating' | 'price-asc' | 'price-desc' | 'students'>('students'); const [localSearch, setLocalSearch] = useState(''); const [showAll, setShowAll] = useState(false); // Sync local search when global searchQuery prop changes (e.g. from navbar or clear button) useEffect(() => { setLocalSearch(searchQuery); }, [searchQuery]); // Reset subcategory and level when selected category changes useEffect(() => { setSelectedSubcategory('Todos'); setSelectedLevel('Todos'); }, [selectedCategory]); // Reset popular area when category changes (avoid conflicts) useEffect(() => { if (selectedCategory !== 'Todos') { setSelectedPopularArea('Todos'); setShowAll(false); } }, [selectedCategory]); // Reset showAll when search is entered useEffect(() => { if (localSearch.trim() !== '') { setShowAll(false); } }, [localSearch]); // Helper to map and sanitize category names for flexible database mapping const getCourseCategory = (course: Course) => { const cat = course.category; if (cat === 'Desarrollo Web') return 'Informática'; if (cat === 'Diseño UI/UX') return 'Informática'; // UI/UX maps to Informática if (cat === 'Inteligencia Artificial') return 'Ciencia de datos'; if (cat === 'Ciberseguridad') return 'Tecnologías de la información'; if (cat === 'Marketing Digital') return 'Empresas'; if (cat === 'Fotografía') return 'Artes y Humanidades'; return cat; }; // Helper to map subcategory topic names dynamically const getCourseSubcategory = (course: Course) => { if (course.subcategory) return course.subcategory; // Fallback topic mappings based on keywords in title const title = course.title.toLowerCase(); const cat = course.category; if (cat === 'Desarrollo Web') { if (title.includes('react') || title.includes('next.js') || title.includes('typescript')) return 'Desarrollo Web'; if (title.includes('aws') || title.includes('cloud') || title.includes('devops') || title.includes('docker')) return 'DevOps & Cloud'; return 'Desarrollo Web'; } if (cat === 'Diseño UI/UX') { if (title.includes('ux') || title.includes('figma')) return 'Diseño UX/UI'; return 'Sistemas de diseño'; } if (cat === 'Fotografía') return 'Fotografía Digital'; if (cat === 'Inteligencia Artificial') return 'IA Generativa & LLMs'; if (cat === 'Ciberseguridad') return 'Ethical Hacking'; if (cat === 'Marketing Digital') return 'Embudos de venta'; return 'General'; }; // Compute subcategory list dynamically based on selected category const subcategories = useMemo(() => { if (selectedCategory === 'Todos') return []; const subcats = courses .filter((c) => getCourseCategory(c) === selectedCategory) .map((c) => getCourseSubcategory(c)); return ['Todos', ...Array.from(new Set(subcats))]; }, [courses, selectedCategory]); // Category information for dedicated page headers (description and metrics) const categoryDetails = useMemo(() => { if (selectedCategory === 'Todos') return null; switch (selectedCategory) { case 'Informática': return { description: 'Domina la programación web, algoritmos avanzados, TypeScript, frameworks modernos como React y Next.js, y el desarrollo estructurado de software.', credentials: 53, totalCourses: 310 }; case 'Ciencia de datos': return { description: 'Conviértete en experto en analizar grandes conjuntos de datos, modelado de Machine Learning, visualización científica e integración de Inteligencia Artificial.', credentials: 35, totalCourses: 182 }; case 'Tecnologías de la información': return { description: 'Capacítate en administración de redes, infraestructura cloud en AWS, automatización DevOps y auditorías avanzadas de ciberseguridad ofensiva.', credentials: 29, totalCourses: 150 }; case 'Empresas': return { description: 'Desarrolla habilidades comerciales estratégicas, administración ágil de proyectos (Scrum/Kanban) y embudos de marketing digital de alta conversión.', credentials: 42, totalCourses: 220 }; case 'Artes y Humanidades': return { description: 'Explora tu potencial creativo y artístico mediante cursos de fotografía digital profesional, composición visual y edición avanzada de imágenes.', credentials: 18, totalCourses: 94 }; default: return { description: 'Explora cursos líderes en esta disciplina, obtén credenciales de nivel profesional y acelera tu inserción en el mercado laboral.', credentials: 12, totalCourses: 60 }; } }, [selectedCategory]); // Filtered & Sorted courses computation const filteredCourses = useMemo(() => { return courses .filter((course) => { // Search query filter const activeSearch = localSearch.trim() || searchQuery.trim(); if (activeSearch) { const q = activeSearch.toLowerCase(); const matchTitle = course.title.toLowerCase().includes(q); const matchSub = course.subtitle.toLowerCase().includes(q); const matchCat = course.category.toLowerCase().includes(q); const matchInst = course.instructor.name.toLowerCase().includes(q); if (!matchTitle && !matchSub && !matchCat && !matchInst) return false; } // Category Page Filter (active only when selectedCategory !== 'Todos') if (selectedCategory !== 'Todos') { const cat = getCourseCategory(course); if (cat !== selectedCategory) return false; // Level Filter (inside category page level pills) if (selectedLevel !== 'Todos') { if (course.level !== selectedLevel && course.level !== 'Todos los niveles') return false; } // Subcategory filter if (selectedSubcategory !== 'Todos') { const sub = getCourseSubcategory(course); if (sub !== selectedSubcategory) return false; } } else { // Main Page Popular Area Filter (active only when selectedCategory === 'Todos') if (selectedPopularArea !== 'Todos') { const cat = getCourseCategory(course); if (cat !== selectedPopularArea) return false; } } return true; }) .sort((a, b) => { if (sortBy === 'rating') return b.rating - a.rating; if (sortBy === 'price-asc') return a.price - b.price; if (sortBy === 'price-desc') return b.price - a.price; return b.studentsCount - a.studentsCount; // default: popular }); }, [courses, searchQuery, localSearch, selectedCategory, selectedSubcategory, selectedPopularArea, selectedLevel, sortBy]); // Filtered courses for general list when selectedCategory === 'Todos' const generalCourses = useMemo(() => { return courses .filter((course) => { // Search query filter const activeSearch = localSearch.trim() || searchQuery.trim(); if (activeSearch) { const q = activeSearch.toLowerCase(); const matchTitle = course.title.toLowerCase().includes(q); const matchSub = course.subtitle.toLowerCase().includes(q); const matchCat = course.category.toLowerCase().includes(q); const matchInst = course.instructor.name.toLowerCase().includes(q); if (!matchTitle && !matchSub && !matchCat && !matchInst) return false; } // Popular area filter if (selectedPopularArea !== 'Todos') { const cat = getCourseCategory(course); if (cat !== selectedPopularArea) return false; } return true; }) .sort((a, b) => b.studentsCount - a.studentsCount); }, [courses, searchQuery, localSearch, selectedPopularArea]); const resetAllFilters = () => { setSelectedCategory('Todos'); setSelectedSubcategory('Todos'); setSelectedPopularArea('Todos'); setSelectedLevel('Todos'); setSortBy('students'); setLocalSearch(''); setShowAll(false); onClearSearch(); }; // Dynamic Icon Mapper Helper for category pills const getCategoryIcon = (catName: string) => { const name = catName.toLowerCase(); if (name.includes('informática') || name.includes('computación') || name.includes('programación') || name.includes('código')) { return ; } if (name.includes('tecnolog') || name.includes('redes') || name.includes('sistemas') || name.includes('monitor')) { return ; } if (name.includes('datos') || name.includes('inteligencia') || name.includes('ia') || name.includes('analytics') || name.includes('trending')) { return ; } if (name.includes('ingenier') || name.includes('física') || name.includes('química') || name.includes('actividad')) { return ; } if (name.includes('matemát') || name.includes('lógica') || name.includes('cálculo') || name.includes('grid')) { return ; } if (name.includes('empresa') || name.includes('negocio') || name.includes('finanzas') || name.includes('briefcase')) { return ; } if (name.includes('arte') || name.includes('humanidad') || name.includes('diseño') || name.includes('feather') || name.includes('fotografía')) { return ; } if (name.includes('idioma') || name.includes('lengua') || name.includes('globe') || name.includes('inglés')) { return ; } if (name.includes('social') || name.includes('comunidad') || name.includes('users') || name.includes('psicología')) { return ; } if (name.includes('personal') || name.includes('liderazgo') || name.includes('zap') || name.includes('crecimiento')) { return ; } if (name.includes('salud') || name.includes('shield') || name.includes('medicina') || name.includes('bienestar')) { return ; } return ; // generic fallback }; // Get all unique category names const allCategories = useMemo(() => { return Array.from(new Set(courses.map(getCourseCategory))).sort(); }, [courses]); // Filter categories by categorySearch query const filteredCategories = useMemo(() => { const query = categorySearch.trim().toLowerCase(); return allCategories.filter(cat => cat.toLowerCase().includes(query)); }, [allCategories, categorySearch]); // Popular Areas matching "Más populares" pills from Coursera screenshot const popularAreasList = [ { name: 'Empresas' }, { name: 'Ciencia de datos' }, { name: 'Tecnologías de la información' }, { name: 'Informática' }, ]; return (
{/* VIEW TYPE A: GENERAL EXPLORE PAGE */} {selectedCategory === 'Todos' ? (
{/* Section Header & Search Bar (Side-by-Side) */}
Catálogo de recursos

Explorar por categoría

Selecciona una categoría para ver los cursos y certificaciones disponibles.

{/* Search Bar compact on the right */}
setLocalSearch(e.target.value)} placeholder="Buscar cursos..." className="w-full pl-11 pr-4 py-3 bg-slate-900 border border-slate-800 rounded-2xl text-sm text-slate-200 placeholder-slate-500 focus:outline-none focus:border-cyan-500 transition-colors" />
{/* Explore Categories Directory */}
{/* Category Search Filter Input */} {allCategories.length > 5 && (
setCategorySearch(e.target.value)} placeholder="Filtrar categorías por nombre..." className="w-full pl-9 pr-4 py-2 bg-slate-900 border border-slate-800 rounded-full text-xs text-slate-200 placeholder-slate-505 focus:outline-none focus:border-cyan-500 transition-colors" />
)} {filteredCategories.length > 0 ? (
{filteredCategories.map((catName) => ( ))}
) : (

No se encontraron categorías que coincidan con "{categorySearch}".

)}
{/* 2. Áreas más populares (Sentence case, descriptive subtitle) */}

Áreas más populares

Descubre los temas de mayor demanda laboral en la actualidad.

{/* Todos Pill */} {/* Popular Area Pills */} {popularAreasList.map((area) => { const isSelected = selectedPopularArea === area.name; return ( ); })}
{/* General Courses Grid */}

Listado de cursos

Todos los cursos incluyen material de aprendizaje de alta calidad y acceso permanente.

{generalCourses.length > 0 ? (
{generalCourses.map((course) => ( ))}
) : (

No se encontraron cursos

)}
) : ( /* VIEW TYPE B: DEDICATED CATEGORY PAGE */
{/* Breadcrumbs Navigation */}
Categorías {selectedCategory}
{/* Category Page Header Block (Title, Description, and Metrics side-by-side) */}

{selectedCategory}

{categoryDetails && (

{categoryDetails.description}

)}
{/* Metrics block on the right */} {categoryDetails && (
{categoryDetails.credentials}
credenciales
cursos
de {categoryDetails.totalCourses}
)}
{/* Subcategories - visible only when category has multiple topics */} {subcategories.length > 2 && (
Temas de {selectedCategory}
{subcategories.map((sub) => { const isSubSelected = selectedSubcategory === sub; return ( ); })}
)} {/* "Filtrar por nivel" (Sentence case, descriptive subtitle, capsules format) */}

Filtrar por nivel

Selecciona la dificultad adecuada para tu ritmo de aprendizaje.

{['Todos', 'Principiante', 'Intermedio', 'Avanzado'].map((lvl) => { const isLvlSelected = selectedLevel === lvl; return ( ); })}
{/* Section: Listado de cursos (Descriptive title & subtitle) */}

Listado de cursos de {selectedCategory}

Encuentra el material didáctico necesario para avanzar en tu formación profesional.

{filteredCourses.length > 0 ? (
{filteredCourses.map((course) => ( ))}
) : (

No se encontraron cursos en este nivel

)}
)}
); };