git pyfleet en gitea.xiberus
This commit is contained in:
Executable
+120
@@ -0,0 +1,120 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Campus{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div class="page-eyebrow">Base de datos</div>
|
||||
<div class="page-title">Campus</div>
|
||||
<div class="page-subtitle">Gestiona los registros de campus: búsqueda, alta, edición y baja.</div>
|
||||
</div>
|
||||
|
||||
<div class="crud-toolbar">
|
||||
<form method="GET" action="{{ url_for('campus_list') }}" class="search-wrap" id="searchForm">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
|
||||
</svg>
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
id="searchInput"
|
||||
placeholder="Buscar por ID, nombre, teléfono o email…"
|
||||
value="{{ q }}"
|
||||
autocomplete="off"
|
||||
>
|
||||
</form>
|
||||
<a href="{{ url_for('campus_nuevo') }}" class="btn btn-primary">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
Nuevo campus
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nombre</th>
|
||||
<th>Teléfono</th>
|
||||
<th>Email</th>
|
||||
<th>Categoría</th>
|
||||
<th style="text-align:right">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbody">
|
||||
{% if rows %}
|
||||
{% for r in rows %}
|
||||
<tr data-id="{{ r['id'] }}">
|
||||
<td class="td-id">#{{ r['id'] }}</td>
|
||||
<td><strong>{{ r['nombre'] }}</strong></td>
|
||||
<td>{{ r['telefono'] }}</td>
|
||||
<td>{{ r['email'] }}</td>
|
||||
<td>{% if r['categoria'] %}<span style="background:rgba(92,110,248,.12);color:var(--accent);font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;border:1px solid rgba(92,110,248,.25)">{{ r['categoria'] }}</span>{% else %}<span style="color:var(--muted);font-size:12px">—</span>{% endif %}</td>
|
||||
|
||||
<!-- <td>{{ r['categoria'] }}</td> -->
|
||||
<td>
|
||||
<div class="td-actions" style="justify-content:flex-end">
|
||||
<a href="{{ url_for('campus_editar', id=r['id']) }}" class="btn btn-ghost btn-sm">Editar</a>
|
||||
<form method="POST" action="{{ url_for('campus_eliminar', id=r['id']) }}"
|
||||
onsubmit="return confirm('¿Eliminar «{{ r['nombre'] }}»? Esta acción no se puede deshacer.')">
|
||||
<button type="submit" class="btn btn-danger btn-sm">Eliminar</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<div class="empty-state">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<circle cx="12" cy="12" r="10"/><line x1="8" y1="12" x2="16" y2="12"/>
|
||||
</svg>
|
||||
{% if q %}
|
||||
No se encontraron resultados para <strong>"{{ q }}"</strong>.
|
||||
<br><a href="{{ url_for('campus_list') }}" style="color:var(--accent);text-decoration:none">Ver todos</a>
|
||||
{% else %}
|
||||
No hay campus registrados aún.
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if rows %}
|
||||
<p id="counter" style="margin-top:12px;font-size:12px;color:var(--muted)">
|
||||
{{ rows|length }} registro{{ 's' if rows|length != 1 }}
|
||||
{% if q %} — filtrado por «{{ q }}»{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
var input = document.getElementById('searchInput');
|
||||
var tbody = document.getElementById('tbody');
|
||||
var counter = document.getElementById('counter');
|
||||
var timer;
|
||||
|
||||
/* Actualiza la tabla sin recargar la página (el foco no se pierde) */
|
||||
input.addEventListener('input', function() {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function() { buscar(input.value.trim()); }, 300);
|
||||
});
|
||||
|
||||
function buscar(q) {
|
||||
var url = '{{ url_for("campus_list") }}?q=' + encodeURIComponent(q) + '&solo_filas=1';
|
||||
fetch(url)
|
||||
.then(function(r) { return r.text(); })
|
||||
.then(function(html) {
|
||||
tbody.innerHTML = html;
|
||||
if (counter) {
|
||||
var filas = tbody.querySelectorAll('tr[data-id]').length;
|
||||
counter.textContent = filas + ' registro' + (filas !== 1 ? 's' : '')
|
||||
+ (q ? ' — filtrado por «' + q + '»' : '');
|
||||
counter.style.display = filas ? '' : 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user