UNPKG

react-vite-themes

Version:

A test/experimental React theme system created for learning purposes. Features atomic design components, SCSS variables, and dark/light theme support. Not intended for production use.

91 lines (90 loc) 13.4 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useMemo } from 'react'; import { Badge } from "../../../components/atoms/Badge"; import { Button } from "../../../components/atoms/Button"; import { Card } from "../../../components/atoms/Card"; import { Icon } from "../../../components/atoms/Icon"; import { ProgressBar } from "../../../components/atoms/ProgressBar"; import { StatCard } from "../../../components/molecules/StatCard"; import { Image } from "../../../components/atoms/Image"; import { Input } from "../../../components/atoms/Input"; import { Select } from "../../../components/atoms/Select"; import { Tabs } from "../../../components/molecules/Tabs"; import { Alert } from "../../../components/atoms/Alert"; import modulesData from '../seeds/extended-modules-data.json'; const categories = modulesData.categories; const difficultyLevels = modulesData.difficultyLevels; // ModuleCard component defined outside to avoid temporal dead zone const ModuleCard = ({ module, viewMode }) => { const getProgressColor = (progress) => { if (progress === 100) return 'success'; if (progress > 50) return 'warning'; return 'primary'; }; const getDifficultyColor = (difficulty) => { switch (difficulty) { case 'beginner': return 'success'; case 'intermediate': return 'warning'; case 'advanced': return 'error'; default: return 'primary'; } }; const getCategoryIcon = (categoryId) => { const category = categories.find(cat => cat.id === categoryId); return category?.icon || 'book'; }; return (_jsxs(Card, { variant: "neutral", style: "elevated", padding: "lg", className: `transition-all duration-300 hover:shadow-light-xl cursor-pointer ${viewMode === 'list' ? 'd-flex flex-row' : ''}`, image: viewMode === 'grid' ? { src: module.image.src, alt: module.image.alt, height: "200px" } : undefined, children: [viewMode === 'list' && (_jsx("div", { className: "w-32 h-24 mr-4 flex-shrink-0", children: _jsx(Image, { src: module.image.src, alt: module.image.alt, style: "natural", size: "md", className: "w-full h-full object-cover rounded-md" }) })), _jsxs("div", { className: `d-flex flex-column ${viewMode === 'list' ? 'flex-1' : 'h-100'}`, children: [_jsxs("div", { className: "d-flex justify-between align-start mb-3", children: [_jsxs("div", { className: "d-flex align-center gap-2", children: [_jsx(Icon, { name: getCategoryIcon(module.category), size: "sm", className: "text-primary-500" }), _jsx(Badge, { variant: "neutral", size: "sm", children: categories.find(cat => cat.id === module.category)?.name || module.category })] }), _jsxs("div", { className: "d-flex gap-2", children: [_jsx(Badge, { variant: getDifficultyColor(module.difficulty), size: "sm", children: module.difficulty }), module.progress > 0 && (_jsxs(Badge, { variant: getProgressColor(module.progress), size: "sm", children: [module.progress, "%"] }))] })] }), _jsx("h3", { className: "text-lg font-bold mb-2", children: module.title }), _jsx("p", { className: "text-secondary mb-4 flex-1 text-sm", children: module.description }), module.progress > 0 && (_jsx("div", { className: "mb-4", children: _jsx(ProgressBar, { value: module.progress, variant: getProgressColor(module.progress), size: "sm", showLabel: true, labelPosition: "top", isAnimated: true }) })), _jsx("div", { className: "d-flex justify-between align-center mb-3", children: _jsxs("div", { className: "d-flex gap-4 text-xs text-neutral-600", children: [_jsxs("span", { className: "d-flex align-center gap-1", children: [_jsx(Icon, { name: "lessons", size: "sm" }), module.lessons, " lecciones"] }), _jsxs("span", { className: "d-flex align-center gap-1", children: [_jsx(Icon, { name: "clock", size: "sm" }), module.duration] }), _jsxs("span", { className: "d-flex align-center gap-1", children: [_jsx(Icon, { name: "users", size: "sm" }), module.students, " estudiantes"] })] }) }), _jsx(Button, { variant: module.progress === 100 ? "success" : module.progress > 0 ? "secondary" : "primary", size: "sm", rightIcon: module.progress === 100 ? "check-circle" : "play-circle", className: "w-full", children: module.progress === 100 ? "Completado" : module.progress > 0 ? "Continuar" : "Comenzar" })] })] }, module.id)); }; const ModulesPage = () => { const [searchTerm, setSearchTerm] = useState(''); const [selectedCategory, setSelectedCategory] = useState('all'); const [selectedDifficulty, setSelectedDifficulty] = useState('all'); const [viewMode, setViewMode] = useState('grid'); const [activeTab, setActiveTab] = useState('all'); const filteredModules = useMemo(() => { return modulesData.allModules.filter((module) => { const matchesSearch = module.title.toLowerCase().includes(searchTerm.toLowerCase()) || module.description.toLowerCase().includes(searchTerm.toLowerCase()); const matchesCategory = selectedCategory === 'all' || module.category === selectedCategory; const matchesDifficulty = selectedDifficulty === 'all' || module.difficulty === selectedDifficulty; return matchesSearch && matchesCategory && matchesDifficulty; }); }, [searchTerm, selectedCategory, selectedDifficulty]); const featuredModules = filteredModules.slice(0, 3); const recentModules = filteredModules.filter(module => new Date(module.lastUpdated) > new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)).slice(0, 6); const tabs = [ { id: 'all', label: 'Todos los Módulos', icon: 'grid', content: (_jsx("div", { className: "d-grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: filteredModules.map((module) => (_jsx(ModuleCard, { module: module, viewMode: viewMode }, module.id))) })) }, { id: 'featured', label: 'Destacados', icon: 'star', content: (_jsx("div", { className: "d-grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: featuredModules.map((module) => (_jsx(ModuleCard, { module: module, viewMode: viewMode }, module.id))) })) }, { id: 'recent', label: 'Recientes', icon: 'clock', content: (_jsx("div", { className: "d-grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: recentModules.map((module) => (_jsx(ModuleCard, { module: module, viewMode: viewMode }, module.id))) })) } ]; return (_jsxs("div", { className: "modules-page", children: [_jsxs("section", { className: "bg-gradient-rainbow-burst text-white py-12 relative overflow-hidden", children: [_jsxs("div", { className: "absolute inset-0 opacity-10", children: [_jsx("div", { className: "absolute top-0 left-0 w-64 h-64 bg-white rounded-full -translate-x-1/2 -translate-y-1/2" }), _jsx("div", { className: "absolute bottom-0 right-0 w-96 h-96 bg-white rounded-full translate-x-1/2 translate-y-1/2" })] }), _jsx("div", { className: "container relative z-10", children: _jsxs("div", { className: "text-center mb-8", children: [_jsx("h1", { className: "font-bold mb-4 text-4xl md:text-5xl", children: "Explora Nuestros M\u00F3dulos" }), _jsx("p", { className: "text-xl mb-8 w-75 mx-auto opacity-95", children: "M\u00E1s de 50 lecciones dise\u00F1adas espec\u00EDficamente para migrantes latinos en Alemania" }), _jsx("div", { className: "w-75 mx-auto mb-8", children: _jsx(Input, { placeholder: "Buscar m\u00F3dulos por t\u00EDtulo, descripci\u00F3n o categor\u00EDa...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), leftIcon: _jsx(Icon, { name: "search", size: "md" }), size: "lg", isRounded: true, className: "shadow-light-lg" }) }), _jsxs("div", { className: "d-flex flex-wrap justify-center gap-4", children: [_jsx(StatCard, { value: modulesData.statistics.totalModules.toString(), subtitle: "M\u00F3dulos Disponibles", style: "glass", isHoverable: true, size: "sm" }), _jsx(StatCard, { value: modulesData.statistics.totalLessons.toString(), subtitle: "Lecciones Totales", style: "glass", isHoverable: true, size: "sm" }), _jsx(StatCard, { value: modulesData.statistics.totalCategories.toString(), subtitle: "Categor\u00EDas", style: "glass", isHoverable: true, size: "sm" }), _jsx(StatCard, { value: `${modulesData.statistics.completionRate}%`, subtitle: "Tasa de Completado", style: "glass", isHoverable: true, size: "sm" })] })] }) })] }), _jsxs("section", { className: "container-xl py-8", children: [_jsx(Alert, { variant: "info", title: "\uD83D\uDCCA Estad\u00EDsticas R\u00E1pidas", className: "mb-6", children: _jsxs("div", { className: "d-flex justify-between align-center", children: [_jsxs("span", { children: ["Mostrando ", filteredModules.length, " de ", modulesData.statistics.totalModules, " m\u00F3dulos"] }), _jsxs("div", { className: "d-flex gap-2", children: [_jsx(Button, { variant: viewMode === 'grid' ? "primary" : "secondary", size: "sm", centerIcon: "grid", onClick: () => setViewMode('grid') }), _jsx(Button, { variant: viewMode === 'list' ? "primary" : "secondary", size: "sm", centerIcon: "list", onClick: () => setViewMode('list') })] })] }) }), _jsx(Card, { variant: "neutral", style: "elevated", className: "mb-8", children: _jsxs("div", { className: "p-6", children: [_jsx("h3", { className: "text-lg font-semibold mb-4", children: "Filtros y Categor\u00EDas" }), _jsxs("div", { className: "mb-6", children: [_jsx("h4", { className: "text-sm font-medium mb-3 text-neutral-600", children: "Categor\u00EDas" }), _jsxs("div", { className: "d-flex flex-wrap gap-2", children: [_jsx(Button, { variant: selectedCategory === 'all' ? "primary" : "secondary", size: "sm", onClick: () => setSelectedCategory('all'), className: "shadow-light-sm", children: "Todas" }), categories.map((category) => (_jsx(Button, { variant: selectedCategory === category.id ? "primary" : "secondary", size: "sm", leftIcon: _jsx(Icon, { name: category.icon, size: "sm" }), onClick: () => setSelectedCategory(category.id), className: "shadow-light-sm", children: category.name }, category.id)))] })] }), _jsx("div", { className: "d-flex align-center gap-4", children: _jsxs("div", { className: "flex-1", children: [_jsx("h4", { className: "text-sm font-medium mb-3 text-neutral-600", children: "Nivel de Dificultad" }), _jsx(Select, { options: difficultyLevels.map((level) => ({ value: level.id, label: level.name })), value: selectedDifficulty, onChange: setSelectedDifficulty, placeholder: "Seleccionar nivel", size: "md", variant: "secondary" })] }) })] }) }), _jsx(Tabs, { tabs: tabs, variant: "underline", size: "md", defaultActiveTab: "all", onTabChange: setActiveTab, className: "mb-8" }), _jsxs("div", { className: "mb-8", children: [activeTab === 'all' && (_jsx("div", { className: "d-grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: filteredModules.map((module) => (_jsx(ModuleCard, { module: module, viewMode: viewMode }, module.id))) })), activeTab === 'featured' && (_jsx("div", { className: "d-grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: featuredModules.map((module) => (_jsx(ModuleCard, { module: module, viewMode: viewMode }, module.id))) })), activeTab === 'recent' && (_jsx("div", { className: "d-grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6", children: recentModules.map((module) => (_jsx(ModuleCard, { module: module, viewMode: viewMode }, module.id))) }))] }), filteredModules.length === 0 && (_jsxs(Card, { variant: "neutral", style: "elevated", className: "text-center py-12", children: [_jsx(Icon, { name: "search", size: "xl", className: "text-neutral-400 mb-4" }), _jsx("h3", { className: "text-xl font-semibold mb-2", children: "No se encontraron m\u00F3dulos" }), _jsx("p", { className: "text-neutral-600 mb-6", children: "Intenta ajustar tus filtros de b\u00FAsqueda o explorar otras categor\u00EDas" }), _jsx(Button, { variant: "primary", onClick: () => { setSearchTerm(''); setSelectedCategory('all'); setSelectedDifficulty('all'); }, children: "Limpiar Filtros" })] })), _jsx(Card, { variant: "primary", style: "elevated", className: "text-center py-12 bg-gradient-sunset", children: _jsxs("div", { className: "w-75 mx-auto", children: [_jsx("h2", { className: "text-2xl font-bold mb-4 text-white", children: "\u00BFNo encuentras lo que buscas?" }), _jsx("p", { className: "text-white opacity-90 mb-6", children: "Estamos constantemente agregando nuevos m\u00F3dulos. Suscr\u00EDbete para recibir notificaciones sobre nuevos contenidos y actualizaciones." }), _jsxs("div", { className: "d-flex justify-center gap-4", children: [_jsx(Button, { variant: "light", size: "lg", leftIcon: _jsx(Icon, { name: "bell", size: "md" }), className: "shadow-light-lg", children: "Suscribirse" }), _jsx(Button, { variant: "light", size: "lg", leftIcon: _jsx(Icon, { name: "message", size: "md" }), className: "shadow-light-lg", children: "Contactar" })] })] }) })] })] })); }; export default ModulesPage;