Tul xxx Tul
User / IP
:
216.73.216.159
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
vnet
/
app
/
views
/
herramientas
/
Viewing: index.php
<?php declare(strict_types=1); // Vista: Herramientas. ?> <section class="page"> <header class="page__header page__header--with-actions"> <div> <h1 class="page__title">Herramientas</h1> </div> <div class="page__actions"> <a class="btn btn--primary" href="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/herramientas/create">Nueva herramienta</a> </div> </header> <?php if (!empty($flash) && is_array($flash)) : ?> <?php if (($flash['type'] ?? '') === 'success') : ?> <div class="alert alert--success"><?= htmlspecialchars((string)($flash['message'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div> <?php else : ?> <div class="alert alert--error"><?= htmlspecialchars((string)($flash['message'] ?? ''), ENT_QUOTES, 'UTF-8') ?></div> <?php endif; ?> <?php endif; ?> <section class="panel" style="margin-bottom: 16px;"> <form method="get" action="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/herramientas" id="filterForm"> <div class="form-grid form-grid--filters"> <label class="field"> <span class="field__label">Buscar por nombre o código</span> <input type="text" class="field__input" name="nombre" id="filterNombre" placeholder="Escribe para buscar..." value="<?= htmlspecialchars((string)($filters['nombre'] ?? ''), ENT_QUOTES, 'UTF-8') ?>" autocomplete="off" > </label> <label class="field"> <span class="field__label">Categoría</span> <?php $catSel = (string)($filters['categoria'] ?? ''); ?> <select class="field__input" name="categoria" id="filterCategoria"> <option value="" <?= $catSel === '' ? 'selected' : '' ?>>Todas las categorías</option> <?php foreach ((array)($categorias ?? []) as $cat) : ?> <?php $cat = (string)$cat; ?> <option value="<?= htmlspecialchars($cat, ENT_QUOTES, 'UTF-8') ?>" <?= $catSel === $cat ? 'selected' : '' ?>> <?= htmlspecialchars($cat, ENT_QUOTES, 'UTF-8') ?> </option> <?php endforeach; ?> </select> </label> <label class="field"> <span class="field__label">Estado</span> <?php $estadoSel = (string)($filters['estado'] ?? ''); ?> <select class="field__input" name="estado" id="filterEstado"> <option value="" <?= $estadoSel === '' ? 'selected' : '' ?>>Todos los estados</option> <option value="1" <?= $estadoSel === '1' ? 'selected' : '' ?>>Disponible</option> <option value="0" <?= $estadoSel === '0' ? 'selected' : '' ?>>No disponible</option> </select> </label> </div> <div class="form-actions"> <a class="btn btn--secondary" href="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/herramientas">Limpiar filtros</a> </div> </form> </section> <div class="table-wrap"> <table class="table"> <thead> <tr> <th>Imagen</th> <th>Código</th> <th>Nombre</th> <th>Descripción</th> <th>Categoría</th> <th class="th-right">Cantidad</th> <th>Estado</th> <th class="th-right">Acciones</th> </tr> </thead> <tbody id="herramientasTableBody"> <?php if (empty($herramientas)) : ?> <tr> <td colspan="8" class="td-muted">No hay herramientas registradas.</td> </tr> <?php else : ?> <?php foreach ($herramientas as $h) : ?> <?php $id = (int)($h['id'] ?? 0); $disponible = (int)($h['estado'] ?? 0) === 1; $img = trim((string)($h['imagen'] ?? '')); ?> <tr> <td data-label="Imagen"> <?php if ($img !== '') : ?> <img class="table__thumb" src="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/public/<?= htmlspecialchars($img, ENT_QUOTES, 'UTF-8') ?>" alt=""> <?php else : ?> <span class="td-muted">—</span> <?php endif; ?> </td> <td data-label="Código"><?= htmlspecialchars((string)($h['codigo'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td> <td data-label="Nombre"><?= htmlspecialchars((string)($h['nombre'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td> <td data-label="Descripción"><?= htmlspecialchars((string)($h['descripcion'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td> <td data-label="Categoría"><?= htmlspecialchars((string)($h['categoria'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td> <td data-label="Cantidad" class="td-right"><?= (int)($h['cantidad'] ?? 0) ?></td> <td data-label="Estado"> <span class="badge <?= $disponible ? 'badge--success' : 'badge--muted' ?>"> <?= $disponible ? 'Disponible' : 'No disponible' ?> </span> </td> <td data-label="Acciones" class="td-right td-actions"> <a class="btn btn--secondary btn--sm" href="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/herramientas/show/<?= $id ?>">Ver</a> <a class="btn btn--secondary btn--sm" href="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/herramientas/edit/<?= $id ?>">Editar</a> <form method="post" action="<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, 'UTF-8') ?>/herramientas/delete/<?= $id ?>" class="inline" data-confirm="¿Eliminar esta herramienta? Esta acción no se puede deshacer."> <button class="btn btn--danger btn--sm" type="submit">Eliminar</button> </form> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </section> <script> (function() { 'use strict'; const filterForm = document.getElementById('filterForm'); const filterNombre = document.getElementById('filterNombre'); const filterCategoria = document.getElementById('filterCategoria'); const filterEstado = document.getElementById('filterEstado'); const tableBody = document.getElementById('herramientasTableBody'); const baseUrl = '<?= htmlspecialchars((string)BASE_URL, ENT_QUOTES, "UTF-8") ?>'; if (!filterForm || !filterNombre || !tableBody) return; let searchTimeout = null; let isSearching = false; // Función para escapar HTML function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Función para renderizar las filas de la tabla function renderTableRows(herramientas) { if (!herramientas || !Array.isArray(herramientas) || herramientas.length === 0) { tableBody.innerHTML = '<tr><td colspan="8" class="td-muted">No se encontraron herramientas.</td></tr>'; return; } let html = ''; herramientas.forEach(function(h) { const id = parseInt(h.id || 0, 10); const disponible = parseInt(h.estado || 0, 10) === 1; const img = (h.imagen || '').trim(); let imgHtml = '<span class="td-muted">—</span>'; if (img !== '') { imgHtml = '<img class="table__thumb" src="' + escapeHtml(baseUrl + '/public/' + img) + '" alt="">'; } html += '<tr>' + '<td data-label="Imagen">' + imgHtml + '</td>' + '<td data-label="Código">' + escapeHtml(h.codigo || '') + '</td>' + '<td data-label="Nombre">' + escapeHtml(h.nombre || '') + '</td>' + '<td data-label="Descripción">' + escapeHtml(h.descripcion || '') + '</td>' + '<td data-label="Categoría">' + escapeHtml(h.categoria || '') + '</td>' + '<td data-label="Cantidad" class="td-right">' + parseInt(h.cantidad || 0, 10) + '</td>' + '<td data-label="Estado">' + '<span class="badge ' + (disponible ? 'badge--success' : 'badge--muted') + '">' + (disponible ? 'Disponible' : 'No disponible') + '</span>' + '</td>' + '<td data-label="Acciones" class="td-right td-actions">' + '<a class="btn btn--secondary btn--sm" href="' + escapeHtml(baseUrl + '/herramientas/show/' + id) + '">Ver</a> ' + '<a class="btn btn--secondary btn--sm" href="' + escapeHtml(baseUrl + '/herramientas/edit/' + id) + '">Editar</a> ' + '<form method="post" action="' + escapeHtml(baseUrl + '/herramientas/delete/' + id) + '" class="inline" data-confirm="¿Eliminar esta herramienta? Esta acción no se puede deshacer.">' + '<button class="btn btn--danger btn--sm" type="submit">Eliminar</button>' + '</form>' + '</td>' + '</tr>'; }); tableBody.innerHTML = html; // Re-inicializar confirmaciones de formularios const confirmForms = tableBody.querySelectorAll('form[data-confirm]'); if (confirmForms && confirmForms.length) { confirmForms.forEach(function(form) { form.addEventListener('submit', function(e) { const msg = form.getAttribute('data-confirm') || '¿Confirmar acción?'; if (!window.confirm(msg)) { e.preventDefault(); } }); }); } } // Función para realizar la búsqueda con AJAX function performSearch() { if (isSearching) return; isSearching = true; const nombre = (filterNombre ? filterNombre.value.trim() : ''); const categoria = (filterCategoria ? filterCategoria.value.trim() : ''); const estado = (filterEstado ? filterEstado.value.trim() : ''); const params = new URLSearchParams(); if (nombre !== '') params.set('nombre', nombre); if (categoria !== '') params.set('categoria', categoria); if (estado !== '') params.set('estado', estado); const url = baseUrl + '/herramientas/search' + (params.toString() ? '?' + params.toString() : ''); fetch(url, { method: 'GET', headers: { 'Accept': 'application/json' }, credentials: 'same-origin' }) .then(function(response) { if (!response.ok) { throw new Error('Error en la búsqueda'); } return response.json(); }) .then(function(data) { renderTableRows(data); isSearching = false; }) .catch(function(error) { console.error('Error:', error); tableBody.innerHTML = '<tr><td colspan="7" class="td-muted">Error al buscar herramientas. Recarga la página.</td></tr>'; isSearching = false; }); } // Búsqueda en tiempo real con debounce para el campo de nombre if (filterNombre) { filterNombre.addEventListener('input', function() { clearTimeout(searchTimeout); searchTimeout = setTimeout(function() { performSearch(); }, 400); // Espera 400ms después de que el usuario deje de escribir }); } // Filtros de categoría y estado se aplican inmediatamente al cambiar if (filterCategoria) { filterCategoria.addEventListener('change', performSearch); } if (filterEstado) { filterEstado.addEventListener('change', performSearch); } })(); </script>
Coded With 💗 by
0x6ick