HEX
Server: LiteSpeed
System: Linux br-asc-web1193.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User: u474979917 (474979917)
PHP: 8.3.30
Disabled: system, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Upload Files
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>