Explora
Cursos
Catálogo siempre actualizado
= $row["updated_at"] ?>
¡Exacto! Separar los videos y los cuestionarios por temario es una excelente decisión tanto por rendimiento como por estructura lógica. Te explico por qué y cómo podrías modelarlo:
📦 Estructura recomendada (continuando con la normalización):
Tabla: temario
temario_id (PK)
curso_id (FK a cursos)
titulo
descripcion
orden (para definir el orden del temario dentro del curso)
duracion_estimada (opcional, por ejemplo: 10 min)
Tabla: videos
video_id (PK)
temario_id (FK a temario)
titulo
url_video o archivo_ruta
duracion
descripcion (opcional)
Tabla: cuestionarios
cuestionario_id (PK)
temario_id (FK a temario)
titulo
descripcion
tiempo_limite
intentos_maximos
Tabla: preguntas
pregunta_id (PK)
cuestionario_id (FK a cuestionarios)
texto_pregunta
tipo (por ejemplo: opción múltiple, verdadero/falso, etc.)
Tabla: respuestas
respuesta_id (PK)
pregunta_id (FK a preguntas)
texto_respuesta
es_correcta (boolean)
CREATE TABLE cursos (
curso_id INT AUTO_INCREMENT PRIMARY KEY,
curso_titulo VARCHAR(255) NOT NULL,
descripcion TEXT,
categoria_id INT NOT NULL,
detalle_id INT,
empresa_id INT NOT NULL,
fecha_inicio DATE,
fecha_fin DATE,
imagen VARCHAR(255),
precio DECIMAL(10, 2) DEFAULT 0.00,
estado ENUM('activo', 'inactivo') DEFAULT 'activo',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_curso_titulo (curso_titulo),
INDEX idx_categoria_id (categoria_id),
INDEX idx_empresa_id (empresa_id),
FOREIGN KEY (categoria_id) REFERENCES categorias(categoria_id),
FOREIGN KEY (detalle_id) REFERENCES detalles_curso(detalle_id),
FOREIGN KEY (empresa_id) REFERENCES empresas(empresa_id)
);
CREATE TABLE categorias (
categoria_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_categoria VARCHAR(100) NOT NULL UNIQUE,
descripcion TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE detalles_curso (
detalle_id INT AUTO_INCREMENT PRIMARY KEY,
objetivos TEXT,
temario TEXT,
requisitos TEXT,
beneficios TEXT,
duracion VARCHAR(50),
recursos TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE empresas (
empresa_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_empresa VARCHAR(255) NOT NULL UNIQUE,
rfc VARCHAR(20),
direccion TEXT,
contacto VARCHAR(255) NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE promotorias (
promotoria_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_promotoria VARCHAR(255) NOT NULL UNIQUE,
empresa_id INT,
contacto VARCHAR(255) NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE puestos (
puesto_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_puesto VARCHAR(255) NOT NULL UNIQUE,
);
CREATE TABLE roles (
rol_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_rol VARCHAR(255) NOT NULL UNIQUE,
);
CREATE TABLE usuarios (
usuario_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_completo VARCHAR(255),
rfc VARCHAR(25) UNIQUE,
promotoria_id INT,
curp VARCHAR(25) UNIQUE,
puesto_id INT,
estado_lugar VARCHAR(250),
status ENUM('ACTIVO', 'INACTIVO') DEFAULT 'ACTIVO',
email VARCHAR(150) UNIQUE,
password VARCHAR(250),
rol_id INT,
fecha_ingreso DATE NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (promotoria_id) REFERENCES promotorias(promotoria_id),
FOREIGN KEY (puesto_id) REFERENCES puestos(puesto_id),
FOREIGN KEY (rol_id) REFERENCES roles(rol_id),
);
CREATE TABLE cursos_usuario (
curso_usuario_ id INT AUTO_INCREMENT PRIMARY KEY,
curso_id INT,
usuario_id INT,
fecha_inscripcion DATETIME DEFAULT CURRENT_TIMESTAMP,
fecha_finalizacion DATETIME,
estatus ENUM('inscrito', 'en_progreso', 'finalizado', 'cancelado') DEFAULT 'inscrito',
calificacion DECIMAL(4,2),
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id),
FOREIGN KEY (usuario_id) REFERENCES usuarios(usuario_id),
INDEX idx_usuario_id (usuario_id),
INDEX idx_curso_id (curso_id)
);
CREATE TABLE calificaciones (
calificacion_id INT AUTO_INCREMENT PRIMARY KEY,
curso_id INT,
usuario_id INT,
puntuacion INT CHECK (puntuacion BETWEEN 1 AND 5),
comentario TEXT,
fecha DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id),
FOREIGN KEY (usuario_id) REFERENCES usuarios(usuario_id)
);
-----------------------------------------------------------
CREATE TABLE cuestionarios (
cuestionario_id INT AUTO_INCREMENT PRIMARY KEY,
curso_id INT,
titulo VARCHAR(255) NOT NULL,
descripcion TEXT,
fecha_creacion DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id)
);
CREATE TABLE preguntas (
pregunta_id INT AUTO_INCREMENT PRIMARY KEY,
cuestionario_id INT,
texto_pregunta TEXT NOT NULL,
tipo ENUM('opcion_multiple', 'verdadero_falso', 'respuesta_abierta') NOT NULL,
FOREIGN KEY (cuestionario_id) REFERENCES cuestionarios(cuestionario_id)
);
CREATE TABLE respuestas (
respuesta_id INT AUTO_INCREMENT PRIMARY KEY,
pregunta_id INT,
texto_respuesta TEXT NOT NULL,
es_correcta BOOLEAN DEFAULT FALSE,
FOREIGN KEY (pregunta_id) REFERENCES preguntas(pregunta_id)
);
CREATE TABLE respuestas_usuario (
respuesta_usuario_id INT AUTO_INCREMENT PRIMARY KEY,
usuario_id INT,
pregunta_id INT,
respuesta_id INT NULL, -- si es opción múltiple / verdadero-falso
respuesta_texto TEXT NULL, -- si es abierta
fecha_respuesta DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (usuario_id) REFERENCES usuarios(usuario_id),
FOREIGN KEY (pregunta_id) REFERENCES preguntas(pregunta_id),
FOREIGN KEY (respuesta_id) REFERENCES respuestas(respuesta_id)
);
---------------------------------------------
contraseña
Promotoria2025
---------------------------------------------TBL_DETALLESCURSO-----------------------------
Desglose de la Tabla detalles_curso
detalle_id (INT, AUTO_INCREMENT, PRIMARY KEY):
Identificador único para cada conjunto de detalles del curso.
AUTO_INCREMENT genera automáticamente valores únicos.
PRIMARY KEY asegura que no haya detalles duplicados.
curso_id (INT, UNIQUE, NOT NULL, FOREIGN KEY):
Clave externa que conecta esta tabla con la tabla cursos.
UNIQUE es crucial para la relación 1:1: cada curso tiene solo un conjunto de detalles.
NOT NULL garantiza que cada detalle esté asociado a un curso.
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id) establece la relación con la clave primaria curso_id en la tabla cursos.
objetivos_aprendizaje (TEXT):
Descripción detallada de lo que los estudiantes podrán hacer después del curso.
audiencia_objetivo (VARCHAR(255)):
Grupo de empleados o personas a quienes está dirigido el curso.
requisitos_previos (TEXT):
Conocimientos, habilidades o cursos necesarios antes de tomar este curso.
duracion (VARCHAR(100)):
Tiempo que dura el curso (por ejemplo, "5 días", "40 horas").
modalidad (VARCHAR(50)):
Formato del curso (por ejemplo, "En línea", "Presencial", "Híbrido").
materiales_curso (TEXT):
Lista o descripción de los materiales proporcionados a los estudiantes.
evaluacion (VARCHAR(255)):
Métodos utilizados para evaluar el aprendizaje de los estudiantes.
instructor (VARCHAR(255)):
Nombre del instructor o facilitador del curso.
ubicacion (VARCHAR(255)):
Lugar donde se imparte el curso (si es presencial) o plataforma (si es en línea).
horario_sesiones (VARCHAR(255)):
Días y horas de las sesiones del curso.
created_at (DATETIME, DEFAULT CURRENT_TIMESTAMP):
Fecha y hora en que se creó el registro.
DEFAULT CURRENT_TIMESTAMP establece la fecha y hora actual por defecto.
updated_at (DATETIME, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP):
Fecha y hora en que se actualizó el registro por última vez.
ON UPDATE CURRENT_TIMESTAMP actualiza automáticamente la fecha y hora cuando se modifica el registro.
--------------------------------------------TABLAS YA APROBADAS ---------------------------------------------
SQL: SELECT c.*
FROM cursos c
JOIN cursos_promotorias cp ON c.curso_id = cp.curso_id
WHERE cp.promotoria_id = [promotoria_id_deseada];
CREATE TABLE empresas (
empresa_id INT AUTO_INCREMENT PRIMARY KEY,
nombre_empresa VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE promotorias (
promotoria_id INT AUTO_INCREMENT PRIMARY KEY,
empresa_id INT NOT NULL,
nombre_promotoria VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (empresa_id) REFERENCES empresas(empresa_id)
);
CREATE TABLE cursos_promotorias (
curso_promotoria_id INT AUTO_INCREMENT PRIMARY KEY,
curso_id INT NOT NULL,
promotoria_id INT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id),
FOREIGN KEY (promotoria_id) REFERENCES promotorias(promotoria_id),
UNIQUE KEY unique_curso_promotoria (curso_id, promotoria_id) -- Asegura que no haya duplicados en la relación
);
CREATE TABLE cuestionarios (
cuestionario_id INT AUTO_INCREMENT PRIMARY KEY,
curso_id INT NOT NULL,
titulo VARCHAR(255) NOT NULL,
descripcion TEXT,
fecha_creacion DATETIME DEFAULT CURRENT_TIMESTAMP,
fecha_actualizacion DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id)
);
CREATE TABLE preguntas (
pregunta_id INT AUTO_INCREMENT PRIMARY KEY,
cuestionario_id INT NOT NULL,
texto_pregunta TEXT NOT NULL,
puntaje DECIMAL(5, 2) NOT NULL,
fecha_creacion DATETIME DEFAULT CURRENT_TIMESTAMP,
fecha_actualizacion DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (cuestionario_id) REFERENCES cuestionarios(cuestionario_id)
);
CREATE TABLE opciones_pregunta (
opcion_id INT AUTO_INCREMENT PRIMARY KEY,
pregunta_id INT NOT NULL,
texto_opcion VARCHAR(255) NOT NULL,
es_correcta BOOLEAN DEFAULT FALSE,
FOREIGN KEY (pregunta_id) REFERENCES preguntas(pregunta_id)
);
CREATE TABLE usuarios_cursos (
usuario_curso_id INT AUTO_INCREMENT PRIMARY KEY,
usuario_id INT NOT NULL,
curso_id INT NOT NULL,
fecha_inscripcion DATETIME DEFAULT CURRENT_TIMESTAMP,
progreso DECIMAL(5,2) DEFAULT 0.00, -- Porcentaje de progreso en el curso
estado_curso ENUM('En curso', 'Completado', 'Abandonado') DEFAULT 'En curso',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
calificacion_final DECIMAL(5,2) NULL,
FOREIGN KEY (usuario_id) REFERENCES usuarios(usuario_id),
FOREIGN KEY (curso_id) REFERENCES cursos(curso_id),
UNIQUE KEY unique_usuario_curso (usuario_id, curso_id) -- Evita duplicados
);
CREATE TABLE respuestas_usuario (
respuesta_id INT AUTO_INCREMENT PRIMARY KEY,
usuario_curso_id INT NOT NULL,
pregunta_id INT NOT NULL,
opcion_seleccionada_id INT NOT NULL,
es_correcta BOOLEAN, -- Redundante pero útil para consultas
puntaje_obtenido DECIMAL(5, 2),
fecha_respuesta DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (usuario_curso_id) REFERENCES usuarios_cursos(usuario_curso_id),
FOREIGN KEY (pregunta_id) REFERENCES preguntas(pregunta_id),
FOREIGN KEY (opcion_seleccionada_id) REFERENCES opciones_pregunta(opcion_id)
);
------------------------------------------------------------------------------------------------
FUNCION PARA CONVERTR LA FECHA EN FORMATO 2025-04-10 EN 10 DE ABRIL 2025
function formatearFecha(fechaString) {
/**
* Convierte una cadena de fecha en formato 'YYYY-MM-DD' a 'DD de Mes de AAAA'.
*
* @param {string} fechaString La cadena de fecha a convertir (ej: '2025-05-12').
* @returns {string} La cadena de fecha formateada (ej: '12 de Mayo de 2025') o un mensaje de error.
*/
try {
const fechaObj = new Date(fechaString.replace(/-/g, '/')); // Replace - with / for better parsing
if (isNaN(fechaObj.getTime())) { // Check for invalid date
return "Formato de fecha inválido. Por favor, use AAAA-MM-DD.";
}
const meses = [
"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
];
const dia = fechaObj.getDate();
const mes = meses[fechaObj.getMonth()];
const anio = fechaObj.getFullYear();
return `${dia} de ${mes} de ${anio}`;
} catch (error) {
return "Error al formatear la fecha: " + error.message;
}
}
// Ejemplos de uso:
let fecha = "2025-05-12";
let fechaFormateada = formatearFecha(fecha);
console.log(`Fecha original: ${fecha}`);
console.log(`Fecha formateada: ${fechaFormateada}`);
fecha = "2025-10-01";
fechaFormateada = formatearFecha(fecha);
console.log(`Fecha original: ${fecha}`);
console.log(`Fecha formateada: ${fechaFormateada}`);
fecha = "2025/10/01"; // Formato inválido - pero parseado con el replace
fechaFormateada = formatearFecha(fecha);
console.log(`Fecha original: ${"2025/10/01"}`);
console.log(`Fecha formateada: ${fechaFormateada}`);
fecha = "invalid-date"; // Realmente inválido
fechaFormateada = formatearFecha(fecha);
console.log(`Fecha original: ${"invalid-date"}`);
console.log(`Fecha formateada: ${fechaFormateada}`);
//////////////////////////////////////////////////////////////////////////////////////////ASIGANACION DE promotorias