From e50d637e9047df44f918533de9cab461397e2bfb Mon Sep 17 00:00:00 2001 From: "luis.aguilar" Date: Wed, 14 May 2025 21:15:53 +0000 Subject: [PATCH] revert 2b862b74c2d1fefedd7550d826886f47c4490e01 revert pruebas --- api/alumnos.php | 64 --- api/cursos.php | 103 ++--- api/diploma.php | 78 ---- api/login.php | 59 ++- assets/css/styles.css | 33 -- assets/js/main.js | 852 ++++++++++++---------------------------- dashboard.php | 113 ++++-- includes/config.php | 2 +- index.php | 9 +- sql/diplomaster (1).sql | 194 ++++++--- 10 files changed, 552 insertions(+), 955 deletions(-) delete mode 100644 api/alumnos.php delete mode 100644 api/diploma.php diff --git a/api/alumnos.php b/api/alumnos.php deleted file mode 100644 index fe00c0d..0000000 --- a/api/alumnos.php +++ /dev/null @@ -1,64 +0,0 @@ - 'No autenticado']); - exit; -} - -$method = $_SERVER['REQUEST_METHOD']; - -switch ($method) { - case 'GET': - try { - $stmt = $pdo->query(" - SELECT a.*, - GROUP_CONCAT(ac.curso_id) AS cursos - FROM alumnos a - LEFT JOIN alumnos_cursos ac ON a.id = ac.alumno_id - GROUP BY a.id - "); - - $alumnos = $stmt->fetchAll(); - - // Convertir cursos a array - foreach ($alumnos as &$alumno) { - $alumno['cursos'] = $alumno['cursos'] ? explode(',', $alumno['cursos']) : []; - } - - echo json_encode($alumnos); - - } catch (PDOException $e) { - http_response_code(500); - echo json_encode(['error' => 'Error al cargar alumnos']); - } - break; - - case 'POST': - $data = json_decode(file_get_contents('php://input'), true); - - try { - $stmt = $pdo->prepare(" - INSERT INTO alumnos (nombre, email, telefono) - VALUES (?, ?, ?) - "); - $stmt->execute([ - $data['nombre'], - $data['email'], - $data['telefono'] ?? null - ]); - - echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); - } catch (PDOException $e) { - http_response_code(500); - echo json_encode(['error' => 'Error al crear alumno: ' . $e->getMessage()]); - } - break; - - default: - http_response_code(405); - echo json_encode(['error' => 'Método no permitido']); -} -?> \ No newline at end of file diff --git a/api/cursos.php b/api/cursos.php index 83de32e..9d7ce17 100644 --- a/api/cursos.php +++ b/api/cursos.php @@ -9,91 +9,44 @@ if (!is_logged_in()) { } $method = $_SERVER['REQUEST_METHOD']; -$profesorId = $_SESSION['profesor']['id'] ?? null; +$user = $_SESSION['user']; switch ($method) { case 'GET': - try { - $query = " - SELECT - c.*, - COUNT(ac.id) AS alumnos_count, - u.nombre AS profesor_nombre - FROM cursos c - LEFT JOIN alumnos_cursos ac ON c.id = ac.curso_id - LEFT JOIN usuarios u ON c.profesor_id = u.id - "; - - $params = []; - - if (isset($_GET['profesor_id'])) { - $query .= " WHERE c.profesor_id = ?"; - $params[] = $_GET['profesor_id']; - } - - $query .= " GROUP BY c.id ORDER BY c.estado, c.nombre"; - - $stmt = $pdo->prepare($query); - $stmt->execute($params); - - echo json_encode($stmt->fetchAll()); - - } catch (PDOException $e) { - http_response_code(500); - echo json_encode(['error' => 'Error al cargar cursos: ' . $e->getMessage()]); + if ($user['rol'] === 'admin') { + $stmt = $pdo->query("SELECT * FROM cursos"); + } else { + $stmt = $pdo->prepare(" + SELECT c.*, uc.estado, uc.fecha_inicio, uc.fecha_fin, uc.profesor + FROM usuario_cursos uc + JOIN cursos c ON uc.curso_id = c.id + WHERE uc.usuario_id = ? + "); + $stmt->execute([$user['id']]); } + echo json_encode($stmt->fetchAll()); break; case 'POST': - $data = json_decode(file_get_contents('php://input'), true); - - try { - $stmt = $pdo->prepare(" - INSERT INTO cursos (nombre, descripcion, tipo, estado, profesor_id) - VALUES (?, ?, ?, 'activo', ?) - "); - $stmt->execute([ - $data['nombre'], - $data['descripcion'] ?? null, - $data['tipo'], - $profesorId - ]); - - echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); - } catch (PDOException $e) { - http_response_code(500); - echo json_encode(['error' => 'Error al crear curso: ' . $e->getMessage()]); - } - break; - - case 'DELETE': - $id = $_GET['id'] ?? null; - if (!$id) { - http_response_code(400); - echo json_encode(['error' => 'ID de curso no proporcionado']); + if ($user['rol'] !== 'admin') { + http_response_code(403); + echo json_encode(['error' => 'Acceso no autorizado']); exit; } - try { - // Verificar que el curso pertenece al profesor - if ($profesorId) { - $stmt = $pdo->prepare("SELECT id FROM cursos WHERE id = ? AND profesor_id = ?"); - $stmt->execute([$id, $profesorId]); - if (!$stmt->fetch()) { - http_response_code(403); - echo json_encode(['error' => 'No autorizado']); - exit; - } - } - - $stmt = $pdo->prepare("DELETE FROM cursos WHERE id = ?"); - $stmt->execute([$id]); - - echo json_encode(['success' => true]); - } catch (PDOException $e) { - http_response_code(500); - echo json_encode(['error' => 'Error al eliminar curso: ' . $e->getMessage()]); - } + $data = json_decode(file_get_contents('php://input'), true); + + $stmt = $pdo->prepare(" + INSERT INTO cursos (nombre, tipo, competencias) + VALUES (?, ?, ?) + "); + $stmt->execute([ + $data['nombre'], + $data['tipo'], + $data['competencias'] ?? null + ]); + + echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); break; default: diff --git a/api/diploma.php b/api/diploma.php deleted file mode 100644 index 5450f13..0000000 --- a/api/diploma.php +++ /dev/null @@ -1,78 +0,0 @@ - 'No autenticado']); - exit; -} - -try { - $profesorId = $_SESSION['profesor']['id'] ?? null; - $action = $_GET['action'] ?? null; - - if ($action === 'resend') { - // Lógica para reenviar diploma - $codigo = $_GET['codigo'] ?? null; - if (!$codigo) { - throw new Exception('Código de diploma no proporcionado'); - } - - // Aquí iría la lógica para reenviar el diploma por email - echo json_encode(['success' => true, 'message' => 'Diploma reenviado']); - exit; - } - - $query = " - SELECT - d.id, - d.codigo_unico, - d.fecha_emision, - a.nombre AS alumno_nombre, - a.email AS alumno_email, - c.nombre AS curso_nombre, - c.tipo AS curso_tipo, - c.id AS curso_id, - DATE_FORMAT(d.fecha_emision, '%d/%m/%Y') AS fecha_formateada - FROM diplomas d - JOIN alumnos_cursos ac ON d.alumno_curso_id = ac.id - JOIN alumnos a ON ac.alumno_id = a.id - JOIN cursos c ON ac.curso_id = c.id - "; - - $params = []; - - if ($profesorId) { - $query .= " WHERE c.profesor_id = ?"; - $params[] = $profesorId; - } - - $query .= " ORDER BY d.fecha_emision DESC"; - - $stmt = $pdo->prepare($query); - $stmt->execute($params); - - $diplomas = $stmt->fetchAll(); - - // Asegurar que todos los diplomas tengan código único - foreach ($diplomas as &$diploma) { - if (empty($diploma['codigo_unico'])) { - $diploma['codigo_unico'] = 'DIPL-' . str_pad($diploma['id'], 6, '0', STR_PAD_LEFT); - } - } - - echo json_encode([ - 'success' => true, - 'data' => $diplomas, - 'count' => count($diplomas) - ]); - -} catch (Exception $e) { - http_response_code(500); - echo json_encode([ - 'success' => false, - 'error' => $e->getMessage() - ]); -} -?> \ No newline at end of file diff --git a/api/login.php b/api/login.php index 9906b9c..b62b8f4 100644 --- a/api/login.php +++ b/api/login.php @@ -2,57 +2,80 @@ header('Content-Type: application/json'); require '../includes/config.php'; +// Habilitar reporte de errores para depuración (quitar en producción) error_reporting(E_ALL); ini_set('display_errors', 1); +// Verificar si la solicitud es POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['success' => false, 'message' => 'Método no permitido']); exit; } -$email = trim($_POST['email'] ?? ''); +// Obtener datos del formulario +$username = trim($_POST['username'] ?? ''); $password = $_POST['password'] ?? ''; -if (empty($email) || empty($password)) { - echo json_encode(['success' => false, 'message' => 'Email y contraseña son requeridos']); +// Validaciones básicas +if (empty($username) || empty($password)) { + echo json_encode(['success' => false, 'message' => 'Usuario y contraseña son requeridos']); exit; } try { - // Buscar profesor en la base de datos - $stmt = $pdo->prepare("SELECT * FROM usuarios WHERE email = ? AND aprobado = 1"); - $stmt->execute([$email]); - $profesor = $stmt->fetch(); + // Buscar usuario en la base de datos + $stmt = $pdo->prepare("SELECT * FROM usuarios WHERE username = ?"); + $stmt->execute([$username]); + $user = $stmt->fetch(); - if (!$profesor) { - echo json_encode(['success' => false, 'message' => 'Profesor no encontrado o no aprobado']); + if (!$user) { + echo json_encode(['success' => false, 'message' => 'Usuario no encontrado']); exit; } - if (!password_verify($password, $profesor['password'])) { + // Verificar contraseña + if (!password_verify($password, $user['password'])) { echo json_encode(['success' => false, 'message' => 'Contraseña incorrecta']); exit; } - // Configurar sesión de profesor - $_SESSION['profesor'] = [ - 'id' => $profesor['id'], - 'nombre' => $profesor['nombre'], - 'email' => $profesor['email'] + // Obtener cursos del usuario + $stmt = $pdo->prepare(" + SELECT c.*, uc.estado, uc.fecha_inicio, uc.fecha_fin, uc.profesor + FROM usuario_cursos uc + JOIN cursos c ON uc.curso_id = c.id + WHERE uc.usuario_id = ? + "); + $stmt->execute([$user['id']]); + $cursos = $stmt->fetchAll(); + + // Configurar sesión de usuario + $_SESSION['user'] = [ + 'id' => $user['id'], + 'username' => $user['username'], + 'nombre' => $user['nombre'], + 'email' => $user['email'], + 'rol' => $user['rol'], + 'cursos' => $cursos ]; + // Respuesta exitosa echo json_encode([ 'success' => true, 'redirect' => 'dashboard.php', - 'profesor' => [ - 'id' => $profesor['id'], - 'nombre' => $profesor['nombre'] + 'user' => [ + 'id' => $user['id'], + 'nombre' => $user['nombre'], + 'rol' => $user['rol'] ] ]); } catch (PDOException $e) { + // Registrar error en archivo de log error_log('Error en login.php: ' . $e->getMessage()); + + // Respuesta de error genérico (no mostrar detalles internos al usuario) echo json_encode([ 'success' => false, 'message' => 'Error en el servidor. Por favor, intente más tarde.' diff --git a/assets/css/styles.css b/assets/css/styles.css index 2daf94d..d106f83 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -566,36 +566,3 @@ header h1 { background-color: #a0aec0; cursor: not-allowed; } -/* Badges para tipos de curso */ -.badge { - padding: 4px 8px; - border-radius: 12px; - font-size: 0.8em; - font-weight: 600; - text-transform: capitalize; -} - -.badge.active { - background-color: #4CAF50; - color: white; -} - -.badge.inactive { - background-color: #f44336; - color: white; -} - -.badge.type-inyeccion { - background-color: #2196F3; - color: white; -} - -.badge.type-pildora { - background-color: #FF9800; - color: white; -} - -.badge.type-tratamiento { - background-color: #9C27B0; - color: white; -} diff --git a/assets/js/main.js b/assets/js/main.js index 38b160d..6b93519 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -6,7 +6,7 @@ document.addEventListener('DOMContentLoaded', function() { } // Configuración inicial del dashboard - if (document.body.classList.contains('admin')) { + if (document.body.classList.contains('admin') || document.body.classList.contains('user')) { initializeDashboard(); } }); @@ -47,126 +47,126 @@ function initializeDashboard() { function setupSidebarNavigation() { document.querySelectorAll('.sidebar-menu li').forEach(item => { - if (item.getAttribute('data-section')) { - item.addEventListener('click', function() { - const section = this.getAttribute('data-section'); - showSection(section); - }); - } + item.addEventListener('click', function() { + const section = this.getAttribute('data-section'); + showSection(section); + }); }); } function loadInitialData() { - // Verificar si es admin o profesor - const isAdmin = document.body.classList.contains('admin'); - - // Hacer todas las peticiones en paralelo - Promise.all([ - fetch('api/cursos.php').then(res => res.json()), - fetch('api/alumnos.php').then(res => res.json()), - fetch('api/diplomas.php').then(res => res.json()) - ]) - .then(([courses, students, diplomas]) => { - if (isAdmin) { - updateAdminStats(courses, students, diplomas); - } else { - updateProfessorStats(courses, students, diplomas); - } - }) - .catch(error => { - console.error('Error loading initial data:', error); - showErrorNotification('Error al cargar datos iniciales'); - }); + fetch('api/cursos.php') + .then(response => response.json()) + .then(data => { + if (document.body.classList.contains('admin')) { + updateAdminStats(data); + } else { + updateUserStats(data); + } + }) + .catch(error => console.error('Error:', error)); } -function updateAdminStats(courses, students, diplomas) { - // Filtrar cursos activos - const activeCourses = courses.filter(c => c.estado === 'activo'); - - // Actualizar estadísticas - document.getElementById('active-courses-count').textContent = activeCourses.length; - document.getElementById('students-count').textContent = students.length; - document.getElementById('diplomas-count').textContent = diplomas.length; - - // Actualizar gráficos o tablas adicionales si existen - updateCoursesTable(activeCourses.slice(0, 5)); - updateRecentDiplomas(diplomas.slice(0, 5)); +function updateAdminStats(courses) { + document.getElementById('active-courses-count').textContent = courses.length; + // Aquí puedes agregar más llamadas para estudiantes y diplomas + // fetch('api/estudiantes.php')... + // fetch('api/diplomas.php')... } -function updateProfessorStats(courses, students, diplomas) { - const profesorId = getProfesorId(); +function updateUserStats(courses) { + document.getElementById('user-courses-count').textContent = courses.length; + const approvedCourses = courses.filter(c => c.estado === 'Aprobado'); + document.getElementById('user-diplomas-count').textContent = approvedCourses.length; + window.userCourses = courses; - // Filtrar datos del profesor actual - const profesorCourses = courses.filter(c => c.profesor_id == profesorId); - const activeProfesorCourses = profesorCourses.filter(c => c.estado === 'activo'); - - // Obtener alumnos del profesor - const profesorStudents = students.filter(s => - profesorCourses.some(c => s.cursos.includes(c.id)) - ); - - // Obtener diplomas del profesor - const profesorDiplomas = diplomas.filter(d => - profesorCourses.some(c => d.curso_id === c.id) - ); - - // Actualizar estadísticas - document.getElementById('active-courses-count').textContent = activeProfesorCourses.length; - document.getElementById('students-count').textContent = profesorStudents.length; - document.getElementById('diplomas-count').textContent = profesorDiplomas.length; - - // Actualizar tablas específicas del profesor - updateProfessorCoursesTable(activeProfesorCourses); - updateProfessorStudentsTable(profesorStudents.slice(0, 5)); + // Mostrar los primeros 5 cursos en el dashboard + renderDashboardCourses(courses.slice(0, 5)); + setupDashboardPagination(courses); + setupDashboardSearch(); } - -function updateRecentDiplomas(diplomas) { - const tableBody = document.getElementById('diplomas-table-body'); - if (!tableBody) return; +function renderDashboardCourses(courses) { + const tbody = document.getElementById('dashboard-courses-body'); + if (!tbody) return; - tableBody.innerHTML = diplomas.map(diploma => ` + tbody.innerHTML = courses.map(course => ` - ${diploma.alumno_nombre} - ${diploma.curso_nombre} - ${new Date(diploma.fecha_emision).toLocaleDateString()} + ${course.nombre} + ${course.fecha_inicio || '-'} + ${course.fecha_fin || '-'} - + ${course.estado === 'Aprobado' ? + `` : + 'No disponible'} `).join(''); -} -function updateCoursesTable(courses) { - const tableBody = document.getElementById('courses-table-body'); - if (!tableBody) return; - tableBody.innerHTML = courses.map(course => ` - - ${course.nombre} - ${course.tipo} - ${course.alumnos_count || 0} - ${course.estado} - - `).join(''); + // Configurar eventos de descarga + document.querySelectorAll('.download-btn').forEach(btn => { + btn.addEventListener('click', function() { + const courseId = this.getAttribute('data-course-id'); + window.open(`certificado.php?course_id=${courseId}`, '_blank'); + }); + }); } -function updateDashboardStats(courses, students, diplomas) { - const activeCourses = courses.filter(c => c.estado === 'activo'); +function setupDashboardPagination(allCourses) { + let currentPage = 1; + const perPage = 5; + const totalPages = Math.ceil(allCourses.length / perPage); - if (document.getElementById('active-courses-count')) { - document.getElementById('active-courses-count').textContent = activeCourses.length; + function updatePagination() { + const start = (currentPage - 1) * perPage; + const end = start + perPage; + renderDashboardCourses(allCourses.slice(start, end)); + + document.getElementById('page-info').textContent = `Página ${currentPage} de ${totalPages}`; + document.getElementById('prev-page').disabled = currentPage === 1; + document.getElementById('next-page').disabled = currentPage === totalPages || totalPages === 0; } - if (document.getElementById('students-count')) { - document.getElementById('students-count').textContent = students.length; - } + document.getElementById('prev-page')?.addEventListener('click', () => { + if (currentPage > 1) { + currentPage--; + updatePagination(); + } + }); - if (document.getElementById('diplomas-count')) { - document.getElementById('diplomas-count').textContent = diplomas.length; - } + document.getElementById('next-page')?.addEventListener('click', () => { + if (currentPage < totalPages) { + currentPage++; + updatePagination(); + } + }); + + updatePagination(); } +function setupDashboardSearch() { + const searchBtn = document.getElementById('dashboard-search-btn'); + const searchInput = document.getElementById('dashboard-course-search'); + + if (searchBtn && searchInput) { + searchBtn.addEventListener('click', () => { + const term = searchInput.value.toLowerCase(); + const filtered = window.userCourses.filter(course => + course.nombre.toLowerCase().includes(term) || + course.tipo.toLowerCase().includes(term) || + course.estado.toLowerCase().includes(term) + ); + + setupDashboardPagination(filtered); + }); + + // Permitir búsqueda al presionar Enter + searchInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') { + searchBtn.click(); + } + }); + } +} function showSection(sectionId, isInitialLoad = false) { // Actualizar menú activo updateActiveMenu(sectionId); @@ -176,7 +176,7 @@ function showSection(sectionId, isInitialLoad = false) { if (sectionElement) { toggleSections(sectionElement); - // Solo cargar contenido dinámico si no es la carga inicial del dashboard + // Solo cargar contenido dinámico si no es la carga inicial del dashboard if (!(isInitialLoad && sectionId === 'dashboard')) { if (sectionId === 'dashboard') { // Recargar los datos del dashboard @@ -184,22 +184,21 @@ function showSection(sectionId, isInitialLoad = false) { } else { loadDynamicContent(sectionId, sectionElement); } + } } } -} function updateActiveMenu(sectionId) { document.querySelectorAll('.sidebar-menu li').forEach(li => { li.classList.remove('active'); }); - - const activeItem = document.querySelector(`.sidebar-menu li[data-section="${sectionId}"]`); - if (activeItem) { - activeItem.classList.add('active'); - } + document.querySelector(`.sidebar-menu li[data-section="${sectionId}"]`).classList.add('active'); } function getSectionElement(sectionId) { + if (sectionId === 'dashboard') { + return document.getElementById('dashboard-content'); + } return document.getElementById(`${sectionId}-content`); } @@ -211,133 +210,66 @@ function toggleSections(activeSection) { } function loadDynamicContent(sectionId, container) { + // Mostrar loader mientras se carga container.innerHTML = '
Cargando...
'; switch(sectionId) { - case 'dashboard': - loadDashboardContent(container); - break; case 'courses': - loadProfessorCourses(container); + loadAdminCourses(container); break; case 'students': - loadStudentsManagement(container); + loadAdminStudents(container); + break; + case 'my-courses': + loadUserCourses(container); break; case 'diplomas': - loadDiplomasSection(container); + loadUserDiplomas(container); + break; + case 'profile': + loadProfileSection(container); break; default: container.innerHTML = '

Sección no implementada

'; } } -async function loadDashboardContent(container) { - try { - container.innerHTML = '
Cargando datos...
'; - - // Obtener datos del profesor - const profesorId = getProfesorId(); - if (!profesorId) throw new Error('No se pudo obtener ID de profesor'); - - // Hacer peticiones en paralelo - const responses = await Promise.all([ - fetch(`api/cursos.php?profesor_id=${profesorId}`), - fetch('api/alumnos.php'), - fetch(`api/diplomas.php?profesor_id=${profesorId}`) - ]); - - // Verificar respuestas - for (const response of responses) { - if (!response.ok) throw new Error(`Error HTTP: ${response.status}`); - } - - // Parsear JSON - const [courses, students, diplomas] = await Promise.all( - responses.map(r => r.json()) - ); - - // Filtrar cursos activos - const activeCourses = Array.isArray(courses) ? - courses.filter(c => c.estado === 'activo') : []; - - // Generar HTML - container.innerHTML = ` -
-

Resumen General

-
-

Resumen:

-

${activeCourses.length} cursos activos

-

${students.length || 0} alumnos registrados

-

${diplomas.length || 0} diplomas emitidos

-
-
-
-

Mis Cursos Activos

- ${generateCoursesPreview(activeCourses.slice(0, 5))} -
`; - - } catch (error) { - console.error('Error loading dashboard:', error); - container.innerHTML = ` -
-

Error al cargar datos

-

${error.message}

- -
`; - } -} - // Funciones para cargar contenido específico -function loadProfessorCourses(container) { - fetch(`api/cursos.php?profesor_id=${getProfesorId()}`) +function loadAdminCourses(container) { + fetch('api/cursos.php') .then(response => response.json()) .then(courses => { container.innerHTML = `
-

Mis Cursos

+

Gestión de Cursos

- - - - - + - +
+ + +
+ +

Lista de Cursos

-
- - -
-
- - - - - - - - - - - ${generateCoursesTableRows(courses)} - -
NombreTipoEstadoAcciones
+
+ ${generateCoursesList(courses)}
`; setupCourseForm(); - setupCourseSearch(); }) .catch(error => { container.innerHTML = '

Error al cargar los cursos

'; @@ -345,241 +277,96 @@ function loadProfessorCourses(container) { }); } -function loadStudentsManagement(container) { +function loadUserCourses(container) { + const courses = window.userCourses || []; + container.innerHTML = `
-

Gestión de Alumnos

-
- - - - - - - - - - -
-
-
-

Lista de Alumnos

+

Mis Cursos

- - + +
-
- - - - - - - - - - - - -
NombreEmailTeléfonoAcciones
+
+ ${courses.length > 0 ? + courses.map(course => generateCourseCard(course)).join('') : + '

No tienes cursos registrados.

'}
`; - - fetch('api/alumnos.php') - .then(response => response.json()) - .then(students => { - renderStudentsTable(students); - }) - .catch(error => { - console.error('Error:', error); - }); - - setupStudentForm(); - setupStudentSearch(); -} - -function loadDiplomasSection(container) { - container.innerHTML = '
Cargando diplomas...
'; - fetch(`api/diplomas.php?profesor_id=${getProfesorId()}`) - .then(response => { - if (!response.ok) throw new Error('Error en la respuesta del servidor'); - return response.json(); - }) - .then(data => { - if (!data.success) throw new Error(data.error || 'Error al obtener diplomas'); - - if (data.data.length === 0) { - container.innerHTML = ` -
-

Diplomas Emitidos

-

No hay diplomas registrados aún

- -
`; - return; - } - - container.innerHTML = ` -
-

Diplomas Emitidos

-
- -
- - -
-
-
- - - - - - - - - - - - - - ${data.data.map(diploma => ` - - - - - - - - - - `).join('')} - -
AlumnoEmailCursoTipoFechaCódigoAcciones
${diploma.alumno_nombre}${diploma.alumno_email}${diploma.curso_nombre}${diploma.curso_tipo}${diploma.fecha_formateada}${diploma.codigo_unico} - - -
-
-
- Mostrando ${data.data.length} diplomas -
-
`; - }) - .catch(error => { - console.error('Error:', error); - container.innerHTML = ` -
-

Error al cargar diplomas

-

${error.message}

- -
`; - }); + setupCourseSearch(); } -// Función para generar nuevo diploma -function generateNewDiploma() { - // Implementar lógica para seleccionar alumno y curso - alert('Implementar diálogo para seleccionar alumno y curso'); -} - -// Funciones auxiliares para generar contenido -function generateCoursesTableRows(courses) { - return courses.map(course => ` - - ${course.nombre} - ${course.tipo} - ${course.estado} - - - - - - `).join(''); -} - -function generateStudentsTableRows(students) { - return students.map(student => ` - - ${student.nombre} - ${student.email} - ${student.telefono || '-'} - - - - - - `).join(''); -} - -function generateDiplomasTableRows(diplomas) { - return diplomas.map(diploma => ` - - ${diploma.alumno_nombre} - ${diploma.curso_nombre} - ${new Date(diploma.fecha_emision).toLocaleDateString()} - - - - - - `).join(''); -} -function generateDashboardCoursesRows(courses) { - return courses.map(course => ` - - ${course.nombre} - ${course.tipo} - ${course.alumnos_count || 0} - ${course.estado} - - `).join(''); -} -function generateCoursesPreview(courses) { - if (!courses.length) return '

No tienes cursos activos

'; +function loadUserDiplomas(container) { + const courses = (window.userCourses || []).filter(c => c.estado === 'Aprobado'); + container.innerHTML = ` +
+

Mis Diplomas

+ ${courses.length > 0 ? + courses.map(course => generateDiplomaCard(course)).join('') : + '

No tienes diplomas disponibles todavía.

'} +
`; + + setupDiplomaDownloads(); +} + +// Funciones auxiliares +function generateCoursesList(courses) { + return courses.map(course => ` +
+

${course.nombre}

+

Tipo: ${course.tipo}

+

ID: ${course.id}

+
+ `).join(''); +} + +function generateCourseCard(course) { return ` -
- - - - - - - - - - - ${courses.map(course => ` - - - - - - - `).join('')} - -
NombreTipoAlumnosEstado
${course.nombre || 'Sin nombre'}${course.tipo || 'N/A'}${course.alumnos_count || 0}${course.estado || 'N/A'}
+
+

${course.nombre}

+

Tipo: ${course.tipo}

+

Estado: ${course.estado}

+ ${course.competencias ? `

Competencias: ${course.competencias}

` : ''} +

Profesor: ${course.profesor || 'No asignado'}

+

Fecha: ${course.fecha_inicio} a ${course.fecha_fin}

`; } -// Configuración de formularios y eventos + +function generateDiplomaCard(course) { + return ` +
+

Diploma de ${course.nombre}

+

Fecha: ${course.fecha_fin || 'Completado'}

+

Profesor: ${course.profesor || 'No especificado'}

+ +
`; +} + +// Configuración de eventos dinámicos function setupCourseForm() { + const courseTypeSelect = document.getElementById('courseType'); + if (courseTypeSelect) { + courseTypeSelect.addEventListener('change', function() { + const competencesField = document.getElementById('competencesField'); + if (competencesField) { + competencesField.classList.toggle('oculto', this.value !== 'tratamiento'); + } + }); + } + const courseForm = document.getElementById('courseForm'); if (courseForm) { courseForm.addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); - const jsonData = { - nombre: formData.get('nombre'), - descripcion: formData.get('descripcion'), - tipo: formData.get('tipo'), - profesor_id: getProfesorId() - }; + const jsonData = {}; + formData.forEach((value, key) => jsonData[key] = value); fetch('api/cursos.php', { method: 'POST', @@ -590,7 +377,7 @@ function setupCourseForm() { .then(data => { if (data.success) { alert('Curso creado exitosamente'); - showSection('courses'); // Recargar la sección + showSection('courses'); } else { alert('Error al crear el curso'); } @@ -600,209 +387,54 @@ function setupCourseForm() { } } -function setupStudentForm() { - const studentForm = document.getElementById('studentForm'); - if (studentForm) { - studentForm.addEventListener('submit', function(e) { - e.preventDefault(); - const formData = new FormData(this); - const jsonData = { - nombre: formData.get('nombre'), - email: formData.get('email'), - telefono: formData.get('telefono') - }; - - fetch('api/alumnos.php', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(jsonData) - }) - .then(response => response.json()) - .then(data => { - if (data.success) { - alert('Alumno registrado exitosamente'); - showSection('students'); // Recargar la sección - } else { - alert('Error al registrar al alumno'); - } - }) - .catch(error => console.error('Error:', error)); - }); - } -} - function setupCourseSearch() { - const searchBtn = document.getElementById('searchCourseBtn'); - const searchInput = document.getElementById('courseSearch'); - - if (searchBtn && searchInput) { - searchBtn.addEventListener('click', searchCourses); - searchInput.addEventListener('keypress', function(e) { - if (e.key === 'Enter') searchCourses(); - }); - } -} - -function setupStudentSearch() { - const searchBtn = document.getElementById('searchStudentBtn'); - const searchInput = document.getElementById('studentSearch'); - - if (searchBtn && searchInput) { - searchBtn.addEventListener('click', searchStudents); - searchInput.addEventListener('keypress', function(e) { - if (e.key === 'Enter') searchStudents(); - }); - } -} - -function searchCourses() { - const term = document.getElementById('courseSearch').value.toLowerCase(); - - fetch(`api/cursos.php?profesor_id=${getProfesorId()}`) - .then(response => response.json()) - .then(courses => { - const filtered = courses.filter(course => - course.nombre.toLowerCase().includes(term) || - course.tipo.toLowerCase().includes(term) || - course.estado.toLowerCase().includes(term) + const searchButton = document.getElementById('searchButton'); + if (searchButton) { + searchButton.addEventListener('click', function() { + const searchTerm = document.getElementById('courseSearch').value.toLowerCase(); + const courses = window.userCourses || []; + const filteredCourses = courses.filter(course => + course.nombre.toLowerCase().includes(searchTerm) || + (course.profesor && course.profesor.toLowerCase().includes(searchTerm)) ); - document.getElementById('coursesTableBody').innerHTML = generateCoursesTableRows(filtered); - }) - .catch(error => console.error('Error:', error)); -} - -function searchStudents() { - const term = document.getElementById('studentSearch').value.toLowerCase(); - - fetch('api/alumnos.php') - .then(response => response.json()) - .then(students => { - const filtered = students.filter(student => - student.nombre.toLowerCase().includes(term) || - student.email.toLowerCase().includes(term) || - (student.telefono && student.telefono.toLowerCase().includes(term)) - ); - - document.getElementById('studentsTableBody').innerHTML = generateStudentsTableRows(filtered); - }) - .catch(error => console.error('Error:', error)); -} - -function renderStudentsTable(students) { - const tbody = document.getElementById('studentsTableBody'); - if (tbody) { - tbody.innerHTML = generateStudentsTableRows(students); - } -} - -function setupDiplomaActions() { - // Los eventos se manejan directamente con onclick en los botones -} - -// Funciones de acciones -function editCourse(courseId) { - // Implementar lógica de edición - alert(`Editar curso con ID: ${courseId}`); -} - -function deleteCourse(courseId) { - if (confirm('¿Estás seguro de eliminar este curso?')) { - fetch(`api/cursos.php?id=${courseId}`, { - method: 'DELETE' - }) - .then(response => response.json()) - .then(data => { - if (data.success) { - showSection('courses'); // Recargar la sección - } else { - alert('Error al eliminar el curso'); + const courseList = document.querySelector('.course-list'); + if (courseList) { + courseList.innerHTML = filteredCourses.length > 0 ? + filteredCourses.map(course => generateCourseCard(course)).join('') : + '

No se encontraron cursos que coincidan con la búsqueda.

'; } - }) - .catch(error => console.error('Error:', error)); - } -} - -function editStudent(studentId) { - // Implementar lógica de edición - alert(`Editar alumno con ID: ${studentId}`); -} - -function deleteStudent(studentId) { - if (confirm('¿Estás seguro de eliminar este alumno?')) { - fetch(`api/alumnos.php?id=${studentId}`, { - method: 'DELETE' - }) - .then(response => response.json()) - .then(data => { - if (data.success) { - showSection('students'); // Recargar la sección - } else { - alert('Error al eliminar el alumno'); - } - }) - .catch(error => console.error('Error:', error)); - } -} - -function resendDiploma(diplomaId) { - fetch(`api/diplomas.php?action=resend&id=${diplomaId}`) - .then(response => response.json()) - .then(data => { - if (data.success) { - alert('Diploma reenviado exitosamente'); - } else { - alert('Error al reenviar el diploma'); - } - }) - .catch(error => console.error('Error:', error)); -} - -function downloadDiploma(diplomaId) { - window.open(`certificado.php?diploma_id=${diplomaId}`, '_blank'); -} - -// Función para obtener el ID del profesor desde la sesión -function getProfesorId() { - // En una implementación real, esto debería venir de la sesión - // Esto es solo un ejemplo temporal - return 1; -} -function getCourseTypeClass(type) { - const types = { - 'inyeccion': 'type-inyeccion', - 'pildora': 'type-pildora', - 'tratamiento': 'type-tratamiento' - }; - return types[type] || ''; -} - -// Funciones globales para usar en onclick -window.editCourse = editCourse; -window.deleteCourse = deleteCourse; -window.editStudent = editStudent; -window.deleteStudent = deleteStudent; -window.resendDiploma = resendDiploma; -window.downloadDiploma = downloadDiploma; - -//Diplomas -function downloadDiploma(codigo) { - window.open(`certificado.php?codigo=${codigo}`, '_blank'); -} - -// Función para reenviar diploma -function resendDiploma(codigo) { - fetch(`api/diplomas.php?action=resend&codigo=${codigo}`) - .then(response => response.json()) - .then(data => { - if (data.success) { - alert('Diploma reenviado exitosamente'); - } else { - alert('Error: ' + (data.error || 'No se pudo reenviar el diploma')); - } - }) - .catch(error => { - console.error('Error:', error); - alert('Error al reenviar el diploma'); }); + } +} + +function setupDiplomaDownloads() { + document.querySelectorAll('.download-btn').forEach(btn => { + btn.addEventListener('click', function() { + + + // Mostrar mensaje de carga + const originalText = this.innerHTML; + this.innerHTML = 'Generando diploma...'; + this.disabled = true; + + // Abrir en nueva pestaña en lugar de usar fetch + window.open(`certificado.php`, '_blank'); + + // Restaurar botón después de un breve retraso + setTimeout(() => { + this.innerHTML = originalText; + this.disabled = false; + }, 2000); + }); + }); +} + +// Funciones de secciones no implementadas (para completar) +function loadAdminStudents(container) { + container.innerHTML = '

Gestión de Estudiantes

Sección en desarrollo

'; +} + +function loadProfileSection(container) { + container.innerHTML = '

Perfil de Usuario

Sección en desarrollo

'; } \ No newline at end of file diff --git a/dashboard.php b/dashboard.php index 414e581..6121c78 100644 --- a/dashboard.php +++ b/dashboard.php @@ -2,7 +2,7 @@ include 'includes/config.php'; redirect_if_not_logged_in(); -$profesor = $_SESSION['profesor']; +$user = $_SESSION['user']; ?> @@ -13,49 +13,108 @@ $profesor = $_SESSION['profesor']; - +

DiploMaster

-
- +
+
-
-
-

Bienvenido

-

Este es tu panel de gestión de DiploMaster

-
-

Resumen:

-

0 cursos activos

-

0 alumnos registrados

-

0 diplomas emitidos

+ + +
+
+

Panel de Administración

+

Bienvenido al sistema de gestión de DiploMaster

+
+

Estadísticas:

+

0 cursos activos

+

0 estudiantes registrados

+

0 diplomas emitidos

+
-
+ +
+ +
+ +
+ +
+ + +
+
+

Bienvenido

+

Este es tu panel de control en DiploMaster

+
+

Resumen:

+

0 cursos registrados

+

0 diplomas disponibles

+
+
+ +
+

Mis Cursos Recientes

+
+ + +
+
+ + + + + + + + + + + + +
NombreFecha InicioFecha FinAcciones
+ +
+
+
+ +
+ +
+ +
+ +
+ -
- -
- -
- -
- -
+ +
diff --git a/includes/config.php b/includes/config.php index 0ab85c9..930bb62 100644 --- a/includes/config.php +++ b/includes/config.php @@ -21,7 +21,7 @@ try { } function is_logged_in() { - return isset($_SESSION['profesor']); + return isset($_SESSION['user']); } function redirect_if_not_logged_in() { diff --git a/index.php b/index.php index cda4885..73ec632 100644 --- a/index.php +++ b/index.php @@ -17,14 +17,14 @@

DiploMaster

-

Sistema de gestión de diplomas para profesores

+

Bienvenido al sistema de diplomas

- +
@@ -40,6 +40,11 @@ + +
diff --git a/sql/diplomaster (1).sql b/sql/diplomaster (1).sql index a1a759c..89c3975 100644 --- a/sql/diplomaster (1).sql +++ b/sql/diplomaster (1).sql @@ -1,57 +1,157 @@ --- Crear la base de datos -CREATE DATABASE IF NOT EXISTS diplomaster; -USE diplomaster; +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Servidor: 127.0.0.1 +-- Tiempo de generación: 05-05-2025 a las 04:15:28 +-- Versión del servidor: 10.4.32-MariaDB +-- Versión de PHP: 8.2.12 --- Tabla de usuarios (profesores) -CREATE TABLE `usuarios` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `nombre` VARCHAR(100) NOT NULL, - `email` VARCHAR(100) UNIQUE NOT NULL, - `password` VARCHAR(255) NOT NULL, - `aprobado` BOOLEAN NOT NULL DEFAULT 0, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Base de datos: `diplomaster` +-- + +-- -------------------------------------------------------- + +-- +-- Estructura de tabla para la tabla `cursos` +-- --- Tabla de cursos (cada profesor crea sus cursos) CREATE TABLE `cursos` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `nombre` VARCHAR(100) NOT NULL, - `descripcion` VARCHAR(250) DEFAULT NULL, - `estado` ENUM('activo', 'completado', 'archivado') NOT NULL DEFAULT 'activo', - `tipo` ENUM('inyeccion', 'pildora', 'tratamiento') NOT NULL, - `profesor_id` INT(11) NOT NULL, - FOREIGN KEY (`profesor_id`) REFERENCES `usuarios`(`id`) ON DELETE CASCADE, - PRIMARY KEY (`id`) + `id` int(11) NOT NULL, + `nombre` varchar(100) NOT NULL, + `tipo` enum('pildora','inyeccion','tratamiento') NOT NULL, + `competencias` text DEFAULT NULL, + `fecha_creacion` timestamp NOT NULL DEFAULT current_timestamp() ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; --- Tabla de alumnos -CREATE TABLE `alumnos` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `nombre` VARCHAR(100) NOT NULL, - `email` VARCHAR(100) UNIQUE NOT NULL, - `telefono` VARCHAR(15) DEFAULT NULL, - PRIMARY KEY (`id`) +-- +-- Volcado de datos para la tabla `cursos` +-- + +INSERT INTO `cursos` (`id`, `nombre`, `tipo`, `competencias`, `fecha_creacion`) VALUES +(1, 'Seguridad Informática', 'tratamiento', 'Análisis de datos, Comunicación efectiva', '2025-05-05 01:27:58'), +(2, 'Introducción a Python', 'pildora', NULL, '2025-05-05 01:27:58'), +(3, 'Machine Learning Avanzado', 'tratamiento', 'Modelado predictivo, Python', '2025-05-05 01:27:58'); + +-- -------------------------------------------------------- + +-- +-- Estructura de tabla para la tabla `usuarios` +-- + +CREATE TABLE `usuarios` ( + `id` int(11) NOT NULL, + `username` varchar(50) NOT NULL, + `password` varchar(255) NOT NULL, + `nombre` varchar(100) NOT NULL, + `email` varchar(100) NOT NULL, + `rol` enum('admin','user') NOT NULL DEFAULT 'user', + `fecha_registro` timestamp NOT NULL DEFAULT current_timestamp() ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; --- Tabla para vincular alumnos con cursos -CREATE TABLE `alumnos_cursos` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `alumno_id` INT(11) NOT NULL, - `curso_id` INT(11) NOT NULL, - `estado` ENUM('cursando', 'aprobado', 'reprobado') NOT NULL DEFAULT 'cursando', - `competencias` TEXT DEFAULT NULL, -- Solo para tratamiento - FOREIGN KEY (`alumno_id`) REFERENCES `alumnos`(`id`) ON DELETE CASCADE, - FOREIGN KEY (`curso_id`) REFERENCES `cursos`(`id`) ON DELETE CASCADE, - PRIMARY KEY (`id`) +-- +-- Volcado de datos para la tabla `usuarios` +-- + +INSERT INTO `usuarios` (`id`, `username`, `password`, `nombre`, `email`, `rol`, `fecha_registro`) VALUES +(1, 'admin', '$2y$10$H3tCRUt444g0jo996uiKXenINy2d84FfuwQhoDBfa3tNblZLtNZpK', 'Administrador', 'admin@diplomaster.com', 'admin', '2025-05-05 01:27:58'), +(2, 'usuario1', '$2y$10$SjyU29E200ax73/m0NTjqe0sMLmpsPBThlIUucGKyxvqh/znHiwh.', 'Juan Pérez', 'juan@example.com', 'user', '2025-05-05 01:27:58'); + +-- -------------------------------------------------------- + +-- +-- Estructura de tabla para la tabla `usuario_cursos` +-- + +CREATE TABLE `usuario_cursos` ( + `id` int(11) NOT NULL, + `usuario_id` int(11) NOT NULL, + `curso_id` int(11) NOT NULL, + `estado` enum('En progreso','Aprobado','Completado') NOT NULL DEFAULT 'En progreso', + `fecha_inicio` date DEFAULT NULL, + `fecha_fin` date DEFAULT NULL, + `profesor` varchar(100) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; --- Tabla de diplomas -CREATE TABLE `diplomas` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `alumno_curso_id` INT(11) NOT NULL, - `fecha_emision` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `competencias` TEXT DEFAULT NULL, - FOREIGN KEY (`alumno_curso_id`) REFERENCES `alumnos_cursos`(`id`) ON DELETE CASCADE, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +-- +-- Volcado de datos para la tabla `usuario_cursos` +-- +INSERT INTO `usuario_cursos` (`id`, `usuario_id`, `curso_id`, `estado`, `fecha_inicio`, `fecha_fin`, `profesor`) VALUES +(1, 2, 1, 'Aprobado', '2023-01-15', '2023-04-20', 'Dra. Ana López'), +(2, 2, 2, 'En progreso', '2023-05-10', NULL, 'Prof. Carlos Ruiz'); + +-- +-- Índices para tablas volcadas +-- + +-- +-- Indices de la tabla `cursos` +-- +ALTER TABLE `cursos` + ADD PRIMARY KEY (`id`); + +-- +-- Indices de la tabla `usuarios` +-- +ALTER TABLE `usuarios` + ADD PRIMARY KEY (`id`), + ADD UNIQUE KEY `username` (`username`), + ADD UNIQUE KEY `email` (`email`); + +-- +-- Indices de la tabla `usuario_cursos` +-- +ALTER TABLE `usuario_cursos` + ADD PRIMARY KEY (`id`), + ADD KEY `usuario_id` (`usuario_id`), + ADD KEY `curso_id` (`curso_id`); + +-- +-- AUTO_INCREMENT de las tablas volcadas +-- + +-- +-- AUTO_INCREMENT de la tabla `cursos` +-- +ALTER TABLE `cursos` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +-- +-- AUTO_INCREMENT de la tabla `usuarios` +-- +ALTER TABLE `usuarios` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; + +-- +-- AUTO_INCREMENT de la tabla `usuario_cursos` +-- +ALTER TABLE `usuario_cursos` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; + +-- +-- Restricciones para tablas volcadas +-- + +-- +-- Filtros para la tabla `usuario_cursos` +-- +ALTER TABLE `usuario_cursos` + ADD CONSTRAINT `usuario_cursos_ibfk_1` FOREIGN KEY (`usuario_id`) REFERENCES `usuarios` (`id`), + ADD CONSTRAINT `usuario_cursos_ibfk_2` FOREIGN KEY (`curso_id`) REFERENCES `cursos` (`id`); +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;