git pyfleet en gitea.xiberus
This commit is contained in:
Executable
+91
@@ -0,0 +1,91 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ 'Editar' if campus else 'Nuevo' }} Campus{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<div class="page-eyebrow">Campus</div>
|
||||
<div class="page-title">{{ 'Editar campus' if campus else 'Nuevo campus' }}</div>
|
||||
<div class="page-subtitle">
|
||||
{{ 'Modifica los datos del campus #' ~ campus['id'] if campus else 'Completa el formulario para registrar un nuevo campus.' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-card">
|
||||
<form method="POST">
|
||||
|
||||
{% if campus %}
|
||||
<div class="form-group">
|
||||
<label class="form-label">ID</label>
|
||||
<input class="form-input" type="text" value="#{{ campus['id'] }}" disabled>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="nombre">Nombre *</label>
|
||||
<input
|
||||
class="form-input"
|
||||
type="text"
|
||||
id="nombre"
|
||||
name="nombre"
|
||||
placeholder="Ej. Campus Norte"
|
||||
value="{{ campus['nombre'] if campus else request.form.get('nombre','') }}"
|
||||
required
|
||||
autofocus
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="telefono">Teléfono *</label>
|
||||
<input
|
||||
class="form-input"
|
||||
type="tel"
|
||||
id="telefono"
|
||||
name="telefono"
|
||||
placeholder="Ej. +52 55 1234 5678"
|
||||
value="{{ campus['telefono'] if campus else request.form.get('telefono','') }}"
|
||||
required
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="email">Email *</label>
|
||||
<input
|
||||
class="form-input"
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="Ej. [email protected]"
|
||||
value="{{ campus['email'] if campus else request.form.get('email','') }}"
|
||||
required
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="categoria_id">Categoría</label>
|
||||
<div class="select-wrap">
|
||||
<select class="form-input form-select" id="categoria_id" name="categoria_id">
|
||||
<option value="">— Sin categoría —</option>
|
||||
{% for cat in categorias %}
|
||||
<option value="{{ cat['id'] }}"
|
||||
{% if campus and campus['categoria_id'] == cat['id'] %}selected
|
||||
{% elif request.form.get('categoria_id') == cat['id']|string %}selected
|
||||
{% endif %}>
|
||||
{{ cat['tipo'] }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<svg class="select-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||||
<polyline points="6 9 12 15 18 9"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ '💾 Guardar cambios' if campus else '✚ Crear campus' }}
|
||||
</button>
|
||||
<a href="{{ url_for('campus_list') }}" class="btn btn-ghost">Cancelar</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
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 %}
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
{% 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>
|
||||
<div class="td-actions" style="justify-content:flex-end">
|
||||
<a href="/campus/{{ r['id'] }}/editar" class="btn btn-ghost btn-sm">Editar</a>
|
||||
<form method="POST" action="/campus/{{ r['id'] }}/eliminar"
|
||||
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>.
|
||||
{% else %}
|
||||
No hay campus registrados aún.
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user