diff --git a/api/alumnos.php b/api/alumnos.php
new file mode 100644
index 0000000..fe00c0d
--- /dev/null
+++ b/api/alumnos.php
@@ -0,0 +1,64 @@
+ '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 9d7ce17..83de32e 100644
--- a/api/cursos.php
+++ b/api/cursos.php
@@ -9,44 +9,91 @@ if (!is_logged_in()) {
}
$method = $_SERVER['REQUEST_METHOD'];
-$user = $_SESSION['user'];
+$profesorId = $_SESSION['profesor']['id'] ?? null;
switch ($method) {
case 'GET':
- 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']]);
+ 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()]);
}
- echo json_encode($stmt->fetchAll());
break;
case 'POST':
- if ($user['rol'] !== 'admin') {
- http_response_code(403);
- echo json_encode(['error' => 'Acceso no autorizado']);
+ $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']);
exit;
}
- $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()]);
+ 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()]);
+ }
break;
default:
diff --git a/api/diploma.php b/api/diploma.php
new file mode 100644
index 0000000..5450f13
--- /dev/null
+++ b/api/diploma.php
@@ -0,0 +1,78 @@
+ '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 b62b8f4..9906b9c 100644
--- a/api/login.php
+++ b/api/login.php
@@ -2,80 +2,57 @@
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;
}
-// Obtener datos del formulario
-$username = trim($_POST['username'] ?? '');
+$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
-// Validaciones básicas
-if (empty($username) || empty($password)) {
- echo json_encode(['success' => false, 'message' => 'Usuario y contraseña son requeridos']);
+if (empty($email) || empty($password)) {
+ echo json_encode(['success' => false, 'message' => 'Email y contraseña son requeridos']);
exit;
}
try {
- // Buscar usuario en la base de datos
- $stmt = $pdo->prepare("SELECT * FROM usuarios WHERE username = ?");
- $stmt->execute([$username]);
- $user = $stmt->fetch();
+ // Buscar profesor en la base de datos
+ $stmt = $pdo->prepare("SELECT * FROM usuarios WHERE email = ? AND aprobado = 1");
+ $stmt->execute([$email]);
+ $profesor = $stmt->fetch();
- if (!$user) {
- echo json_encode(['success' => false, 'message' => 'Usuario no encontrado']);
+ if (!$profesor) {
+ echo json_encode(['success' => false, 'message' => 'Profesor no encontrado o no aprobado']);
exit;
}
- // Verificar contraseña
- if (!password_verify($password, $user['password'])) {
+ if (!password_verify($password, $profesor['password'])) {
echo json_encode(['success' => false, 'message' => 'Contraseña incorrecta']);
exit;
}
- // 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
+ // Configurar sesión de profesor
+ $_SESSION['profesor'] = [
+ 'id' => $profesor['id'],
+ 'nombre' => $profesor['nombre'],
+ 'email' => $profesor['email']
];
- // Respuesta exitosa
echo json_encode([
'success' => true,
'redirect' => 'dashboard.php',
- 'user' => [
- 'id' => $user['id'],
- 'nombre' => $user['nombre'],
- 'rol' => $user['rol']
+ 'profesor' => [
+ 'id' => $profesor['id'],
+ 'nombre' => $profesor['nombre']
]
]);
} 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 d106f83..2daf94d 100644
--- a/assets/css/styles.css
+++ b/assets/css/styles.css
@@ -566,3 +566,36 @@ 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 6b93519..38b160d 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') || document.body.classList.contains('user')) {
+ if (document.body.classList.contains('admin')) {
initializeDashboard();
}
});
@@ -47,126 +47,126 @@ function initializeDashboard() {
function setupSidebarNavigation() {
document.querySelectorAll('.sidebar-menu li').forEach(item => {
- item.addEventListener('click', function() {
- const section = this.getAttribute('data-section');
- showSection(section);
- });
+ if (item.getAttribute('data-section')) {
+ item.addEventListener('click', function() {
+ const section = this.getAttribute('data-section');
+ showSection(section);
+ });
+ }
});
}
function loadInitialData() {
- 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));
+ // 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');
+ });
}
-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 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 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;
+function updateProfessorStats(courses, students, diplomas) {
+ const profesorId = getProfesorId();
- // Mostrar los primeros 5 cursos en el dashboard
- renderDashboardCourses(courses.slice(0, 5));
- setupDashboardPagination(courses);
- setupDashboardSearch();
+ // 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));
}
-function renderDashboardCourses(courses) {
- const tbody = document.getElementById('dashboard-courses-body');
- if (!tbody) return;
+
+function updateRecentDiplomas(diplomas) {
+ const tableBody = document.getElementById('diplomas-table-body');
+ if (!tableBody) return;
- tbody.innerHTML = courses.map(course => `
+ tableBody.innerHTML = diplomas.map(diploma => `
- ${course.nombre} |
- ${course.fecha_inicio || '-'} |
- ${course.fecha_fin || '-'} |
+ ${diploma.alumno_nombre} |
+ ${diploma.curso_nombre} |
+ ${new Date(diploma.fecha_emision).toLocaleDateString()} |
- ${course.estado === 'Aprobado' ?
- `` :
- 'No disponible'}
+
|
`).join('');
+}
+function updateCoursesTable(courses) {
+ const tableBody = document.getElementById('courses-table-body');
+ if (!tableBody) return;
- // 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');
- });
- });
+ tableBody.innerHTML = courses.map(course => `
+
+ ${course.nombre} |
+ ${course.tipo} |
+ ${course.alumnos_count || 0} |
+ ${course.estado} |
+
+ `).join('');
}
-function setupDashboardPagination(allCourses) {
- let currentPage = 1;
- const perPage = 5;
- const totalPages = Math.ceil(allCourses.length / perPage);
+function updateDashboardStats(courses, students, diplomas) {
+ const activeCourses = courses.filter(c => c.estado === 'activo');
- 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('active-courses-count')) {
+ document.getElementById('active-courses-count').textContent = activeCourses.length;
}
- document.getElementById('prev-page')?.addEventListener('click', () => {
- if (currentPage > 1) {
- currentPage--;
- updatePagination();
- }
- });
+ if (document.getElementById('students-count')) {
+ document.getElementById('students-count').textContent = students.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();
- }
- });
+ if (document.getElementById('diplomas-count')) {
+ document.getElementById('diplomas-count').textContent = diplomas.length;
}
}
+
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,21 +184,22 @@ function showSection(sectionId, isInitialLoad = false) {
} else {
loadDynamicContent(sectionId, sectionElement);
}
- }
}
}
+}
function updateActiveMenu(sectionId) {
document.querySelectorAll('.sidebar-menu li').forEach(li => {
li.classList.remove('active');
});
- document.querySelector(`.sidebar-menu li[data-section="${sectionId}"]`).classList.add('active');
+
+ const activeItem = document.querySelector(`.sidebar-menu li[data-section="${sectionId}"]`);
+ if (activeItem) {
+ activeItem.classList.add('active');
+ }
}
function getSectionElement(sectionId) {
- if (sectionId === 'dashboard') {
- return document.getElementById('dashboard-content');
- }
return document.getElementById(`${sectionId}-content`);
}
@@ -210,66 +211,133 @@ function toggleSections(activeSection) {
}
function loadDynamicContent(sectionId, container) {
- // Mostrar loader mientras se carga
container.innerHTML = 'Cargando...
';
switch(sectionId) {
+ case 'dashboard':
+ loadDashboardContent(container);
+ break;
case 'courses':
- loadAdminCourses(container);
+ loadProfessorCourses(container);
break;
case 'students':
- loadAdminStudents(container);
- break;
- case 'my-courses':
- loadUserCourses(container);
+ loadStudentsManagement(container);
break;
case 'diplomas':
- loadUserDiplomas(container);
- break;
- case 'profile':
- loadProfileSection(container);
+ loadDiplomasSection(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 loadAdminCourses(container) {
- fetch('api/cursos.php')
+function loadProfessorCourses(container) {
+ fetch(`api/cursos.php?profesor_id=${getProfesorId()}`)
.then(response => response.json())
.then(courses => {
container.innerHTML = `
-
Gestión de Cursos
+
Mis Cursos
Lista de Cursos
-
- ${generateCoursesList(courses)}
+
+
+
+
+
+
+
+
+ Nombre |
+ Tipo |
+ Estado |
+ Acciones |
+
+
+
+ ${generateCoursesTableRows(courses)}
+
+
`;
setupCourseForm();
+ setupCourseSearch();
})
.catch(error => {
container.innerHTML = '
Error al cargar los cursos
';
@@ -277,96 +345,241 @@ function loadAdminCourses(container) {
});
}
-function loadUserCourses(container) {
- const courses = window.userCourses || [];
-
+function loadStudentsManagement(container) {
container.innerHTML = `
-
Mis Cursos
-
-
-
-
-
- ${courses.length > 0 ?
- courses.map(course => generateCourseCard(course)).join('') :
- '
No tienes cursos registrados.
'}
-
-
`;
-
- setupCourseSearch();
-}
-
-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 => `
-
+
+
Lista de Alumnos
+
+
+
+
+
+
+
+
+ Nombre |
+ Email |
+ Teléfono |
+ Acciones |
+
+
+
+
+
+
+
+
`;
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+ Alumno |
+ Email |
+ Curso |
+ Tipo |
+ Fecha |
+ Código |
+ Acciones |
+
+
+
+ ${data.data.map(diploma => `
+
+ ${diploma.alumno_nombre} |
+ ${diploma.alumno_email} |
+ ${diploma.curso_nombre} |
+ ${diploma.curso_tipo} |
+ ${diploma.fecha_formateada} |
+ ${diploma.codigo_unico} |
+
+
+
+ |
+
+ `).join('')}
+
+
+
+
+
`;
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ container.innerHTML = `
+
+
Error al cargar diplomas
+
${error.message}
+
+
`;
+ });
+}
+
+// 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 generateCourseCard(course) {
- return `
-
-
${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}
-
`;
+function generateStudentsTableRows(students) {
+ return students.map(student => `
+
+ ${student.nombre} |
+ ${student.email} |
+ ${student.telefono || '-'} |
+
+
+
+ |
+
+ `).join('');
}
-function generateDiplomaCard(course) {
- return `
-
-
Diploma de ${course.nombre}
-
Fecha: ${course.fecha_fin || 'Completado'}
-
Profesor: ${course.profesor || 'No especificado'}
-
-
`;
+function generateDiplomasTableRows(diplomas) {
+ return diplomas.map(diploma => `
+
+ ${diploma.alumno_nombre} |
+ ${diploma.curso_nombre} |
+ ${new Date(diploma.fecha_emision).toLocaleDateString()} |
+
+
+
+ |
+
+ `).join('');
}
-
-// 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');
- }
- });
- }
+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
';
+ return `
+
+
+
+
+ Nombre |
+ Tipo |
+ Alumnos |
+ Estado |
+
+
+
+ ${courses.map(course => `
+
+ ${course.nombre || 'Sin nombre'} |
+ ${course.tipo || 'N/A'} |
+ ${course.alumnos_count || 0} |
+ ${course.estado || 'N/A'} |
+
+ `).join('')}
+
+
+
`;
+}
+// Configuración de formularios y eventos
+function setupCourseForm() {
const courseForm = document.getElementById('courseForm');
if (courseForm) {
courseForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
- const jsonData = {};
- formData.forEach((value, key) => jsonData[key] = value);
+ const jsonData = {
+ nombre: formData.get('nombre'),
+ descripcion: formData.get('descripcion'),
+ tipo: formData.get('tipo'),
+ profesor_id: getProfesorId()
+ };
fetch('api/cursos.php', {
method: 'POST',
@@ -377,7 +590,7 @@ function setupCourseForm() {
.then(data => {
if (data.success) {
alert('Curso creado exitosamente');
- showSection('courses');
+ showSection('courses'); // Recargar la sección
} else {
alert('Error al crear el curso');
}
@@ -387,54 +600,209 @@ function setupCourseForm() {
}
}
-function setupCourseSearch() {
- 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))
- );
+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')
+ };
- 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.
';
- }
+ 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 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);
+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();
});
- });
+ }
}
-// Funciones de secciones no implementadas (para completar)
-function loadAdminStudents(container) {
- container.innerHTML = '
Gestión de Estudiantes
Sección en desarrollo
';
+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 loadProfileSection(container) {
- container.innerHTML = '
Perfil de Usuario
Sección en desarrollo
';
+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)
+ );
+
+ 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');
+ }
+ })
+ .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');
+ });
}
\ No newline at end of file
diff --git a/dashboard.php b/dashboard.php
index 6121c78..414e581 100644
--- a/dashboard.php
+++ b/dashboard.php
@@ -2,7 +2,7 @@
include 'includes/config.php';
redirect_if_not_logged_in();
-$user = $_SESSION['user'];
+$profesor = $_SESSION['profesor'];
?>
@@ -13,108 +13,49 @@ $user = $_SESSION['user'];
-
+