📂 FileMgr
📍
/
home
/
hugpbeavxq
/
colegioelvalle.edu.gt
/
old
✏️ /index.html
⬅ Kembali
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Colegio El Valle | E-Learning Guatemala</title> <!-- React & ReactDOM --> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <!-- Babel for JSX --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <!-- Tailwind CSS --> <script src="https://cdn.tailwindcss.com"></script> <!-- Google Fonts: Inter --> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <!-- Configuración de Tailwind para colores personalizados --> <script> tailwind.config = { theme: { extend: { fontFamily: { sans: ['Inter', 'sans-serif'], }, colors: { 'valle-green': '#10B981', // Esmeralda vibrante 'valle-dark': '#064E3B', // Verde bosque profundo 'cielo-blue': '#3B82F6', // Azul cielo 'guate-white': '#F9FAFB', // Blanco nube } } } } </script> <style> body { background-color: #F3F4F6; } /* Animaciones suaves */ .fade-in { animation: fadeIn 0.5s ease-in; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } </style> </head> <body> <div id="root"></div> <script type="text/babel"> const { useState, useEffect } = React; // --- COMPONENTES DE ICONOS --- const IconBook = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>; const IconMenu = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>; const IconX = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>; const IconMapPin = () => <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>; const IconPhone = () => <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>; const IconMail = () => <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>; const IconGradCap = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 10v6M2 10l10-5 10 5-10 5z"/><path d="M6 12v5c3 3 9 3 12 0v-5"/></svg>; const IconLaptop = () => <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>; const IconCheck = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>; const IconEdit = () => <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>; const IconTrash = () => <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>; const IconPlus = () => <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>; // --- DATOS INICIALES (Actualizados con nuevos campos) --- const INITIAL_COURSES = [ { id: 1, title: "Matemáticas Divertidas", level: "Primaria", price: 150, image: "https://images.unsplash.com/photo-1596495578065-6e0763fa1178?auto=format&fit=crop&q=80&w=600", instructor: "Lic. Ana Gómez", description: "Aprende aritmética básica con juegos y diversión.", link: "" }, { id: 2, title: "Ciencias Naturales", level: "Primaria", price: 150, image: "https://images.unsplash.com/photo-1532094349884-543bc11b234d?auto=format&fit=crop&q=80&w=600", instructor: "Prof. Carlos Ruiz", description: "Explora la flora y fauna de Guatemala.", link: "" }, { id: 3, title: "Programación Básica (Python)", level: "Secundaria", price: 250, image: "https://images.unsplash.com/photo-1515879218367-8466d910aaa4?auto=format&fit=crop&q=80&w=600", instructor: "Ing. Sofía Méndez", description: "Iníciate en el mundo del código desde cero.", link: "" }, { id: 4, title: "Historia de Guatemala", level: "Secundaria", price: 200, image: "https://images.unsplash.com/photo-1596307374092-23c3167b4585?auto=format&fit=crop&q=80&w=600", instructor: "Lic. Pedro Tzoc", description: "Conoce nuestras raíces mayas y coloniales.", link: "" }, { id: 5, title: "Diseño Gráfico Digital", level: "Vocacional", price: 350, image: "https://images.unsplash.com/photo-1626785774573-4b799314346d?auto=format&fit=crop&q=80&w=600", instructor: "D.G. María Castillo", description: "Domina herramientas como Photoshop e Illustrator.", link: "" }, { id: 6, title: "Inglés para Negocios", level: "Profesional", price: 400, image: "https://images.unsplash.com/photo-1557804506-669a67965ba0?auto=format&fit=crop&q=80&w=600", instructor: "Teacher John Smith", description: "Mejora tu perfil profesional con inglés técnico.", link: "" }, { id: 7, title: "Introducción al E-Learning", level: "Gratis", price: 0, image: "https://images.unsplash.com/photo-1501504905252-473c47e087f8?auto=format&fit=crop&q=80&w=600", instructor: "Equipo El Valle", description: "Aprende a usar nuestra plataforma virtual.", link: "" }, ]; const POSTS = [ { id: 1, title: "5 Ventajas de estudiar online en Guatemala", date: "Oct 2023", excerpt: "Descubre cómo el e-learning está transformando la educación rural y urbana en nuestro país." }, { id: 2, title: "Tips para concentrarte en casa", date: "Sep 2023", excerpt: "Crear un espacio de estudio adecuado es clave para el éxito académico virtual." }, { id: 3, title: "El futuro de la tecnología educativa", date: "Ago 2023", excerpt: "Analizamos las nuevas herramientas que implementaremos en el ciclo 2024." }, ]; // --- COMPONENTES --- const NavButton = ({ label, active, onClick, isMobile = false }) => ( <button onClick={onClick} className={`${isMobile ? 'block w-full text-left px-4 py-3' : 'px-4 py-2 rounded-lg transition-colors'} ${active ? 'bg-valle-green text-white font-semibold shadow-md' : 'text-gray-600 hover:text-valle-dark hover:bg-green-50'}`} > {label} </button> ); const Header = ({ setPage, currentPage }) => { const [isMenuOpen, setIsMenuOpen] = useState(false); const handleNav = (page) => { setPage(page); setIsMenuOpen(false); }; return ( <header className="bg-white shadow-sm sticky top-0 z-50"> <div className="container mx-auto px-4 sm:px-6 lg:px-8"> <div className="flex justify-between items-center h-20"> {/* Logo */} <div className="flex items-center cursor-pointer" onClick={() => handleNav('home')}> <div className="text-valle-green mr-2"> <IconBook /> </div> <div className="flex flex-col"> <span className="font-bold text-xl text-gray-800 leading-tight">Colegio El Valle</span> <span className="text-xs text-valle-dark uppercase tracking-wide">E-Learning Guatemala</span> </div> </div> {/* Desktop Nav */} <nav className="hidden md:flex space-x-2"> <NavButton label="Inicio" active={currentPage === 'home'} onClick={() => handleNav('home')} /> <NavButton label="Nosotros" active={currentPage === 'about'} onClick={() => handleNav('about')} /> <a href="cursos.html" className="px-4 py-2 rounded-lg transition-colors text-gray-600 hover:text-valle-dark hover:bg-green-50" > Cursos </a> <NavButton label="Plataforma" active={currentPage === 'platform'} onClick={() => handleNav('platform')} /> <NavButton label="Blog" active={currentPage === 'blog'} onClick={() => handleNav('blog')} /> <NavButton label="Contacto" active={currentPage === 'contact'} onClick={() => handleNav('contact')} /> <button onClick={() => handleNav('enroll')} className="ml-4 bg-cielo-blue text-white px-5 py-2 rounded-full font-bold hover:bg-blue-600 transition-all shadow-lg transform hover:-translate-y-0.5" > Inscribirse </button> </nav> {/* Mobile Menu Button */} <div className="md:hidden"> <button onClick={() => setIsMenuOpen(!isMenuOpen)} className="text-gray-600 p-2"> {isMenuOpen ? <IconX /> : <IconMenu />} </button> </div> </div> </div> {/* Mobile Nav */} {isMenuOpen && ( <div className="md:hidden bg-white border-t border-gray-100 absolute w-full shadow-lg"> <NavButton isMobile label="Inicio" active={currentPage === 'home'} onClick={() => handleNav('home')} /> <NavButton isMobile label="Nosotros" active={currentPage === 'about'} onClick={() => handleNav('about')} /> <a href="cursos.html" className="block w-full text-left px-4 py-3 text-gray-600 hover:text-valle-dark hover:bg-green-50" > Cursos </a> <NavButton isMobile label="Plataforma" active={currentPage === 'platform'} onClick={() => handleNav('platform')} /> <NavButton isMobile label="Blog" active={currentPage === 'blog'} onClick={() => handleNav('blog')} /> <NavButton isMobile label="Contacto" active={currentPage === 'contact'} onClick={() => handleNav('contact')} /> <div className="p-4"> <button onClick={() => handleNav('enroll')} className="w-full bg-cielo-blue text-white py-3 rounded-lg font-bold" > Inscribirse Ahora </button> </div> </div> )} </header> ); }; const Hero = ({ setPage }) => ( <div className="relative bg-valle-dark overflow-hidden"> <div className="absolute inset-0"> <img src="https://images.unsplash.com/photo-1497633762265-9d179a990aa6?auto=format&fit=crop&q=80&w=1920" alt="Estudiante en Guatemala" className="w-full h-full object-cover opacity-30" /> </div> <div className="relative container mx-auto px-4 py-24 sm:py-32 flex flex-col items-center text-center"> <span className="bg-valle-green/20 text-valle-green text-sm font-bold px-4 py-1 rounded-full mb-6 border border-valle-green/30"> 🎓 Educación 100% Online en Guatemala </span> <h1 className="text-4xl sm:text-6xl font-extrabold text-white mb-6 leading-tight"> Aprende desde <span className="text-valle-green">cualquier rincón</span> del país </h1> <p className="text-lg text-gray-300 max-w-2xl mb-10"> Educación de calidad, accesible e innovadora para primaria, secundaria y formación profesional. Tu futuro comienza aquí, en Colegio El Valle. </p> <div className="flex flex-col sm:flex-row gap-4"> <a href="cursos.html" className="bg-valle-green text-white px-8 py-4 rounded-lg font-bold text-lg hover:bg-green-500 transition-colors shadow-lg inline-block" > Ver Cursos Disponibles </a> <button onClick={() => setPage('about')} className="bg-white/10 backdrop-blur-md text-white border border-white/30 px-8 py-4 rounded-lg font-bold text-lg hover:bg-white/20 transition-colors"> Conócenos Más </button> </div> </div> </div> ); const About = () => ( <div className="fade-in py-16 bg-white"> <div className="container mx-auto px-4"> <div className="max-w-4xl mx-auto"> <div className="text-center mb-16"> <h2 className="text-3xl font-bold text-gray-800 mb-4">Sobre Colegio El Valle</h2> <div className="h-1 w-20 bg-valle-green mx-auto"></div> </div> <div className="grid md:grid-cols-2 gap-12 items-center mb-16"> <div> <img src="https://images.unsplash.com/photo-1522202176988-66273c2fd55f?auto=format&fit=crop&q=80&w=800" alt="Estudiantes online" className="rounded-2xl shadow-xl" /> </div> <div className="space-y-6"> <p className="text-gray-600 leading-relaxed"> Fundado con la visión de romper las barreras geográficas en Guatemala, <strong>Colegio El Valle</strong> nació como una respuesta a la necesidad de educación accesible y de alta calidad. </p> <p className="text-gray-600 leading-relaxed"> Utilizamos tecnología de punta para conectar a los mejores maestros con estudiantes desde Petén hasta Escuintla, garantizando que el talento chapín tenga las herramientas para brillar globalmente. </p> <ul className="space-y-3"> <li className="flex items-center text-gray-700"> <span className="text-valle-green mr-2"><IconCheck /></span> Misión: Democratizar la educación digital. </li> <li className="flex items-center text-gray-700"> <span className="text-valle-green mr-2"><IconCheck /></span> Visión: Ser líderes regionales en E-learning. </li> <li className="flex items-center text-gray-700"> <span className="text-valle-green mr-2"><IconCheck /></span> Valores: Inclusión, Innovación y Excelencia. </li> </ul> </div> </div> </div> </div> </div> ); const CourseCard = ({ course, onEnroll }) => ( <div className="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-xl transition-shadow border border-gray-100 flex flex-col h-full"> <div className="h-48 overflow-hidden relative"> <img src={course.image} alt={course.title} className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500" /> <div className="absolute top-3 right-3 bg-white/90 backdrop-blur text-xs font-bold px-2 py-1 rounded text-gray-700 uppercase"> {course.level} </div> </div> <div className="p-6 flex-grow flex flex-col"> <h3 className="text-xl font-bold text-gray-800 mb-1">{course.title}</h3> <p className="text-xs text-gray-500 mb-2 uppercase tracking-wide">{course.instructor}</p> <p className="text-sm text-gray-600 mb-4 line-clamp-2 flex-grow">{course.description || "Un curso excelente para mejorar tus habilidades y conocimientos."}</p> <div className="mt-auto flex justify-between items-center pt-4 border-t border-gray-100"> <span className="text-2xl font-bold text-valle-green"> {course.price === 0 ? 'Gratis' : `Q${course.price}`} </span> <a href={course.link ? course.link : "#"} onClick={(e) => { if(!course.link) { e.preventDefault(); onEnroll(course.title); } }} className="bg-cielo-blue text-white px-4 py-2 rounded-lg text-sm font-semibold hover:bg-blue-600 transition-colors" > Inscribirse </a> </div> </div> </div> ); const Courses = ({ courses, setPage, setPreselectedCourse }) => { const [filter, setFilter] = useState('Todos'); const categories = ['Todos', 'Primaria', 'Secundaria', 'Vocacional', 'Profesional', 'Gratis']; const filteredCourses = filter === 'Todos' ? courses : courses.filter(c => c.level === filter); const handleEnroll = (courseName) => { setPreselectedCourse(courseName); setPage('enroll'); }; return ( <div className="fade-in py-16 container mx-auto px-4"> <div className="text-center mb-12"> <h2 className="text-3xl font-bold text-gray-800 mb-4">Nuestros Cursos</h2> <p className="text-gray-600 max-w-2xl mx-auto">Explora nuestra oferta académica diseñada para desarrollar tus habilidades desde casa.</p> </div> {/* Filters */} <div className="flex flex-wrap justify-center gap-2 mb-12"> {categories.map(cat => ( <button key={cat} onClick={() => setFilter(cat)} className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${ filter === cat ? 'bg-valle-green text-white shadow-md' : 'bg-white text-gray-600 hover:bg-gray-100 border border-gray-200' }`} > {cat} </button> ))} </div> {/* Grid */} <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8"> {filteredCourses.map(course => ( <CourseCard key={course.id} course={course} onEnroll={handleEnroll} /> ))} </div> </div> ); }; const AdminPanel = ({ courses, setCourses }) => { const [isEditing, setIsEditing] = useState(false); const [currentId, setCurrentId] = useState(null); // Estado del formulario const [formData, setFormData] = useState({ title: '', image: '', description: '', instructor: '', price: '', level: 'Primaria', link: '' }); const handleInputChange = (e) => { const { name, value } = e.target; setFormData({ ...formData, [name]: value }); }; const handleSubmit = (e) => { e.preventDefault(); if (isEditing) { // Editar curso existente const updatedCourses = courses.map(course => course.id === currentId ? { ...formData, id: currentId, price: Number(formData.price) } : course ); setCourses(updatedCourses); } else { // Agregar nuevo curso const newCourse = { ...formData, id: Date.now(), // ID simple basado en timestamp price: Number(formData.price) }; setCourses([...courses, newCourse]); } // Reset form resetForm(); }; const handleEdit = (course) => { setIsEditing(true); setCurrentId(course.id); setFormData({ title: course.title, image: course.image, description: course.description || '', instructor: course.instructor, price: course.price, level: course.level, link: course.link || '' }); window.scrollTo(0, 0); // Subir para ver el formulario }; const handleDelete = (id) => { if(confirm('¿Estás seguro de eliminar este curso?')) { const filteredCourses = courses.filter(c => c.id !== id); setCourses(filteredCourses); } }; const resetForm = () => { setIsEditing(false); setCurrentId(null); setFormData({ title: '', image: '', description: '', instructor: '', price: '', level: 'Primaria', link: '' }); }; return ( <div className="fade-in py-16 container mx-auto px-4 bg-gray-50 min-h-screen"> <div className="flex justify-between items-center mb-8"> <h2 className="text-3xl font-bold text-gray-800">Panel de Administración de Cursos</h2> <span className="bg-valle-dark text-white px-3 py-1 rounded text-xs font-mono">Admin Mode</span> </div> <div className="grid lg:grid-cols-3 gap-8"> {/* Formulario (Columna Izquierda en Desktop) */} <div className="lg:col-span-1"> <div className="bg-white p-6 rounded-xl shadow-lg border border-gray-200 sticky top-24"> <h3 className="text-xl font-bold mb-4 text-valle-green flex items-center gap-2"> {isEditing ? <IconEdit/> : <IconPlus/>} {isEditing ? 'Editar Curso' : 'Agregar Nuevo Curso'} </h3> <form onSubmit={handleSubmit} className="space-y-4"> <div> <label className="block text-sm font-medium text-gray-700">Título del Curso</label> <input required name="title" value={formData.title} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none" /> </div> <div> <label className="block text-sm font-medium text-gray-700">Instructor</label> <input required name="instructor" value={formData.instructor} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none" /> </div> <div className="grid grid-cols-2 gap-2"> <div> <label className="block text-sm font-medium text-gray-700">Precio (Q)</label> <input required type="number" name="price" value={formData.price} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none" /> </div> <div> <label className="block text-sm font-medium text-gray-700">Nivel</label> <select name="level" value={formData.level} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none"> <option>Primaria</option> <option>Secundaria</option> <option>Vocacional</option> <option>Profesional</option> <option>Gratis</option> </select> </div> </div> <div> <label className="block text-sm font-medium text-gray-700">URL Imagen</label> <input required name="image" placeholder="https://..." value={formData.image} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none" /> </div> <div> <label className="block text-sm font-medium text-gray-700">Descripción Corta</label> <textarea name="description" rows="2" value={formData.description} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none"></textarea> </div> <div> <label className="block text-sm font-medium text-gray-700">Link de Inscripción (Opcional)</label> <input name="link" placeholder="Ej: https://forms.google.com/..." value={formData.link} onChange={handleInputChange} className="w-full border p-2 rounded focus:ring-2 focus:ring-valle-green outline-none" /> <p className="text-xs text-gray-500 mt-1">Si se deja vacío, usa el formulario interno.</p> </div> <div className="flex gap-2 pt-2"> <button type="submit" className={`flex-1 py-2 px-4 rounded font-bold text-white transition-colors ${isEditing ? 'bg-orange-500 hover:bg-orange-600' : 'bg-valle-green hover:bg-green-600'}`}> {isEditing ? 'Guardar Cambios' : 'Agregar Curso'} </button> {isEditing && ( <button type="button" onClick={resetForm} className="px-4 py-2 bg-gray-300 rounded hover:bg-gray-400 text-gray-700 font-bold"> Cancelar </button> )} </div> </form> </div> </div> {/* Lista de Cursos (Columna Derecha) */} <div className="lg:col-span-2"> <div className="bg-white rounded-xl shadow border border-gray-200 overflow-hidden"> <table className="min-w-full divide-y divide-gray-200"> <thead className="bg-gray-50"> <tr> <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Curso</th> <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Info</th> <th className="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Acciones</th> </tr> </thead> <tbody className="bg-white divide-y divide-gray-200"> {courses.map(course => ( <tr key={course.id} className="hover:bg-gray-50"> <td className="px-6 py-4 whitespace-nowrap"> <div className="flex items-center"> <div className="h-10 w-10 flex-shrink-0"> <img className="h-10 w-10 rounded-full object-cover" src={course.image} alt="" /> </div> <div className="ml-4"> <div className="text-sm font-medium text-gray-900">{course.title}</div> <div className="text-sm text-gray-500">{course.level}</div> </div> </div> </td> <td className="px-6 py-4"> <div className="text-sm text-gray-900 font-bold">Q{course.price}</div> <div className="text-xs text-gray-500 truncate max-w-xs">{course.instructor}</div> {course.link && <span className="text-xs bg-blue-100 text-blue-800 px-2 py-0.5 rounded-full">Link Externo</span>} </td> <td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> <button onClick={() => handleEdit(course)} className="text-indigo-600 hover:text-indigo-900 mr-4 inline-flex items-center"> <IconEdit /> <span className="ml-1 hidden sm:inline">Editar</span> </button> <button onClick={() => handleDelete(course.id)} className="text-red-600 hover:text-red-900 inline-flex items-center"> <IconTrash /> <span className="ml-1 hidden sm:inline">Borrar</span> </button> </td> </tr> ))} {courses.length === 0 && ( <tr> <td colSpan="3" className="px-6 py-4 text-center text-gray-500"> No hay cursos registrados. </td> </tr> )} </tbody> </table> </div> </div> </div> </div> ); }; const Platform = () => ( <div className="fade-in py-16 bg-white"> <div className="container mx-auto px-4"> <div className="text-center mb-16"> <h2 className="text-3xl font-bold text-gray-800 mb-4">Nuestra Plataforma Tecnológica</h2> <p className="text-gray-600">Un entorno virtual intuitivo diseñado para el aprendizaje efectivo.</p> </div> <div className="grid md:grid-cols-3 gap-8 mb-16"> <div className="p-6 bg-gray-50 rounded-xl border border-gray-100 text-center hover:shadow-lg transition-shadow"> <div className="w-16 h-16 bg-blue-100 text-cielo-blue rounded-full flex items-center justify-center mx-auto mb-4"> <IconLaptop /> </div> <h3 className="text-xl font-bold mb-2">Aulas Virtuales</h3> <p className="text-gray-600 text-sm">Integración con Zoom y Google Classroom para clases en vivo fluidas y grabadas.</p> </div> <div className="p-6 bg-gray-50 rounded-xl border border-gray-100 text-center hover:shadow-lg transition-shadow"> <div className="w-16 h-16 bg-green-100 text-valle-green rounded-full flex items-center justify-center mx-auto mb-4"> <IconGradCap /> </div> <h3 className="text-xl font-bold mb-2">Moodle Avanzado</h3> <p className="text-gray-600 text-sm">Gestión de tareas, exámenes automatizados y seguimiento de progreso en tiempo real.</p> </div> <div className="p-6 bg-gray-50 rounded-xl border border-gray-100 text-center hover:shadow-lg transition-shadow"> <div className="w-16 h-16 bg-orange-100 text-orange-500 rounded-full flex items-center justify-center mx-auto mb-4"> <IconPhone /> </div> <h3 className="text-xl font-bold mb-2">100% Móvil</h3> <p className="text-gray-600 text-sm">App dedicada para estudiar desde tu celular o tablet, incluso con baja conexión.</p> </div> </div> {/* Mock Interface */} <div className="bg-valle-dark rounded-2xl p-4 md:p-8 shadow-2xl mx-auto max-w-5xl"> <div className="bg-gray-800 rounded-t-lg p-2 flex space-x-2 items-center mb-1"> <div className="w-3 h-3 bg-red-500 rounded-full"></div> <div className="w-3 h-3 bg-yellow-500 rounded-full"></div> <div className="w-3 h-3 bg-green-500 rounded-full"></div> <span className="text-gray-400 text-xs ml-2">aula.colegioelvalle.edu.gt</span> </div> <div className="bg-white rounded-b-lg overflow-hidden relative"> <img src="https://images.unsplash.com/photo-1531403009284-440f080d1e12?auto=format&fit=crop&q=80&w=1200" alt="Plataforma Interface" className="w-full opacity-90" /> <div className="absolute inset-0 flex items-center justify-center"> <button className="bg-cielo-blue text-white px-6 py-3 rounded-full shadow-lg font-bold flex items-center gap-2 hover:scale-105 transition-transform"> <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"></path><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> Ver Demo </button> </div> </div> </div> </div> </div> ); const EnrollForm = ({ preselectedCourse, courses }) => { const [formData, setFormData] = useState({ name: '', email: '', phone: '', course: preselectedCourse || '', level: 'Primaria' }); const [submitted, setSubmitted] = useState(false); const handleSubmit = (e) => { e.preventDefault(); setSubmitted(true); }; if (submitted) { return ( <div className="fade-in py-16 container mx-auto px-4 text-center"> <div className="bg-green-100 text-valle-dark p-8 rounded-2xl max-w-lg mx-auto"> <h3 className="text-2xl font-bold mb-4">¡Solicitud Recibida!</h3> <p>Gracias, {formData.name}. Hemos enviado los detalles de pago e inscripción a <strong>{formData.email}</strong>.</p> <p className="mt-4 text-sm">Un asesor educativo te contactará pronto al {formData.phone}.</p> <button onClick={() => setSubmitted(false)} className="mt-6 text-valle-green font-semibold underline">Volver al formulario</button> </div> </div> ); } return ( <div className="fade-in py-16 container mx-auto px-4"> <div className="max-w-2xl mx-auto bg-white rounded-2xl shadow-xl overflow-hidden"> <div className="bg-valle-green p-6 text-white text-center"> <h2 className="text-2xl font-bold">Ficha de Inscripción</h2> <p className="opacity-90">Comienza tu viaje educativo hoy</p> </div> <form onSubmit={handleSubmit} className="p-8 space-y-6"> <div className="grid md:grid-cols-2 gap-6"> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Nombre Completo</label> <input required type="text" className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-valle-green focus:border-transparent outline-none" onChange={e => setFormData({...formData, name: e.target.value})} /> </div> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Correo Electrónico</label> <input required type="email" className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-valle-green focus:border-transparent outline-none" onChange={e => setFormData({...formData, email: e.target.value})} /> </div> </div> <div className="grid md:grid-cols-2 gap-6"> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Teléfono (Guatemala)</label> <input required placeholder="+502" type="tel" className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-valle-green focus:border-transparent outline-none" onChange={e => setFormData({...formData, phone: e.target.value})} /> </div> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Nivel Educativo</label> <select className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-valle-green focus:border-transparent outline-none" value={formData.level} onChange={e => setFormData({...formData, level: e.target.value})}> <option>Primaria</option> <option>Secundaria</option> <option>Diversificado/Bachillerato</option> <option>Profesional</option> </select> </div> </div> <div> <label className="block text-sm font-medium text-gray-700 mb-1">Curso de Interés</label> <select className="w-full border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-valle-green focus:border-transparent outline-none" value={formData.course} onChange={e => setFormData({...formData, course: e.target.value})}> <option value="">-- Seleccionar Curso --</option> {courses.map(c => <option key={c.id} value={c.title}>{c.title} - Q{c.price}</option>)} </select> </div> <div className="bg-gray-50 p-4 rounded-lg border border-gray-200"> <h4 className="font-semibold text-gray-700 mb-2">Método de Pago</h4> <div className="flex gap-4"> <label className="flex items-center space-x-2 cursor-pointer"> <input type="radio" name="payment" className="text-valle-green focus:ring-valle-green" defaultChecked /> <span>Tarjeta Crédito/Débito</span> </label> <label className="flex items-center space-x-2 cursor-pointer"> <input type="radio" name="payment" className="text-valle-green focus:ring-valle-green" /> <span>PayPal</span> </label> <label className="flex items-center space-x-2 cursor-pointer"> <input type="radio" name="payment" className="text-valle-green focus:ring-valle-green" /> <span>Transferencia GT</span> </label> </div> </div> <button type="submit" className="w-full bg-valle-green text-white font-bold py-3 rounded-lg hover:bg-green-600 transition-colors shadow-lg"> Completar Inscripción </button> </form> </div> </div> ); }; const Contact = () => ( <div className="fade-in py-16 container mx-auto px-4"> <div className="grid md:grid-cols-2 gap-12"> <div> <h2 className="text-3xl font-bold text-gray-800 mb-6">Contáctanos</h2> <p className="text-gray-600 mb-8">Estamos listos para resolver tus dudas sobre el E-learning. Visítanos o escríbenos.</p> <div className="space-y-6"> <div className="flex items-start"> <div className="text-valle-green mt-1 mr-4"><IconMapPin /></div> <div> <h4 className="font-bold text-gray-800">Ubicación Administrativa</h4> <p className="text-gray-600">Edificio Tecnológico, Zona 4<br/>Ciudad de Guatemala, Guatemala</p> </div> </div> <div className="flex items-start"> <div className="text-valle-green mt-1 mr-4"><IconPhone /></div> <div> <h4 className="font-bold text-gray-800">Teléfono</h4> <p className="text-gray-600">+502 2200-1234</p> <p className="text-gray-500 text-sm">Lunes a Viernes, 8:00 - 17:00</p> </div> </div> <div className="flex items-start"> <div className="text-valle-green mt-1 mr-4"><IconMail /></div> <div> <h4 className="font-bold text-gray-800">Correo Electrónico</h4> <p className="text-gray-600">info@colegioelvalle.gt</p> </div> </div> </div> </div> <div className="bg-white p-8 rounded-xl shadow-lg border border-gray-100"> <h3 className="text-xl font-bold mb-4">Envíanos un mensaje</h3> <form className="space-y-4"> <input type="text" placeholder="Nombre" className="w-full border border-gray-300 rounded px-4 py-2 outline-none focus:border-valle-green" /> <input type="email" placeholder="Email" className="w-full border border-gray-300 rounded px-4 py-2 outline-none focus:border-valle-green" /> <textarea rows="4" placeholder="¿En qué podemos ayudarte?" className="w-full border border-gray-300 rounded px-4 py-2 outline-none focus:border-valle-green"></textarea> <button className="bg-valle-dark text-white px-6 py-2 rounded font-bold hover:bg-gray-800 transition-colors">Enviar Mensaje</button> </form> </div> </div> </div> ); const Blog = () => ( <div className="fade-in py-16 container mx-auto px-4"> <h2 className="text-3xl font-bold text-center text-gray-800 mb-12">Recursos y Blog Educativo</h2> <div className="grid md:grid-cols-3 gap-8"> {POSTS.map(post => ( <div key={post.id} className="bg-white rounded-lg shadow hover:shadow-lg transition-all p-6 border border-gray-100"> <div className="text-sm text-cielo-blue font-bold mb-2">{post.date}</div> <h3 className="text-xl font-bold text-gray-800 mb-3">{post.title}</h3> <p className="text-gray-600 mb-4">{post.excerpt}</p> <button className="text-valle-green font-semibold hover:underline">Leer más →</button> </div> ))} <div className="bg-valle-green/10 rounded-lg p-6 border border-valle-green/20 flex flex-col justify-center items-center text-center"> <div className="text-4xl mb-4">📥</div> <h3 className="text-lg font-bold text-valle-dark mb-2">Guía de Estudio PDF</h3> <p className="text-sm text-gray-600 mb-4">Descarga gratis nuestra guía para estudiantes online.</p> <button className="bg-valle-green text-white px-4 py-2 rounded text-sm hover:bg-green-600 transition">Descargar Ahora</button> </div> </div> </div> ); const Footer = ({ setPage }) => ( <footer className="bg-gray-900 text-gray-300 py-12"> <div className="container mx-auto px-4 grid md:grid-cols-4 gap-8"> <div> <div className="flex items-center text-white mb-4"> <span className="text-valle-green mr-2"><IconBook /></span> <span className="font-bold text-lg">Colegio El Valle</span> </div> <p className="text-sm text-gray-400">Educación innovadora para un futuro brillante en Guatemala.</p> </div> <div> <h4 className="text-white font-bold mb-4">Enlaces Rápidos</h4> <ul className="space-y-2 text-sm"> <li><button onClick={() => setPage('home')} className="hover:text-valle-green">Inicio</button></li> <li><button onClick={() => setPage('courses')} className="hover:text-valle-green">Cursos</button></li> <li><button onClick={() => setPage('enroll')} className="hover:text-valle-green">Admisiones</button></li> </ul> </div> <div> <h4 className="text-white font-bold mb-4">Síguenos</h4> <div className="flex space-x-4"> <a href="#" className="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-blue-600 transition">F</a> <a href="#" className="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-pink-600 transition">I</a> <a href="#" className="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-red-600 transition">Y</a> </div> </div> </div> <div className="border-t border-gray-800 mt-12 pt-8 text-center text-sm text-gray-500"> © 2024 Colegio El Valle Guatemala. Todos los derechos reservados. </div> </footer> ); // --- APP MAIN COMPONENT --- const App = () => { const [currentPage, setCurrentPage] = useState('home'); const [preselectedCourse, setPreselectedCourse] = useState(null); // Estado principal para los cursos const [courses, setCourses] = useState(INITIAL_COURSES); useEffect(() => { window.scrollTo(0, 0); }, [currentPage]); const renderPage = () => { switch(currentPage) { case 'home': return ( <> <Hero setPage={setCurrentPage} /> <div className="container mx-auto px-4 py-16 text-center"> <h2 className="text-2xl font-bold mb-8">Nuestros Estudiantes Dicen</h2> <div className="grid md:grid-cols-2 gap-6 max-w-4xl mx-auto"> <div className="bg-white p-6 rounded-lg shadow italic text-gray-600"> "Gracias a Colegio El Valle pude terminar mi bachillerato sin dejar mi trabajo en Xela. ¡La plataforma es excelente!" <br/> <span className="text-valle-green font-bold not-italic text-sm mt-2 block">- Juan P., Quetzaltenango</span> </div> <div className="bg-white p-6 rounded-lg shadow italic text-gray-600"> "Mis hijos disfrutan sus clases de inglés desde casa. Los maestros son muy pacientes y profesionales." <br/> <span className="text-valle-green font-bold not-italic text-sm mt-2 block">- María L., Ciudad de Guatemala</span> </div> </div> </div> </> ); case 'about': return <About />; case 'courses': return <Courses courses={courses} setPage={setCurrentPage} setPreselectedCourse={setPreselectedCourse} />; case 'platform': return <Platform />; case 'contact': return <Contact />; case 'enroll': return <EnrollForm preselectedCourse={preselectedCourse} courses={courses} />; case 'blog': return <Blog />; case 'admin': return <AdminPanel courses={courses} setCourses={setCourses} />; default: return <Hero setPage={setCurrentPage} />; } }; return ( <div className="min-h-screen flex flex-col font-sans text-gray-900 bg-gray-50"> <Header setPage={setCurrentPage} currentPage={currentPage} /> <main className="flex-grow"> {renderPage()} </main> <Footer setPage={setCurrentPage} /> {/* Botón Flotante de Chat */} {currentPage !== 'admin' && ( <button className="fixed bottom-6 right-6 bg-valle-green text-white p-4 rounded-full shadow-2xl hover:bg-green-600 transition-transform hover:scale-110 z-50 flex items-center gap-2"> <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path></svg> <span className="hidden md:inline font-bold">Ayuda</span> </button> )} </div> ); }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />); </script> </body> </html>
💾 Simpan
Batal
⬅ colegioelvalle.edu.gt
4 item
Nama
Tipe
Ukuran
Diubah
Aksi
🌐
config.html
html
456 B
2026-02-01 23:05
✏️
👁️
🔤
🗑
🌐
cursos.html
html
22.3 KB
2026-02-02 00:18
✏️
👁️
🔤
🗑
🌐
index.html
html
57.2 KB
2026-02-02 00:15
✏️
👁️
🔤
🗑
🌐
old-index.html
html
6.4 KB
2026-01-27 18:21
✏️
👁️
🔤
🗑
✏️ Rename
Nama Baru
Simpan
Batal