File: /home/u474979917/domains/rafaelvasquez.org/public_html/pec/index.php
<?php
// ==================================================
// CONFIGURACIÓN DE LA BASE DE DATOS
// ==================================================
$host = 'localhost';
$dbname = 'u474979917_pec2026_db';
$user = 'u474979917_pec2026';
$password = 'Infernal666_!'; // <--- CAMBIA AQUÍ
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $user, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Error de conexión: " . $e->getMessage());
}
// ==================================================
// DETECTAR TABLA Y COLUMNAS
// ==================================================
$stmt = $pdo->query("SHOW TABLES");
$tablas = $stmt->fetchAll(PDO::FETCH_COLUMN);
$tabla = null;
foreach ($tablas as $t) {
if (strpos($t, 'information_schema') === false && strpos($t, 'mysql') === false && strpos($t, 'performance_schema') === false) {
$tabla = $t;
break;
}
}
if (!$tabla) die("No se encontró ninguna tabla.");
$stmt = $pdo->query("SELECT * FROM $tabla LIMIT 0");
$columnas = [];
for ($i = 0; $i < $stmt->columnCount(); $i++) {
$colMeta = $stmt->getColumnMeta($i);
$columnas[] = $colMeta['name'];
}
// ==================================================
// COLUMNAS A EXCLUIR (NO MOSTRAR)
// ==================================================
$excluirPatrones = [
'RES_ADMIN', // N_DE_RES_ADMIN
'FECHA_DE_RES', // FECHA_DE_RES_ADMIN
'ZONA', // ZONA
'DIRECTOR_DE_NUCLEO', // DIRECCION_DIRECTOR_DE_NUCLEO
'DIRECTOR', // DIRECTOR/A_DE_UE
'CELULAR', // N_DE_CELULAR
];
// Filtrar columnas visibles
$columnas_visibles = [];
foreach ($columnas as $col) {
$excluir = false;
foreach ($excluirPatrones as $patron) {
if (stripos($col, $patron) !== false) {
$excluir = true;
break;
}
}
if (!$excluir) {
$columnas_visibles[] = $col;
}
}
// ==================================================
// IDENTIFICAR COLUMNAS CLAVE PARA FILTROS
// ==================================================
function buscarColumna($columnas, $patrones) {
foreach ($columnas as $col) {
foreach ($patrones as $p) {
if (stripos($col, $p) !== false) return $col;
}
}
return null;
}
$colCodigo = buscarColumna($columnas, ['CODIGO', 'SIE', 'CÓDIGO', 'CODE']);
$colDistrito = buscarColumna($columnas, ['DISTRITO', 'DIST']);
$colUnidad = buscarColumna($columnas, ['UNIDAD', 'EDUCATIVA', 'NOMBRE', 'ESCUELA', 'COLEGIO']);
$colNiveles = buscarColumna($columnas, ['NIVELES', 'NIVEL', 'NIV']);
$colUbicacion= buscarColumna($columnas, ['UBICACION', 'MAPS', 'URL', 'LINK']);
$colSeleccion= buscarColumna($columnas, ['SELECCIONADA', 'SELECCION', 'SEL']);
// Fallback
if (!$colCodigo) $colCodigo = $columnas_visibles[0];
if (!$colDistrito) $colDistrito = $columnas_visibles[0];
if (!$colUnidad) $colUnidad = $columnas_visibles[0];
if (!$colNiveles) $colNiveles = $columnas_visibles[0];
// ==================================================
// VALORES ÚNICOS PARA SELECTORES
// ==================================================
$stmtDist = $pdo->query("SELECT DISTINCT $colDistrito FROM $tabla WHERE $colDistrito IS NOT NULL AND $colDistrito != '' ORDER BY $colDistrito");
$distritos = $stmtDist->fetchAll(PDO::FETCH_COLUMN);
$stmtNiv = $pdo->query("SELECT DISTINCT $colNiveles FROM $tabla WHERE $colNiveles IS NOT NULL AND $colNiveles != '' ORDER BY $colNiveles");
$niveles = $stmtNiv->fetchAll(PDO::FETCH_COLUMN);
// ==================================================
// RECIBIR FILTROS
// ==================================================
$codigo_busqueda = isset($_GET['codigo']) ? trim($_GET['codigo']) : '';
$distrito_sel = isset($_GET['distrito']) ? $_GET['distrito'] : '';
$unidad_busqueda = isset($_GET['unidad']) ? trim($_GET['unidad']) : '';
$nivel_sel = isset($_GET['nivel']) ? $_GET['nivel'] : '';
$sql = "SELECT * FROM $tabla WHERE 1=1";
$params = [];
if ($codigo_busqueda !== '') {
$sql .= " AND $colCodigo LIKE :codigo";
$params[':codigo'] = "%$codigo_busqueda%";
}
if ($distrito_sel !== '') {
$sql .= " AND $colDistrito = :distrito";
$params[':distrito'] = $distrito_sel;
}
if ($unidad_busqueda !== '') {
$sql .= " AND $colUnidad LIKE :unidad";
$params[':unidad'] = "%$unidad_busqueda%";
}
if ($nivel_sel !== '') {
$sql .= " AND $colNiveles = :nivel";
$params[':nivel'] = $nivel_sel;
}
$sql .= " ORDER BY $colCodigo ASC";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$resultados = $stmt->fetchAll(PDO::FETCH_ASSOC);
$total = count($resultados);
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PEC 2026 - Unidades Educativas</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body { background:#f0f7f3; font-family:'Segoe UI',Roboto,sans-serif; padding:1.5rem 1rem; }
.container { max-width:1400px; margin:0 auto; background:white; border-radius:20px; padding:1.2rem; box-shadow:0 8px 20px rgba(0,0,0,0.08); }
h1 { font-size:1.6rem; background:linear-gradient(135deg,#1f6e43,#2b8c5a); background-clip:text; -webkit-background-clip:text; color:transparent; display:inline-flex; align-items:center; gap:8px; }
h1 small { font-size:0.7rem; background:#e9f4ef; color:#1b5e3f; padding:3px 10px; border-radius:30px; }
.sub { color:#4b6a5e; margin-bottom:20px; border-left:3px solid #2b8c5a; padding-left:12px; font-size:0.85rem; }
.filters-panel { display:flex; flex-wrap:wrap; gap:0.8rem; background:#f9fefb; padding:0.8rem 1.2rem; border-radius:50px; align-items:flex-end; margin-bottom:1.5rem; }
.filter-group { flex:1; min-width:150px; }
.filter-group label { font-size:0.7rem; font-weight:600; text-transform:uppercase; color:#2c6e4e; display:block; margin-bottom:4px; }
.filter-group input, .filter-group select { width:100%; padding:6px 12px; border-radius:40px; border:1px solid #cddfd7; background:white; font-size:0.85rem; }
.filter-group input:focus, .filter-group select:focus { border-color:#2b8c5a; outline:none; box-shadow:0 0 0 2px rgba(43,140,90,0.2); }
.btn-reset { background:#eef3f0; border:none; padding:6px 16px; border-radius:40px; font-weight:600; color:#1b5e3f; cursor:pointer; font-size:0.8rem; text-decoration:none; display:inline-block; margin-top:22px; }
.btn-reset:hover { background:#dcebe3; }
.stats { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:0.8rem; font-size:0.8rem; }
.result-count { background:#eef2ef; padding:3px 12px; border-radius:30px; font-weight:500; }
.table-wrapper {
max-height: 70vh;
overflow: auto;
border-radius: 16px;
border: 1px solid #e2ede8;
}
.data-table { width:100%; border-collapse:collapse; font-size:0.75rem; min-width:800px; }
.data-table th { background:#eef4f1; color:#1e4a38; padding:8px 6px; text-align:left; border-bottom:1px solid #cbdcd4; cursor:pointer; user-select:none; position:sticky; top:0; background-color:#eef4f1; z-index:10; }
.data-table th:hover { background:#e2ebe6; }
.data-table td { padding:6px 6px; border-bottom:1px solid #e6f0eb; vertical-align:top; }
.data-table tr:hover td { background:#f6fef9; }
.map-icon { text-decoration:none; font-size:1.1rem; display:inline-block; }
.map-icon:hover { transform:scale(1.1); }
.badge { border-radius:20px; padding:2px 6px; font-size:0.7rem; font-weight:500; display:inline-block; }
.badge-si { background:#c8f0e1; color:#0b5e3a; }
.badge-xx { background:#ffe1cf; color:#b45a2b; }
footer { margin-top:1.5rem; text-align:center; font-size:0.65rem; color:#7f9b8e; }
@media (max-width:780px) { .filters-panel { flex-direction:column; align-items:stretch; border-radius:20px; } .btn-reset { margin-top:5px; } }
.sort-arrow { display:inline-block; margin-left:6px; font-size:0.7rem; }
</style>
</head>
<body>
<div class="container">
<h1>📚 Unidades Educativas <small>PEC 2026</small></h1>
<div class="sub">🔍 Filtros: Código SIE · Distrito · Unidad Educativa · Niveles Autorizados</div>
<form method="GET" class="filters-panel">
<div class="filter-group">
<label>🔢 Código SIE</label>
<input type="text" name="codigo" value="<?= htmlspecialchars($codigo_busqueda) ?>" placeholder="Ej: 81950008">
</div>
<div class="filter-group">
<label>🏫 Distrito</label>
<select name="distrito">
<option value="">Todos</option>
<?php foreach ($distritos as $d): ?>
<option value="<?= htmlspecialchars($d) ?>" <?= ($distrito_sel == $d) ? 'selected' : '' ?>><?= htmlspecialchars($d) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="filter-group">
<label>🏫 Unidad Educativa</label>
<input type="text" name="unidad" value="<?= htmlspecialchars($unidad_busqueda) ?>" placeholder="Nombre parcial...">
</div>
<div class="filter-group">
<label>📖 Niveles autorizados</label>
<select name="nivel">
<option value="">Todos</option>
<?php foreach ($niveles as $n): ?>
<option value="<?= htmlspecialchars($n) ?>" <?= ($nivel_sel == $n) ? 'selected' : '' ?>><?= htmlspecialchars($n) ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<button type="submit" class="btn-reset">🔍 Buscar</button>
<a href="?" class="btn-reset" style="margin-left:8px;">⟳ Limpiar</a>
</div>
</form>
<div class="stats">
<span class="result-count"><?= $total ?> resultados</span>
<span>🖱️ Clic en cabecera para ordenar</span>
</div>
<div class="table-wrapper">
<table class="data-table" id="tablaDatos">
<thead>
<tr>
<?php foreach ($columnas_visibles as $col): ?>
<th data-col="<?= htmlspecialchars($col) ?>"><?= htmlspecialchars($col) ?> <span class="sort-arrow"></span></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody id="tablaBody">
<?php if ($total == 0): ?>
<tr><td colspan="<?= count($columnas_visibles) ?>" style="text-align:center;">No se encontraron resultados</td></tr>
<?php else: ?>
<?php foreach ($resultados as $fila): ?>
<tr>
<?php foreach ($columnas_visibles as $col): ?>
<td>
<?php
$valor = $fila[$col];
if ($col === $colUbicacion && filter_var($valor, FILTER_VALIDATE_URL) &&
(strpos($valor, 'google.com/maps') !== false || strpos($valor, 'goo.gl') !== false || strpos($valor, 'maps.app.goo.gl') !== false)) {
echo '<a href="' . htmlspecialchars($valor) . '" target="_blank" class="map-icon" title="Ver mapa">📍</a>';
}
elseif ($col === $colSeleccion && ($valor == 'SÍ' || $valor == 'XX')) {
$clase = ($valor == 'SÍ') ? 'badge-si' : 'badge-xx';
echo '<span class="badge ' . $clase . '">' . htmlspecialchars($valor) . '</span>';
}
else {
echo htmlspecialchars($valor);
}
?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<footer>Columnas excluidas: N_DE_RES_ADMIN, FECHA_DE_RES_ADMIN, ZONA, DIRECCION_DIRECTOR_DE_NUCLEO, DIRECTOR/A_DE_UE, N_DE_CELULAR. Se muestra N_EQUIPO_PEC.</footer>
</div>
<script>
// Ordenamiento por clic (idéntico a la versión anterior)
(function() {
const table = document.getElementById('tablaDatos');
const tbody = document.getElementById('tablaBody');
let currentSortColumn = null;
let currentSortDirection = 'asc';
function getCellText(row, colIndex) {
const cell = row.cells[colIndex];
if (!cell) return '';
const clone = cell.cloneNode(true);
const icons = clone.querySelectorAll('.map-icon');
icons.forEach(icon => icon.remove());
return clone.innerText.trim();
}
function isNumber(val) {
return !isNaN(parseFloat(val)) && isFinite(val);
}
function isDate(val) {
return /^\d{4}-\d{2}-\d{2}/.test(val);
}
function comparar(a, b, direction) {
let valorA = a.val;
let valorB = b.val;
let tipo = a.type;
if (tipo === 'number') {
valorA = parseFloat(valorA) || 0;
valorB = parseFloat(valorB) || 0;
} else if (tipo === 'date') {
valorA = new Date(valorA);
valorB = new Date(valorB);
if (isNaN(valorA)) valorA = new Date(0);
if (isNaN(valorB)) valorB = new Date(0);
} else {
valorA = valorA.toLowerCase();
valorB = valorB.toLowerCase();
}
if (valorA < valorB) return direction === 'asc' ? -1 : 1;
if (valorA > valorB) return direction === 'asc' ? 1 : -1;
return 0;
}
function ordenarTabla(colIndex) {
const rows = Array.from(tbody.querySelectorAll('tr'));
if (rows.length === 0) return;
const datos = rows.map(row => {
let rawText = getCellText(row, colIndex);
let tipo = 'text';
if (isNumber(rawText)) tipo = 'number';
else if (isDate(rawText)) tipo = 'date';
return { row, val: rawText, type: tipo };
});
let direction;
if (currentSortColumn === colIndex) {
direction = (currentSortDirection === 'asc') ? 'desc' : 'asc';
} else {
direction = 'asc';
}
currentSortColumn = colIndex;
currentSortDirection = direction;
datos.sort((a, b) => comparar(a, b, direction));
datos.forEach(item => tbody.appendChild(item.row));
const headers = document.querySelectorAll('#tablaDatos th');
headers.forEach((th, idx) => {
const arrowSpan = th.querySelector('.sort-arrow');
if (idx === colIndex) {
arrowSpan.innerHTML = (direction === 'asc') ? ' ▲' : ' ▼';
} else {
arrowSpan.innerHTML = '';
}
});
}
function initSort() {
const headers = document.querySelectorAll('#tablaDatos th');
headers.forEach((th, idx) => {
th.style.cursor = 'pointer';
th.addEventListener('click', (e) => {
e.preventDefault();
ordenarTabla(idx);
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSort);
} else {
initSort();
}
})();
</script>
</body>
</html>