Compare commits
No commits in common. "main" and "backend" have entirely different histories.
|
@ -0,0 +1 @@
|
|||
.idea/
|
46
README.md
46
README.md
|
@ -1,46 +0,0 @@
|
|||
# Sistema de Registro y Gestión de Candidatos - LANIA
|
||||
|
||||
Este proyecto es una plataforma web desarrollada para automatizar el registro de usuarios en el **Centro de Certificación LANIA**, con el objetivo de optimizar la recolección de datos demográficos y de satisfacción de los candidatos, así como proporcionar herramientas de análisis al área de administración.
|
||||
|
||||
## ✨ Descripción General
|
||||
|
||||
La aplicación se compone de dos partes principales:
|
||||
|
||||
- **Web App**: Interfaz gráfica donde candidatos pueden llenar formularios y administradores pueden gestionar usuarios, candidatos y consultar datos analíticos.
|
||||
- **API REST**: Servicio backend que expone endpoints para la gestión de candidatos, autenticación vía OAuth2 y exportación de datos en múltiples formatos (JSON, CSV, Excel).
|
||||
|
||||
## 🎯 Propósito
|
||||
|
||||
- Automatizar el proceso de registro y seguimiento de candidatos.
|
||||
- Recolectar datos clave para la toma de decisiones institucionales.
|
||||
- Facilitar la gestión de usuarios y candidatos por parte del personal de LANIA.
|
||||
- Brindar herramientas visuales de análisis mediante un dashboard dinámico.
|
||||
|
||||
## 👥 Tipos de Usuario
|
||||
|
||||
- **Candidato**: Registra sus datos mediante formularios web.
|
||||
- **Administrador LANIA**: Visualiza, filtra y exporta datos, administra usuarios y accede al dashboard analítico.
|
||||
|
||||
## 🛠 Tecnologías Utilizadas
|
||||
|
||||
| Tecnología | Propósito |
|
||||
|-------------------|------------------------------------------------|
|
||||
| PHP (MVC) | Lógica del servidor y API REST |
|
||||
| JavaScript | Interacción dinámica en el cliente |
|
||||
| MySQL | Almacenamiento de datos |
|
||||
| Chart.js | Visualización de datos en gráficos |
|
||||
| OAuth2 | Autenticación y autorización segura |
|
||||
| HTML/CSS | Maquetación y estilos de la interfaz |
|
||||
| INEGI BD externa | Validación geográfica de estado/municipio |
|
||||
|
||||
## 📂 Funcionalidades Principales
|
||||
|
||||
- Dashboard con métricas visuales.
|
||||
- Formularios dinámicos de registro.
|
||||
- Control y gestión de candidatos.
|
||||
- Gestión de usuarios administradores.
|
||||
- Interfaz para consulta y exportación de datos vía API.
|
||||
|
||||
## ℹ️ Documentación de API
|
||||
En el siguiente enlace se encuentra el archivo .yaml de la documentación de la API que puede ser visualizado con Swagger Editor:
|
||||
https://uvmx-my.sharepoint.com/:u:/g/personal/zs22016079_estudiantes_uv_mx/EU0hmEyOj29LgbF9R8CStdcBVLkB11Ik2SfwYQg9fWKXtw?e=Kz3nci
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . "/../../config/Database.php";
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['n'])){
|
||||
$numero_inserts = intval($_GET['n']);
|
||||
|
||||
if ($numero_inserts <= 0) {
|
||||
echo "El número de inserts debe ser un entero positivo.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Configuración de rangos para campos aleatorios
|
||||
$id_examen_min = 1;
|
||||
$id_examen_max = 15;
|
||||
$id_tipo_id_min = 1;
|
||||
$id_tipo_id_max = 5;
|
||||
$id_rango_edad_min = 1;
|
||||
$id_rango_edad_max = 7;
|
||||
$id_genero_min = 1;
|
||||
$id_genero_max = 3;
|
||||
|
||||
$conn = Database::getInstance();
|
||||
|
||||
$conn->begin_transaction();
|
||||
|
||||
try {
|
||||
for ($i = 1; $i <= $numero_inserts; $i++) {
|
||||
$nombres = "Nombre" . $i;
|
||||
$primer_apellido = "ApellidoP" . $i;
|
||||
$segundo_apellido = "ApellidoM" . $i;
|
||||
$correo = "correo" . $i . "@gmail.com";
|
||||
|
||||
$fecha_entrada = date('Y-m-d H:i:s');
|
||||
// fecha_salida es NULL por defecto en la tabla, o se puede especificar como NULL
|
||||
|
||||
$telefono = '';
|
||||
for ($j = 0; $j < 10; $j++) {
|
||||
$telefono .= rand(0, 9);
|
||||
}
|
||||
|
||||
$id_examen = rand($id_examen_min, $id_examen_max);
|
||||
$id_tipo_id = rand($id_tipo_id_min, $id_tipo_id_max);
|
||||
$id_rango_edad = rand($id_rango_edad_min, $id_rango_edad_max);
|
||||
$id_genero = rand($id_genero_min, $id_genero_max);
|
||||
|
||||
$sql = "INSERT INTO candidato (fecha_entrada, nombres, primer_apellido, segundo_apellido, correo, telefono, id_examen, id_tipo_id, id_rango_edad, id_genero)
|
||||
VALUES ('{$fecha_entrada}', '{$nombres}', '{$primer_apellido}', '{$segundo_apellido}', '{$correo}', '{$telefono}', {$id_examen}, {$id_tipo_id}, {$id_rango_edad}, {$id_genero})";
|
||||
|
||||
if (!$conn->query($sql)) {
|
||||
throw new Exception("Error al insertar el registro {$i}: " . $conn->error);
|
||||
}
|
||||
}
|
||||
$conn->commit();
|
||||
echo "Se han insertado {$numero_inserts} registros exitosamente.";
|
||||
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
echo "Error en la transacción: " . $e->getMessage();
|
||||
} finally {
|
||||
$conn->close();
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "Parámetros incorrectos. Asegúrate de pasar 'n' como parámetro GET con un número entero. Por ejemplo: .../ruta/inserts-prueba.php?n=5";
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/../models/CatalogosModel.php';
|
||||
|
||||
class CatalogosController {
|
||||
private static $catalogosModel = null;
|
||||
|
||||
public static function inicializar() {
|
||||
if (self::$catalogosModel === null) {
|
||||
self::$catalogosModel = new Catalogos();
|
||||
}
|
||||
}
|
||||
|
||||
public static function obtenerInfiCodigoPostal($codigo_postal){
|
||||
return self::$catalogosModel->obtenerInfiCodigoPostal($codigo_postal);
|
||||
}
|
||||
|
||||
public static function obtenerGiros(){
|
||||
return self::$catalogosModel->obtenerGiros();
|
||||
}
|
||||
|
||||
public static function obtenerNombresExamenes(){
|
||||
return self::$catalogosModel->obtenerNombresExamenes();
|
||||
}
|
||||
|
||||
public static function obtenerTiposIdentificacion(){
|
||||
return self::$catalogosModel->obtenerTiposIdentificacion();
|
||||
}
|
||||
|
||||
public static function obtenerRangosEdad(){
|
||||
return self::$catalogosModel->obtenerRangosEdad();
|
||||
}
|
||||
|
||||
public static function obtenerNivelesEstudio(){
|
||||
return self::$catalogosModel->obtenerNivelesEstudio();
|
||||
}
|
||||
|
||||
public static function obtenerNombresEmpresasInstituciones(){
|
||||
return self::$catalogosModel->obtenerNombresEmpresasInstituciones();
|
||||
}
|
||||
|
||||
public static function obtenerMotivosExamen(){
|
||||
return self::$catalogosModel->obtenerMotivosExamen();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CatalogosController::inicializar();
|
||||
|
||||
// Petición GET para información del código postal
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['codigo_postal'])) {
|
||||
header('Content-Type: application/json');
|
||||
$codigo_postal = $_GET['codigo_postal'];
|
||||
$result = CatalogosController::obtenerInfiCodigoPostal($codigo_postal);
|
||||
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'giros') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerGiros();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'examenes') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerNombresExamenes();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'identificacion') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerTiposIdentificacion();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'rangosedad') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerRangosEdad();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'nivelesestudio') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerNivelesEstudio();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'empresasinstituciones') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerNombresEmpresasInstituciones();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['obtener']) && $_GET['obtener'] === 'motivos') {
|
||||
header('Content-Type: application/json');
|
||||
$result = CatalogosController::obtenerMotivosExamen();
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/../models/CandidatoModel.php';
|
||||
|
||||
class ControlCandidatos {
|
||||
|
||||
private $candidatoModel;
|
||||
|
||||
public function __construct() {
|
||||
$this->candidatoModel = new CandidatoModel();
|
||||
}
|
||||
|
||||
public function obtenerCandidatosSinFechaSalida(){
|
||||
$resultado = $this->candidatoModel->obtenerCandidatosSinFechaSalida();
|
||||
if( isset($resultado['estado'])){
|
||||
return $resultado;
|
||||
} else {
|
||||
// iterar sobre $resultado y concatenar nombre completo, la fecha dejarla como esta
|
||||
$candidatos = [];
|
||||
foreach ($resultado as $candidato) {
|
||||
$nombreCompleto = "{$candidato['nombres']} {$candidato['primer_apellido']} {$candidato['segundo_apellido']}";
|
||||
$candidatos[] = [
|
||||
'id_candidato' => $candidato['id_candidato'],
|
||||
'nombre_completo' => $nombreCompleto,
|
||||
'fecha_entrada' => $candidato['fecha_entrada']
|
||||
];
|
||||
}
|
||||
return $candidatos;
|
||||
}
|
||||
}
|
||||
|
||||
public function eliminarCandidato($id_candidato){
|
||||
return $this->candidatoModel->eliminarCandidato($id_candidato);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once __DIR__ . '/UsuarioController.php';
|
||||
|
||||
// Inicializar el modelo de usuario
|
||||
UsuarioController::inicializar();
|
||||
|
||||
if ( $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$usuario = isset($_POST['numero-personal']) ? $_POST['numero-personal'] : '';
|
||||
$contrasena = isset($_POST['contrasena']) ? $_POST['contrasena'] : '';
|
||||
|
||||
// Iniciar sesión y obtener respuesta
|
||||
$respuesta = UsuarioController::iniciarSesion($usuario, $contrasena);
|
||||
|
||||
|
||||
if ($respuesta['estado'] === 'exitoso') {
|
||||
// Iniciar sesión
|
||||
session_start();
|
||||
$_SESSION['usuario'] = $usuario;
|
||||
}
|
||||
|
||||
echo json_encode($respuesta);
|
||||
|
||||
} else {
|
||||
// Metodo no permitido
|
||||
echo json_encode([
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Método no permitido'
|
||||
]);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/CandidatoController.php';
|
||||
|
||||
// Manejar la solicitud POST para registrar un candidato
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$insertId = CandidatoController::registrarCandidato();
|
||||
if($insertId > 0){
|
||||
echo json_encode(['registroExitoso' => true, 'message' => 'Se ha registrado el candidato correctamente.']);
|
||||
} else {
|
||||
echo json_encode(['registroExitoso' => false, 'message' => 'Error al registrar el candidato.']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/CandidatoController.php';
|
||||
|
||||
// Manejar la solicitud POST para registrar información un candidato
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$respuesta = CandidatoController::registrarInfoCandidato();
|
||||
|
||||
if(isset($respuesta["estado"]) && $respuesta["estado"] === "exitoso") {
|
||||
echo json_encode([
|
||||
"estado" => "exitoso",
|
||||
"mensaje" => "Se ha registrado la información correctamente.",
|
||||
"res" => "id_candidato: " . $respuesta["mensaje"]
|
||||
]);
|
||||
} else if( isset($respuesta["estado"]) ){
|
||||
echo json_encode([
|
||||
"estado" => "error",
|
||||
"mensaje" => "Error al registrar la información.",
|
||||
"res" => $respuesta["mensaje"]
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/../models/UsuarioModel.php';
|
||||
|
||||
|
||||
class UsuarioController{
|
||||
private static $usuarioModel = null;
|
||||
|
||||
public static function inicializar() {
|
||||
if (self::$usuarioModel === null) {
|
||||
self::$usuarioModel = new UsuarioModel();
|
||||
}
|
||||
}
|
||||
|
||||
public static function obtenerUsuarios(){
|
||||
return self::$usuarioModel->obtenerUsuarios();
|
||||
}
|
||||
|
||||
public static function iniciarSesion($usuario, $contrasena){
|
||||
return self::$usuarioModel->iniciarSesion($usuario, $contrasena);
|
||||
}
|
||||
|
||||
public static function existeUsuario($usuario){
|
||||
$usuario = self::$usuarioModel->buscarUsuario($usuario);
|
||||
if ( isset($usuario['usuario']) ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function crearUsuario($usuario, $contrasena){
|
||||
if ( self::existeUsuario($usuario) ) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'El usuario ya existe.'
|
||||
];
|
||||
} else {
|
||||
return self::$usuarioModel->crearUsuario($usuario, $contrasena);
|
||||
}
|
||||
}
|
||||
|
||||
public static function eliminarUsuario($id_usuario){
|
||||
return self::$usuarioModel->eliminarUsuario($id_usuario);
|
||||
}
|
||||
|
||||
public static function actualizarUsuario($id, $usuario, $contrasena){
|
||||
return self::$usuarioModel->actualizarUsuario($id, $usuario, $contrasena);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Instanciar el modelo al cargar el controlador
|
||||
UsuarioController::inicializar();
|
||||
|
||||
?>
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/UsuarioController.php';
|
||||
header('Content-type: application/json');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$id = $_POST['id'];
|
||||
$usuario = $_POST['usuario'];
|
||||
$contrasena = $_POST['contrasena'];
|
||||
|
||||
$resultado = UsuarioController::actualizarUsuario($id, $usuario, $contrasena);
|
||||
echo json_encode($resultado);
|
||||
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Método no permitido.'
|
||||
]);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
// filepath: c:\xampp\htdocs\Proyecto_Lania\LANIA_Proyecto\php\buscarCodigo.php
|
||||
include 'conexionBd.php'; // Asegúrate de que el archivo esté en la ruta correcta
|
||||
|
||||
header('Content-Type: application/json'); // Aseguramos que la respuesta sea JSON
|
||||
|
||||
// Crear instancia de la conexión
|
||||
$conexion = new Conexion();
|
||||
$conexionBD = $conexion->conectar(); // Establecer conexión
|
||||
|
||||
// Verificar que se ha enviado el parámetro 'codigo_postal'
|
||||
if (isset($_GET['codigo_postal'])) {
|
||||
$codigo_postal = $_GET['codigo_postal'];
|
||||
|
||||
// Consulta SQL para obtener estado, ciudad y colonia en base al código postal
|
||||
$sql = "SELECT e.nombre AS estado, m.nombre AS municipio, c.nombre AS colonia
|
||||
FROM colonias c
|
||||
JOIN municipios m ON c.municipio = m.id
|
||||
JOIN estados e ON m.estado = e.id
|
||||
WHERE c.codigo_postal = ?";
|
||||
|
||||
// Verificar que la conexión a la base de datos esté activa
|
||||
if ($conexionBD) {
|
||||
// Preparar la sentencia SQL
|
||||
$stmt = $conexionBD->prepare($sql);
|
||||
$stmt->bind_param("i", $codigo_postal); // El parámetro es un entero (i)
|
||||
$stmt->execute();
|
||||
|
||||
// Obtener los resultados
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Verificar si hay resultados
|
||||
if ($result->num_rows > 0) {
|
||||
$data = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$data[] = $row; // Agregar cada resultado a un array
|
||||
}
|
||||
echo json_encode($data); // Devolver los resultados en formato JSON
|
||||
} else {
|
||||
echo json_encode([]); // Si no hay resultados, devolver un array vacío
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
} else {
|
||||
echo json_encode(["error" => "Conexión a la base de datos fallida."]);
|
||||
}
|
||||
|
||||
$conexionBD->close();
|
||||
} else {
|
||||
// Si no se recibe un código postal, respondemos con un error
|
||||
echo json_encode(["error" => "Código postal no proporcionado."]);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
session_start();
|
||||
session_destroy();
|
||||
header('Location: ../index.html');
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/UsuarioController.php';
|
||||
header('Content-type: application/json');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$usuario = $_POST['usuario'];
|
||||
$contrasena = $_POST['contrasena'];
|
||||
|
||||
$resultado = UsuarioController::crearUsuario($usuario, $contrasena);
|
||||
echo json_encode($resultado);
|
||||
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Método no permitido.'
|
||||
]);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
header('Content-Type: application/json', 'charset=UTF-8');
|
||||
require_once __DIR__ . '/ControlCandidatos.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['id_candidato'])) {
|
||||
$candidatoController = new ControlCandidatos();
|
||||
$id_candidato = $_POST['id_candidato'];
|
||||
$resultado = $candidatoController->eliminarCandidato($id_candidato);
|
||||
echo json_encode($resultado);
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Método no permitido.'
|
||||
]);
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
header('Content-Type: application/json', 'charset=UTF-8');
|
||||
require_once __DIR__ . '/UsuarioController.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['id_usuario'])) {
|
||||
$id_usuario = $_POST['id_usuario'];
|
||||
$resultado = UsuarioController::eliminarUsuario($id_usuario);
|
||||
echo json_encode($resultado);
|
||||
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Método no permitido.'
|
||||
]);
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
require_once '../config/Database.php';
|
||||
require_once '../models/GraficoModel.php';
|
||||
|
||||
header('Content-Type: application/json'); // Aseguramos que siempre se devuelva JSON
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$tipoConsulta = $input['tipoConsulta'] ?? '';
|
||||
|
||||
|
||||
|
||||
switch ($tipoConsulta) {
|
||||
case 'Femenino':
|
||||
$cantidad = GraficoModel::obtenerGeneroFemenino();
|
||||
break;
|
||||
case 'Masculino':
|
||||
$cantidad = GraficoModel::obtenerGeneroMasculino();
|
||||
break;
|
||||
case 'Prefiero no decirlo':
|
||||
$cantidad = GraficoModel::obtenerGeneroNoDefinido();
|
||||
break;
|
||||
case 'Menor de 18 años':
|
||||
$cantidad = GraficoModel::obtenerEdadMenor18();
|
||||
break;
|
||||
case '18 a 24 años':
|
||||
$cantidad = GraficoModel::obtenerEdad1824();
|
||||
break;
|
||||
case '25 a 34 años':
|
||||
$cantidad = GraficoModel::obtenerEdad2434();
|
||||
break;
|
||||
case '35 a 44 años':
|
||||
$cantidad = GraficoModel::obtenerEdad3544();
|
||||
break;
|
||||
case '45 a 54 años':
|
||||
$cantidad = GraficoModel::obtenerEdad4554();
|
||||
break;
|
||||
case '55 a 64 años':
|
||||
$cantidad = GraficoModel::obtenerEdad5564();
|
||||
break;
|
||||
case '65 años o más':
|
||||
$cantidad = GraficoModel::obtenerEdad65oMas();
|
||||
break;
|
||||
case 'Estados':
|
||||
$cantidad = GraficoModel::obtenerEstados();
|
||||
echo json_encode($cantidad); // Devolver directamente el array de estados
|
||||
exit; // Terminar la ejecucion aqui
|
||||
case 'Examenes':
|
||||
$cantidad = GraficoModel::obtenerExamenes();
|
||||
echo json_encode($cantidad); // Devolver directamente el array de examenes
|
||||
exit; // Terminar la ejecucion aqui
|
||||
default:
|
||||
$cantidad = 0;
|
||||
}
|
||||
|
||||
echo json_encode(['cantidad' => $cantidad]);
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1 @@
|
|||
<?php
|
|
@ -0,0 +1,38 @@
|
|||
.token-info {
|
||||
word-break: break-all;
|
||||
background-color: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
pre {
|
||||
background-color: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
.success-message {
|
||||
background-color: #d4edda;
|
||||
border-color: #c3e6cb;
|
||||
color: #155724;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.download-section {
|
||||
background-color: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
.download-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.download-btn {
|
||||
min-width: 120px;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap');
|
||||
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f1f0f6;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
background-color: #ffffff;
|
||||
border: 2px solid #e8e8e8;
|
||||
border-radius: 8px;
|
||||
padding: 2rem;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.login-container {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.login-encabezado {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.login-logo {
|
||||
max-width: 150px;
|
||||
height: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.login-titulo {
|
||||
font-size: 1.5rem;
|
||||
color: #333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.login-subtitulo {
|
||||
color: #666;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.login-formulario {
|
||||
color: #666;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.form-grupo {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
background-color: #f6f6f6;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
outline: none;
|
||||
border-color: #35245b;
|
||||
box-shadow: 0 0 0 2px rgba(2, 27, 48, 0.2);
|
||||
}
|
||||
|
||||
.login-boton {
|
||||
background-color: #35245b;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 0.75rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
margin-top: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-boton:hover {
|
||||
background-color: #432d74;
|
||||
box-shadow: 0 4px 8px #53388f;
|
||||
}
|
||||
|
||||
.login-boton:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.mensaje-error {
|
||||
display: none;
|
||||
background-color: #f8d7da;
|
||||
color: #dc3545;
|
||||
border: 1px solid #dc3545;
|
||||
border-radius: 4px;
|
||||
padding: 0.75rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
animation: fadeIn 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,260 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href='https://unpkg.com/boxicons@2.0.9/css/boxicons.min.css' rel='stylesheet'>
|
||||
<link rel="stylesheet" href="css/form.css">
|
||||
<title>AdminSite</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<section id="sidebar">
|
||||
<a href="inicio.html" class="brand"><i class='bx bx-code-alt icon' ></i> LANIA</a>
|
||||
<!-- <a href="#" class="brand">
|
||||
<img src="img/lania_logo.png" alt="Logo" style="height: 40px;">
|
||||
</a> -->
|
||||
<ul class="side-menu">
|
||||
<li><a href="#" class="active"><i class='bx bxs-dashboard icon' ></i> Dashboard</a></li>
|
||||
<li class="divider" data-text="main">Main</li>
|
||||
<li>
|
||||
<a href="#"><i class='bx bxs-inbox icon' ></i> Elements <i class='bx bx-chevron-right icon-right' ></i></a>
|
||||
<ul class="side-dropdown">
|
||||
<li><a href="#">Alert</a></li>
|
||||
<li><a href="#">Badges</a></li>
|
||||
<li><a href="#">Breadcrumbs</a></li>
|
||||
<li><a href="#">Button</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#"><i class='bx bxs-chart icon' ></i> Charts</a></li>
|
||||
<li><a href="#"><i class='bx bxs-widget icon' ></i> Widgets</a></li>
|
||||
<li class="divider" data-text="table and forms">Table and forms</li>
|
||||
<li><a href="#"><i class='bx bx-table icon' ></i> Tables</a></li>
|
||||
<li>
|
||||
<a href="#"><i class='bx bxs-notepad icon' ></i> Formularios <i class='bx bx-chevron-right icon-right' ></i></a>
|
||||
<ul class="side-dropdown">
|
||||
<li><a href="form_datos_basicos.html">Datos Básicos</a></li>
|
||||
<li><a href="form_datos_extendidos.html">Datos Extendidos</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- <div class="ads">
|
||||
<div class="wrapper">
|
||||
<a href="#" class="btn-upgrade">Upgrade</a>
|
||||
<p>Become a <span>PRO</span> member and enjoy <span>All Features</span></p>
|
||||
</div>
|
||||
</div> -->
|
||||
</section>
|
||||
<!-- SIDEBAR -->
|
||||
|
||||
<!-- NAVBAR -->
|
||||
<section id="content">
|
||||
<!-- NAVBAR -->
|
||||
<nav>
|
||||
<i class='bx bx-menu toggle-sidebar' ></i>
|
||||
<form action="#">
|
||||
<div class="form-group">
|
||||
<input type="text" placeholder="Buscar...">
|
||||
<i class='bx bx-search icon' ></i>
|
||||
</div>
|
||||
</form>
|
||||
<a href="#" class="nav-link">
|
||||
<i class='bx bxs-bell icon' ></i>
|
||||
<span class="badge">5</span>
|
||||
</a>
|
||||
<a href="#" class="nav-link">
|
||||
<i class='bx bxs-message-square-dots icon' ></i>
|
||||
<span class="badge">8</span>
|
||||
</a>
|
||||
<span class="divider"></span>
|
||||
<div class="profile">
|
||||
<img src="https://images.unsplash.com/photo-1517841905240-472988babdf9?ixid=MnwxMjA3fDB8MHxzZWFyY2h8NHx8cGVvcGxlfGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" alt="">
|
||||
<ul class="profile-link">
|
||||
<li><a href="#"><i class='bx bxs-user-circle icon' ></i> Profile</a></li>
|
||||
<li><a href="#"><i class='bx bxs-cog' ></i> Settings</a></li>
|
||||
<li><a href="#"><i class='bx bxs-log-out-circle' ></i> Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- NAVBAR -->
|
||||
|
||||
<!-- MAIN -->
|
||||
<main>
|
||||
<h1 class="title">Datos Extendidos</h1>
|
||||
<ul class="breadcrumbs">
|
||||
<li><a href="#">Formularios</a></li>
|
||||
<li class="divider">/</li>
|
||||
<li><a href="#" class="active">Datos Extendidos</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="form-container">
|
||||
<form id="formulario-datos-extendido" method="post" action="#">
|
||||
<div class="form-section">
|
||||
<br>
|
||||
<h3>Ubicación</h3>
|
||||
<br>
|
||||
<div class="form-row">
|
||||
<input type="hidden" id="id_candidato" name="id_candidato">
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="id_pais" class="required">País</label>
|
||||
<select id="id_pais" name="id_pais" required>
|
||||
<option value="">Seleccione...</option>
|
||||
<!-- Aquí irían los países desde la base de datos -->
|
||||
<option value="1">México</option>
|
||||
<option value="2">Otro</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="codigo_postal" class="required">Código Postal</label>
|
||||
<input type="number" min="0" step="1" id="codigo_postal" name="codigo_postal" maxlength="10" required>
|
||||
<button type="button" id="buscarBtn"><span class="material-icons">search</span>Buscar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="id_estado">Estado</label>
|
||||
<select id="id_estado" name="id_estado">
|
||||
<option value="">Seleccione...</option>
|
||||
<!-- Aquí irían los estados desde la base de datos -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="id_municipio">Municipio</label>
|
||||
<select id="id_municipio" name="id_municipio">
|
||||
<option value="">Seleccione...</option>
|
||||
<!-- Aquí irían los municipios desde la base de datos -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="id_colonia">Colonia</label>
|
||||
<select id="id_colonia" name="id_colonia">
|
||||
<option value="">Seleccione...</option>
|
||||
<!-- Aquí irían las colonias desde la base de datos -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sección 3: Información Académica y Laboral -->
|
||||
<div class="form-section">
|
||||
<br>
|
||||
<h3>Información Académica/Laboral</h3>
|
||||
<br>
|
||||
<div class="form-row">
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="id_nivel" class="required">Nivel de Estudios</label>
|
||||
<select id="id_nivel" name="id_nivel" required>
|
||||
<option value="">Seleccione...</option>
|
||||
<option value="1">Primaria</option>
|
||||
<option value="2">Secundaria</option>
|
||||
<option value="3">Bachillerato</option>
|
||||
<option value="4">Técnico Superior Universitario</option>
|
||||
<option value="5">Licenciatura</option>
|
||||
<option value="6">Maestría</option>
|
||||
<option value="7">Doctorado</option>
|
||||
<option value="8">Otro</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-col">
|
||||
<div class="form-group">
|
||||
<label for="id_giro" class="required">Giro</label>
|
||||
<select id="id_giro" name="id_giro" required>
|
||||
<option value="">Seleccione...</option>
|
||||
<option value="1">Tecnologías de la Información</option>
|
||||
<option value="2">Gobierno</option>
|
||||
<option value="3">Finanzas</option>
|
||||
<option value="4">Salud</option>
|
||||
<option value="5">Educación</option>
|
||||
<option value="6">Telecomunicaciones</option>
|
||||
<option value="7">Retail</option>
|
||||
<option value="8">Manufactura</option>
|
||||
<option value="9">Logística y Transporte</option>
|
||||
<option value="10">Construcción</option>
|
||||
<option value="11">Turismo y Hospitalidad</option>
|
||||
<option value="12">Energía y Recursos Naturales</option>
|
||||
<option value="13">Agricultura y Alimentación</option>
|
||||
<option value="14">Medios de Comunicación y Entretenimiento</option>
|
||||
<option value="15">Otros</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nombre_empresa">Nombre de la Empresa/Institución</label>
|
||||
<input type="text" id="nombre_empresa" name="nombre_empresa"
|
||||
maxlength="100">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="motivo_examen">Motivo del Examen</label>
|
||||
<textarea id="motivo_examen" name="motivo_examen" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sección 4: Evaluación y Consentimiento -->
|
||||
<div class="form-section">
|
||||
|
||||
<br>
|
||||
<h3>Evaluación y Consentimiento</h3>
|
||||
<br>
|
||||
|
||||
<div class="form-group">
|
||||
<p>Calificación del Servicio</p>
|
||||
<br>
|
||||
<label for="calificacion_servicio">¿Qué tan satisfecho estás con nuestra institución en general, considerando la calidad de las instalaciones, la atención del personal y el proceso de certificación?</label>
|
||||
<br>
|
||||
<select id="calificacion_servicio" name="calificacion_servicio" class="select-emoji">
|
||||
<option value="">Seleccione una calificación...</option>
|
||||
<option value="1">😡 Muy insatisfecho</option>
|
||||
<option value="2">😕 Insatisfecho</option>
|
||||
<option value="3">😐 Neutral</option>
|
||||
<option value="4">🙂 Satisfecho</option>
|
||||
<option value="5">😄 Muy satisfecho</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="form-group">
|
||||
<input type="checkbox" id="consentimiento_pub" name="consentimiento_pub" value="1" checked>
|
||||
<label for="consentimiento_pub" style="display: inline;">Doy mi consentimiento para la publicación de mis datos</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<button type="submit" class="btn-submit">Enviar</button>
|
||||
|
||||
<div id="mensaje-error" class="mensaje-error"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</main>
|
||||
<!-- MAIN -->
|
||||
</section>
|
||||
<!-- NAVBAR -->
|
||||
|
||||
|
||||
<script src="js/form.js"></script>
|
||||
<script src="js/form_datos_extendidos.js"></script>
|
||||
<script src="https://website-widgets.pages.dev/dist/sienna.min.js" defer></script>
|
||||
<script src="js/buscarCodigo.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,69 @@
|
|||
document.addEventListener('DOMContentLoaded', function(){
|
||||
form = document.getElementById('form');
|
||||
const contrasena = document.getElementById('contrasena');
|
||||
const contrasenaVerificacion = document.getElementById('contrasena_verificacion');
|
||||
const btnSubmit = document.getElementById('submit');
|
||||
|
||||
const togglePassword = document.getElementById('togglePassword');
|
||||
togglePassword.addEventListener('click', function(e) {
|
||||
const type = contrasena.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||
contrasena.setAttribute('type', type);
|
||||
const icon = togglePassword.querySelector('i');
|
||||
if (type === 'text') {
|
||||
icon.classList.remove('bi-eye');
|
||||
icon.classList.add('bi-eye-slash');
|
||||
} else {
|
||||
icon.classList.remove('bi-eye-slash');
|
||||
icon.classList.add('bi-eye');
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
btnSubmit.addEventListener('click', function(event){
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
const c1 = contrasena.value;
|
||||
const c2 = contrasenaVerificacion.value;
|
||||
if (c1 === c2) {
|
||||
|
||||
const usuario = document.getElementById('usuario').value;
|
||||
|
||||
const regex = /^[a-zA-Z0-9]+$/;
|
||||
if (!regex.test(usuario)) {
|
||||
alert("Nombre de usuario no valido.");
|
||||
return;
|
||||
}
|
||||
|
||||
const id = document.getElementById('id').value;
|
||||
const data = new FormData();
|
||||
data.append("id", id);
|
||||
data.append("usuario", usuario);
|
||||
data.append("contrasena", c1);
|
||||
|
||||
fetch('../controllers/actualizarUsuario.php', {
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.estado === "exitoso") {
|
||||
alert(data.mensaje);
|
||||
} else if (data.estado === "error") {
|
||||
alert("Error, intentelo más tarde.");
|
||||
console.log(data.mensaje);
|
||||
} else {
|
||||
alert("Error inesperado, intentelo más tarde.");
|
||||
console.log(data);
|
||||
}
|
||||
window.location.href = "control-usuarios.php";
|
||||
})
|
||||
} else {
|
||||
alert("Las contraseñas no coinciden");
|
||||
}
|
||||
})
|
||||
})
|
|
@ -0,0 +1,77 @@
|
|||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var buscarBtn = document.getElementById("buscarBtn");
|
||||
|
||||
//Añadir un evento al boton de buscar
|
||||
buscarBtn.addEventListener("click", function() {
|
||||
var codigoPostal = document.getElementById("codigo_postal").value;
|
||||
console.log(codigoPostal);
|
||||
|
||||
//verificar si el codigo postal esta vacio
|
||||
if (codigoPostal) {
|
||||
//crear la url para la peticion
|
||||
var url = "./php/buscarCodigo.php?codigo_postal=" + encodeURIComponent(codigoPostal);
|
||||
|
||||
//Realiza una solicitud HTTP GET a la URL especificada
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
//console.log("Estado de la respuesta:", response.status);
|
||||
//console.log("Contenido de la respuesta:", response);
|
||||
// Verifica si la respuesta del servidor es exitosa
|
||||
if (!response.ok) {
|
||||
throw new Error("Error en la respuesta del servidor");
|
||||
}
|
||||
//Convierte la respuesta a formato JSON
|
||||
return response.json();
|
||||
|
||||
|
||||
})
|
||||
.then(data => {
|
||||
var estadoSelect = document.getElementById("id_estado");
|
||||
var municipioSelect = document.getElementById("id_municipio");
|
||||
var coloniaSelect = document.getElementById("id_colonia");
|
||||
|
||||
// Inicializa los elementos select con una opción por defecto
|
||||
estadoSelect.innerHTML = "<option value=''>Seleccionar Estado</option>";
|
||||
municipioSelect.innerHTML = "<option value=''>Seleccionar Municipios</option>";
|
||||
coloniaSelect.innerHTML = "<option value=''>Seleccionar Colonia</option>";
|
||||
|
||||
// Verifica si se recibieron datos
|
||||
if (data.length > 0) {
|
||||
//Crea conjuntos para almacenar estados, ciudades y colonias únicos
|
||||
let estados = new Set();
|
||||
let municipios = new Set();
|
||||
let colonias = [];
|
||||
|
||||
// Itera sobre cada fila de datos recibidos
|
||||
data.forEach(row => {
|
||||
estados.add(row.estado);
|
||||
municipios.add(row.municipio);
|
||||
colonias.push(row.colonia);
|
||||
});
|
||||
|
||||
//Añade las opciones de estados al elemento select
|
||||
estados.forEach(estado => {
|
||||
estadoSelect.innerHTML += "<option value='" + estado + "'>" + estado + "</option>";
|
||||
});
|
||||
|
||||
//Añade las opciones de ciudades al elemento select
|
||||
municipios.forEach(municipio => {
|
||||
municipioSelect.innerHTML += "<option value='" + municipio + "'>" + municipio + "</option>";
|
||||
});
|
||||
|
||||
//Añade las opciones de colonias al elemento select
|
||||
colonias.forEach(colonia => {
|
||||
coloniaSelect.innerHTML += "<option value='" + colonia + "'>" + colonia + "</option>";
|
||||
});
|
||||
} else {
|
||||
alert("No se encontraron datos para el código postal ingresado.");
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error en la solicitud:", error);
|
||||
});
|
||||
} else {
|
||||
alert("Por favor, ingrese un código postal.");
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,34 @@
|
|||
document.addEventListener("DOMContentLoaded" , function() {
|
||||
const tabla = document.querySelector('table');
|
||||
|
||||
tabla.addEventListener("click", function(evento) {
|
||||
const botonEliminar = evento.target.closest(".boton-eliminar");
|
||||
|
||||
if (botonEliminar) {
|
||||
const idUsuarioEliminar = botonEliminar.dataset.idUsuario;
|
||||
const nombreUsuarioEliminar = botonEliminar.dataset.nombreUsuario;
|
||||
|
||||
// Mostrar un mensaje de confirmación antes de eliminar
|
||||
if (!confirm("¿Desea eliminar al usuario " + nombreUsuarioEliminar + "?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = new FormData();
|
||||
data.append("id_usuario", idUsuarioEliminar);
|
||||
|
||||
fetch('../controllers/eliminarUsuario.php', {
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
alert(data.mensaje);
|
||||
location.reload();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
});
|
|
@ -0,0 +1,69 @@
|
|||
document.addEventListener('DOMContentLoaded', function(){
|
||||
const form = document.getElementById('form');
|
||||
const contrasena = document.getElementById('contrasena');
|
||||
const contrasenaVerificacion = document.getElementById('contrasena_verificacion');
|
||||
const btnSubmit = document.getElementById('submit');
|
||||
|
||||
const togglePassword = document.getElementById('togglePassword');
|
||||
const password = document.getElementById('contrasena');
|
||||
togglePassword.addEventListener('click', function(e) {
|
||||
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||
password.setAttribute('type', type);
|
||||
const icon = togglePassword.querySelector('i');
|
||||
if (type === 'text') {
|
||||
icon.classList.remove('bi-eye');
|
||||
icon.classList.add('bi-eye-slash');
|
||||
} else {
|
||||
icon.classList.remove('bi-eye-slash');
|
||||
icon.classList.add('bi-eye');
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
btnSubmit.addEventListener('click', function(event){
|
||||
// Forzar vaidación nativa de HTML5
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
const c1 = contrasena.value;
|
||||
const c2 = contrasenaVerificacion.value;
|
||||
if (c1 === c2) {
|
||||
|
||||
const usuario = document.getElementById('usuario').value;
|
||||
|
||||
const regex = /^[a-zA-Z0-9]+$/;
|
||||
if (!regex.test(usuario)) {
|
||||
alert("Nombre de usuario no valido.");
|
||||
return;
|
||||
}
|
||||
|
||||
const data = new FormData();
|
||||
data.append("usuario", usuario);
|
||||
data.append("contrasena", c1);
|
||||
|
||||
fetch('../controllers/crearUsuario.php', {
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.estado === "exitoso") {
|
||||
alert(data.mensaje);
|
||||
window.location.href = "control-usuarios.php";
|
||||
} else if (data.estado === "error") {
|
||||
alert("Error, intentelo más tarde.");
|
||||
console.log(data.mensaje);
|
||||
} else {
|
||||
alert("Error inesperado, intentelo más tarde.");
|
||||
console.log(data);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
alert("Las contraseñas no coinciden");
|
||||
}
|
||||
})
|
||||
})
|
|
@ -0,0 +1,148 @@
|
|||
// SIDEBAR DROPDOWN
|
||||
const allDropdown = document.querySelectorAll('#sidebar .side-dropdown');
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if(!this.classList.contains('active')) {
|
||||
allDropdown.forEach(i=> {
|
||||
const aLink = i.parentElement.querySelector('a:first-child');
|
||||
|
||||
aLink.classList.remove('active');
|
||||
i.classList.remove('show');
|
||||
})
|
||||
}
|
||||
|
||||
this.classList.toggle('active');
|
||||
item.classList.toggle('show');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SIDEBAR COLLAPSE
|
||||
const toggleSidebar = document.querySelector('nav .toggle-sidebar');
|
||||
const allSideDivider = document.querySelectorAll('#sidebar .divider');
|
||||
|
||||
if(sidebar.classList.contains('hide')) {
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = '-'
|
||||
})
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
} else {
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = item.dataset.text;
|
||||
})
|
||||
}
|
||||
|
||||
toggleSidebar.addEventListener('click', function () {
|
||||
sidebar.classList.toggle('hide');
|
||||
|
||||
if(sidebar.classList.contains('hide')) {
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = '-'
|
||||
})
|
||||
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
} else {
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = item.dataset.text;
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
sidebar.addEventListener('mouseleave', function () {
|
||||
if(this.classList.contains('hide')) {
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = '-'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
sidebar.addEventListener('mouseenter', function () {
|
||||
if(this.classList.contains('hide')) {
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = item.dataset.text;
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
// PROFILE DROPDOWN
|
||||
const profile = document.querySelector('nav .profile');
|
||||
const imgProfile = profile.querySelector('img');
|
||||
const dropdownProfile = profile.querySelector('.profile-link');
|
||||
|
||||
imgProfile.addEventListener('click', function () {
|
||||
dropdownProfile.classList.toggle('show');
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
// MENU
|
||||
const allMenu = document.querySelectorAll('main .content-data .head .menu');
|
||||
|
||||
allMenu.forEach(item=> {
|
||||
const icon = item.querySelector('.icon');
|
||||
const menuLink = item.querySelector('.menu-link');
|
||||
|
||||
icon.addEventListener('click', function () {
|
||||
menuLink.classList.toggle('show');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
window.addEventListener('click', function (e) {
|
||||
if(e.target !== imgProfile) {
|
||||
if(e.target !== dropdownProfile) {
|
||||
if(dropdownProfile.classList.contains('show')) {
|
||||
dropdownProfile.classList.remove('show');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allMenu.forEach(item=> {
|
||||
const icon = item.querySelector('.icon');
|
||||
const menuLink = item.querySelector('.menu-link');
|
||||
|
||||
if(e.target !== icon) {
|
||||
if(e.target !== menuLink) {
|
||||
if (menuLink.classList.contains('show')) {
|
||||
menuLink.classList.remove('show')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
|
@ -0,0 +1,43 @@
|
|||
const formulario = document.getElementById("login-formulario");
|
||||
const notificacion = document.getElementById("mensaje-error");
|
||||
|
||||
formulario.addEventListener("submit", async (event) => {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const numeroPersonal = document.getElementById("numero-personal").value;
|
||||
const contrasena = document.getElementById("contrasena").value;
|
||||
const data = new FormData();
|
||||
|
||||
data.append("numero-personal", numeroPersonal);
|
||||
data.append("contrasena", contrasena);
|
||||
|
||||
try {
|
||||
const respuestaPeticion = await fetch("controllers/LoginController.php", {
|
||||
method: "POST",
|
||||
body: data,
|
||||
});
|
||||
|
||||
// const respuesta = await respuestaPeticion.json();
|
||||
const respuesta = await respuestaPeticion.json();
|
||||
|
||||
if (respuesta.estado === 'exitoso') {
|
||||
window.location.href = 'views/inicio.html';
|
||||
|
||||
} else if(respuesta.estado === 'error') {
|
||||
notificacion.textContent = respuesta.mensaje;
|
||||
if(respuesta.res){ // Si existe respuesta.res hubo un error y se imprime en consola
|
||||
console.error(respuesta.res)
|
||||
}
|
||||
notificacion.style.display = "block";
|
||||
|
||||
} else {
|
||||
notificacion.textContent = "Lo sentimos, el servicio no está disponible por el momento";
|
||||
console.error("No se recibió la respuesta esperada del servidor");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
notificacion.textContent = "Lo sentimos, el servicio no está disponible por el momento";
|
||||
console.error(error)
|
||||
}
|
||||
});
|
|
@ -0,0 +1,160 @@
|
|||
// SIDEBAR DROPDOWN
|
||||
const allDropdown = document.querySelectorAll('#sidebar .side-dropdown');
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
|
||||
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if(!this.classList.contains('active')) {
|
||||
allDropdown.forEach(i=> {
|
||||
const aLink = i.parentElement.querySelector('a:first-child');
|
||||
|
||||
aLink.classList.remove('active');
|
||||
i.classList.remove('show');
|
||||
})
|
||||
}
|
||||
|
||||
this.classList.toggle('active');
|
||||
item.classList.toggle('show');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SIDEBAR COLLAPSE
|
||||
// const toggleSidebar = document.querySelector('nav .toggle-sidebar');
|
||||
const allSideDivider = document.querySelectorAll('#sidebar .divider');
|
||||
|
||||
if(sidebar.classList.contains('hide')) {
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = '-'
|
||||
})
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
} else {
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = item.dataset.text;
|
||||
})
|
||||
}
|
||||
|
||||
// toggleSidebar.addEventListener('click', function () {
|
||||
// sidebar.classList.toggle('hide');
|
||||
//
|
||||
// if(sidebar.classList.contains('hide')) {
|
||||
// allSideDivider.forEach(item=> {
|
||||
// item.textContent = '-'
|
||||
// })
|
||||
//
|
||||
// allDropdown.forEach(item=> {
|
||||
// const a = item.parentElement.querySelector('a:first-child');
|
||||
// a.classList.remove('active');
|
||||
// item.classList.remove('show');
|
||||
// })
|
||||
// } else {
|
||||
// allSideDivider.forEach(item=> {
|
||||
// item.textContent = item.dataset.text;
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
|
||||
|
||||
|
||||
|
||||
sidebar.addEventListener('mouseleave', function () {
|
||||
if(this.classList.contains('hide')) {
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = '-'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
sidebar.addEventListener('mouseenter', function () {
|
||||
if(this.classList.contains('hide')) {
|
||||
allDropdown.forEach(item=> {
|
||||
const a = item.parentElement.querySelector('a:first-child');
|
||||
a.classList.remove('active');
|
||||
item.classList.remove('show');
|
||||
})
|
||||
allSideDivider.forEach(item=> {
|
||||
item.textContent = item.dataset.text;
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
// PROFILE DROPDOWN
|
||||
// const profile = document.querySelector('nav .profile');
|
||||
// const imgProfile = profile.querySelector('img');
|
||||
// const dropdownProfile = profile.querySelector('.profile-link');
|
||||
//
|
||||
// imgProfile.addEventListener('click', function () {
|
||||
// dropdownProfile.classList.toggle('show');
|
||||
// })
|
||||
|
||||
|
||||
|
||||
|
||||
// MENU
|
||||
const allMenu = document.querySelectorAll('main .content-data .head .menu');
|
||||
|
||||
allMenu.forEach(item=> {
|
||||
const icon = item.querySelector('.icon');
|
||||
const menuLink = item.querySelector('.menu-link');
|
||||
|
||||
icon.addEventListener('click', function () {
|
||||
menuLink.classList.toggle('show');
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
// window.addEventListener('click', function (e) {
|
||||
// if(e.target !== imgProfile) {
|
||||
// if(e.target !== dropdownProfile) {
|
||||
// if(dropdownProfile.classList.contains('show')) {
|
||||
// dropdownProfile.classList.remove('show');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// allMenu.forEach(item=> {
|
||||
// const icon = item.querySelector('.icon');
|
||||
// const menuLink = item.querySelector('.menu-link');
|
||||
//
|
||||
// if(e.target !== icon) {
|
||||
// if(e.target !== menuLink) {
|
||||
// if (menuLink.classList.contains('show')) {
|
||||
// menuLink.classList.remove('show')
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // PROGRESSBAR
|
||||
// const allProgress = document.querySelectorAll('main .card .progress');
|
||||
//
|
||||
// allProgress.forEach(item=> {
|
||||
// item.style.setProperty('--value', item.dataset.value)
|
||||
// })
|
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/../config/Database.php';
|
||||
|
||||
class Catalogos{
|
||||
private $conn;
|
||||
|
||||
public function __construct() {
|
||||
$this->conn = Database::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene el estado, municipio y colonia en base al código postal proporcionado.
|
||||
* @param int $codigo_postal El código postal a buscar.
|
||||
* @return array Un array con los datos de estado, municipio y colonia.
|
||||
*/
|
||||
public function obtenerInfiCodigoPostal($codigo_postal){
|
||||
|
||||
// Consulta SQL para obtener estado, ciudad y colonia en base al código postal
|
||||
$sql = "SELECT e.id AS id_estado, e.nombre AS estado, m.id AS id_municipio, m.nombre AS municipio, c.id AS id_colonia, c.nombre AS colonia
|
||||
FROM colonias c
|
||||
JOIN municipios m ON c.municipio = m.id
|
||||
JOIN estados e ON m.estado = e.id
|
||||
WHERE c.codigo_postal = ?";
|
||||
|
||||
// Preparar la sentencia SQL
|
||||
$stmt = $this->conn->prepare($sql);
|
||||
$stmt->bind_param("i", $codigo_postal);
|
||||
$stmt->execute();
|
||||
|
||||
// Obtener los resultados
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$stmt->close();
|
||||
$data = [];
|
||||
// Verificar si hay resultados
|
||||
if ($result->num_rows > 0) {
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$data[] = $row; // Agregar cada resultado a un array
|
||||
}
|
||||
return $data;
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los giros.
|
||||
* @return array
|
||||
*/
|
||||
public function obtenerGiros(){
|
||||
$sql = "SELECT id_giro, descripcion FROM giro ORDER BY descripcion";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$giros = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$giros[] = $row;
|
||||
}
|
||||
|
||||
return $giros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los nombres de los examenes disponibles.
|
||||
* @return array Lista del nombre de la institución a la que pertenece el examen.
|
||||
*/
|
||||
public function obtenerNombresExamenes(){
|
||||
$sql = "SELECT id_examen, nombre_examen FROM examen ORDER BY nombre_examen";
|
||||
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$examenes = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$examenes[] = $row;
|
||||
}
|
||||
|
||||
return $examenes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener los tipos de identificación.
|
||||
* @return array
|
||||
*/
|
||||
public function obtenerTiposIdentificacion(){
|
||||
$sql = "SELECT id_tipo_id, descripcion FROM tipo_identificacion ORDER BY descripcion";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$tipos = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$tipos[] = $row;
|
||||
}
|
||||
|
||||
return $tipos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los rangos de edad.
|
||||
* @return array
|
||||
*/
|
||||
public function obtenerRangosEdad(){
|
||||
$sql = "SELECT id_rango_edad, descripcion FROM rango_edad ORDER BY id_rango_edad";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$rangos = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$rangos[] = $row;
|
||||
}
|
||||
|
||||
return $rangos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los niveles de estudio.
|
||||
* @return array
|
||||
*/
|
||||
public function obtenerNivelesEstudio(){
|
||||
$sql = "SELECT id_nivel, descripcion FROM nivel_estudio ORDER BY id_nivel";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$niveles = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$niveles[] = $row;
|
||||
}
|
||||
|
||||
return $niveles;
|
||||
}
|
||||
|
||||
public function obtenerNombresEmpresasInstituciones(){
|
||||
$sql = "SELECT DISTINCT nombre_empresa_institucion FROM info_candidatos ORDER BY nombre_empresa_institucion";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$empresas = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$empresas[] = $row;
|
||||
}
|
||||
|
||||
return $empresas;
|
||||
}
|
||||
|
||||
public function obtenerMotivosExamen(){
|
||||
$sql = "SELECT id, descripcion FROM motivo_examen ORDER BY descripcion";
|
||||
$result = $this->conn->query($sql);
|
||||
|
||||
$motivos = [];
|
||||
while($row = $result->fetch_assoc()){
|
||||
$motivos[] = $row;
|
||||
}
|
||||
|
||||
return $motivos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,266 @@
|
|||
<?php
|
||||
require_once '../config/Database.php';
|
||||
|
||||
|
||||
class GraficoModel{
|
||||
private $db;
|
||||
|
||||
public function __construct() {
|
||||
$db = DataBase::getInstance();
|
||||
}
|
||||
|
||||
|
||||
public static function obtenerGeneroFemenino() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS Femenino FROM candidato WHERE id_genero = 2 ");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['Femenino'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerGeneroMasculino() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS Maculino FROM candidato WHERE id_genero = 1 ");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['Maculino'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerGeneroNoDefinido() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS NoDefinido FROM candidato WHERE id_genero = 3 ");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['NoDefinido'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerEdadMenor18() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS menorEdad FROM candidato WHERE id_rango_edad = 1");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['menorEdad'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerEdad1824() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS edad1824 FROM candidato WHERE id_rango_edad = 2");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['edad1824'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerEdad2434() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS edad2434 FROM candidato WHERE id_rango_edad = 3");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['edad2434'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerEdad3544() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS edad3544 FROM candidato WHERE id_rango_edad = 4");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['edad3544'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
public static function obtenerEdad4554() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS edad4554 FROM candidato WHERE id_rango_edad = 5");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['edad4554'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
public static function obtenerEdad5564() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS edad5564 FROM candidato WHERE id_rango_edad = 6");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['edad5564'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerEdad65oMas() {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS edad65oMas FROM candidato WHERE id_rango_edad = 7");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
$output = "0";
|
||||
|
||||
if($resultado->num_rows > 0) {
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$output= $data['edad65oMas'];
|
||||
}
|
||||
}
|
||||
$query->close();
|
||||
self::$db->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public static function obtenerEstados() {
|
||||
try {
|
||||
$query = self::$db->prepare("SELECT estados.nombre AS estado, COUNT(*) AS cantidad
|
||||
FROM estados
|
||||
INNER JOIN info_candidatos ON info_candidatos.id_estado = estados.id
|
||||
GROUP BY estados.nombre
|
||||
ORDER BY estados.nombre
|
||||
");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
|
||||
$estados = [];
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$estados[] = $data;
|
||||
}
|
||||
|
||||
$query->close();
|
||||
|
||||
error_log(json_encode($estados));
|
||||
return $estados;
|
||||
} catch (Exception $e) {
|
||||
error_log("Error al obtener los estados: " . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public static function obtenerExamenes() {
|
||||
try {
|
||||
$query = self::$db->prepare("SELECT nombre_examen AS examen , COUNT(*) AS cantidad
|
||||
FROM examen
|
||||
INNER JOIN candidato ON candidato.id_examen = examen.id_examen
|
||||
GROUP BY nombre_examen
|
||||
ORDER BY nombre_examen;
|
||||
");
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
|
||||
$examenes = [];
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$examenes[] = $data;
|
||||
}
|
||||
|
||||
$query->close();
|
||||
|
||||
error_log(json_encode($examenes));
|
||||
return $examenes;
|
||||
} catch (Exception $e) {
|
||||
error_log("Error al obtener los examenes: " . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function obtenerFecha($fechaInicio, $fechaFin) {
|
||||
try {
|
||||
$query = self::$db->prepare("SELECT COUNT(*) AS total
|
||||
FROM candidato
|
||||
WHERE DATE(fecha_entrada) = ?
|
||||
AND DATE(fecha_salida) = ?;
|
||||
");
|
||||
$query->bind_param("ss", $fechaInicio, $fechaFin);
|
||||
$query->execute();
|
||||
$resultado = $query->get_result();
|
||||
|
||||
$fechas = [];
|
||||
while ($data = $resultado->fetch_assoc()) {
|
||||
$fechas[] = $data;
|
||||
}
|
||||
|
||||
error_log("Resultados de la consulta: " . json_encode($fechas)); // <-- Agrega este log
|
||||
|
||||
$query->close();
|
||||
return $fechas;
|
||||
} catch (Exception $e) {
|
||||
error_log("Error al obtener las fechas: " . $e->getMessage());
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,172 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/../config/Database.php';
|
||||
|
||||
class UsuarioModel {
|
||||
private $conn;
|
||||
|
||||
public function __construct() {
|
||||
$this->conn = Database::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registrar un nuevo usuario
|
||||
* @param string $usuario Nombre de usuario
|
||||
* @param string $contrasena Contraseña del usuario
|
||||
* @return array
|
||||
*/
|
||||
public function crearUsuario($usuario, $contrasena){
|
||||
// Hashear contraseña
|
||||
$contrasena_hash = password_hash($contrasena, PASSWORD_DEFAULT);
|
||||
|
||||
$stmt = $this->conn->prepare("INSERT INTO usuario (usuario, contrasena) VALUES (?, ?)");
|
||||
$stmt->bind_param("ss", $usuario, $contrasena_hash);
|
||||
if (!$stmt->execute()) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Error al registrar usuario: ' . $stmt->error
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return [
|
||||
'estado' => 'exitoso',
|
||||
'mensaje' => 'Usuario ' . $usuario . ' registrado exitosamente.'
|
||||
];
|
||||
}
|
||||
|
||||
public function actualizarUsuario($id, $usuario, $contrasena){
|
||||
// Hashear contraseña
|
||||
$contrasena_hash = password_hash($contrasena, PASSWORD_DEFAULT);
|
||||
|
||||
$stmt = $this->conn->prepare("UPDATE usuario SET usuario = ?, contrasena = ? WHERE id = ?");
|
||||
$stmt->bind_param("ssi", $usuario, $contrasena_hash, $id);
|
||||
if (!$stmt->execute()) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Error al actualizar usuario: ' . $stmt->error
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return [
|
||||
'estado' => 'exitoso',
|
||||
'mensaje' => 'Usuario ' . $usuario .' actualizado exitosamente.'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Iniciar sesión de un usuario
|
||||
* @param string $usuario Nombre de usuario
|
||||
* @param string $contrasena Contraseña del usuario
|
||||
* @return array
|
||||
*/
|
||||
public function iniciarSesion($usuario, $contrasena) {
|
||||
$stmt = $this->conn->prepare("SELECT contrasena FROM usuario WHERE usuario = ?");
|
||||
$stmt->bind_param("s", $usuario);
|
||||
if (!$stmt->execute()) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Error al iniciar sesión, intentelo más tarde.',
|
||||
'res' => $stmt->error
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->store_result();
|
||||
if ($stmt->num_rows == 0) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Usuario o contraseña incorrectos.'
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->bind_result($contrasena_hash);
|
||||
$stmt->fetch();
|
||||
|
||||
if (password_verify($contrasena, $contrasena_hash)){
|
||||
return [
|
||||
'estado' => 'exitoso',
|
||||
'mensaje' => 'Inicio de sesión exitoso.'
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Usuario o contraseña incorrectos.'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function obtenerUsuarios() {
|
||||
// Preparar la consulta mysql usando msqli
|
||||
$stmt = $this->conn->prepare("SELECT id, usuario FROM usuario");
|
||||
if (!$stmt->execute()) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Error al obtener usuarios: ' . $stmt->error
|
||||
];
|
||||
}
|
||||
|
||||
// Obtener el resultado
|
||||
$result = $stmt->get_result();
|
||||
|
||||
// Si no hay resultados, retornar un array con estado y mensaje
|
||||
if ($result->num_rows == 0) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'No hay usuarios registrados.'
|
||||
];
|
||||
}
|
||||
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
}
|
||||
|
||||
public function buscarUsuario($usuario) {
|
||||
$stmt = $this->conn->prepare("SELECT id, usuario FROM usuario WHERE usuario = ?");
|
||||
$stmt->bind_param("s", $usuario);
|
||||
if (!$stmt->execute()) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Error al verificar usuario: ' . $stmt->error
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->store_result();
|
||||
// Si no hay resultados, retornar un array con estado y mensaje
|
||||
if ($stmt->num_rows == 0) {
|
||||
return [
|
||||
'estado' => 'exitoso',
|
||||
'mensaje' => 'No existe el usuario.'
|
||||
];
|
||||
} else {
|
||||
$stmt->bind_result($id, $usuario);
|
||||
$stmt->fetch();
|
||||
return [
|
||||
'estado' => 'exitoso',
|
||||
'mensaje' => 'Usuario existe.',
|
||||
'id' => $id,
|
||||
'usuario' => $usuario
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function eliminarUsuario($id){
|
||||
$stmt = $this->conn->prepare("DELETE FROM usuario WHERE id = ?");
|
||||
$stmt->bind_param("i", $id);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
return [
|
||||
'estado' => 'error',
|
||||
'mensaje' => 'Error al eliminar usuario: ' . $stmt->error
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
return [
|
||||
'estado' => 'exitoso',
|
||||
'mensaje' => 'Usuario eliminado exitosamente.'
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
if (!isset($_SESSION['usuario'])) {
|
||||
header('Location: index.html');
|
||||
exit();
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pagina protegida</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
//require_once __DIR__ . "/controllers/usuarioController.php";
|
||||
|
||||
// UsuarioController::registrarUsuario("root", "root");
|
||||
|
||||
?>
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href='https://unpkg.com/boxicons@2.0.9/css/boxicons.min.css' rel='stylesheet'>
|
||||
<link rel="stylesheet" href="../css/inicio.css">
|
||||
<title>Gestión de usuarios</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<section id="sidebar">
|
||||
<a href="inicio.html" class="brand"><i class='bx bx-code-alt icon' ></i> LANIA</a>
|
||||
|
||||
<ul class="side-menu">
|
||||
|
||||
<li><a href="inicio.html"><i class='bx bxs-dashboard icon' ></i>Dashboard</a></li>
|
||||
<li><a href="formulario-candidato.html" target="_blank"><i class='bx bxs-dashboard icon' ></i>Formulario de registro</a></li>
|
||||
<li><a href="control-candidatos.php"><i class='bx bxs-dashboard icon' ></i>Control candidatos</a></li>
|
||||
<li><a href="control-candidatos.php" class="active"><i class='bx bxs-dashboard icon' ></i>Gestión usuarios</a></li>
|
||||
|
||||
<!--
|
||||
<li class="divider" data-text="main">Main</li>
|
||||
<li>
|
||||
<a href="#"><i class='bx bxs-inbox icon' ></i> Elements <i class='bx bx-chevron-right icon-right' ></i></a>
|
||||
<ul class="side-dropdown">
|
||||
<li><a href="#">Alert</a></li>
|
||||
<li><a href="#">Badges</a></li>
|
||||
<li><a href="#">Breadcrumbs</a></li>
|
||||
<li><a href="#">Button</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#"><i class='bx bxs-chart icon' ></i> Charts</a></li>
|
||||
<li><a href="#"><i class='bx bxs-widget icon' ></i> Widgets</a></li>
|
||||
<li class="divider" data-text="tablas y formularios">Tablas y formularios</li>
|
||||
<li><a href="#"><i class='bx bx-table icon' ></i> Tablas</a></li>
|
||||
<li>
|
||||
<a href="#"><i class='bx bxs-notepad icon' ></i> Formularios <i class='bx bx-chevron-right icon-right' ></i></a>
|
||||
<ul class="side-dropdown">
|
||||
<li><a href="formulario-candidato.html">Registro de candidato</a></li>
|
||||
<li><a href="formulario-datos-candidato.php">Datos de candidato</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
|
||||
|
||||
</section>
|
||||
<!-- .SIDEBAR -->
|
||||
|
||||
<section id="content">
|
||||
<!-- ========== MAIN ========== -->
|
||||
<main>
|
||||
<h1 class="title" style="margin: 2% 1%">Control</h1>
|
||||
|
||||
</main>
|
||||
<!-- .......... MAIN .......... -->
|
||||
</section>
|
||||
|
||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="../js/sidebar-navbar.js"></script>
|
||||
<script src="https://website-widgets.pages.dev/dist/sienna.min.js" defer></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
After Width: | Height: | Size: 257 KiB |
Loading…
Reference in New Issue