feat: refactorizar espacios fisicos desacoplando Edificio, Piso y Aula con selectores en cascada y filtros

This commit is contained in:
Carlos Tello
2026-09-03 05:18:01 -03:00
parent 5e0b905e55
commit 6ccc9e8c87
11 changed files with 1093 additions and 522 deletions
+52 -19
View File
@@ -80,8 +80,21 @@
</div>
</div>
<!-- Second row of filters: Floor & Hide Virtual -->
<!-- Second row of filters: Building, Floor & Hide Virtual -->
<div class="row g-2 align-items-center mt-2 pt-2 border-top">
<!-- Filter by Building -->
<div class="col-lg-3 col-md-4">
<label for="filterBuilding" class="form-label small fw-bold text-muted mb-1">
<i class="bi bi-buildings text-primary me-1"></i>{% trans %}Filtrar por Edificio{% endtrans %}
</label>
<select id="filterBuilding" class="form-select form-select-sm">
<option value="">{% trans %}Todos los edificios{% endtrans %}</option>
{% for b in buildings %}
<option value="{{ b.name }}">{{ b.name }}</option>
{% endfor %}
</select>
</div>
<!-- Filter by Floor -->
<div class="col-lg-3 col-md-4">
<label for="filterFloor" class="form-label small fw-bold text-muted mb-1">
@@ -90,26 +103,25 @@
<select id="filterFloor" class="form-select form-select-sm">
<option value="">{% trans %}Todos los pisos{% endtrans %}</option>
{% for f in available_floors %}
<option value="{{ f }}">{% if f == 0 %}{% trans %}Planta Baja (Piso 0){% endtrans %}{% else %}{% trans %}Piso{% endtrans %} {{ f }}{% endif %}</option>
<option value="{{ f }}">{% if f == '0' or f == 0 or f == 'PB' %}{% trans %}Planta Baja{% endtrans %}{% else %}{% trans %}Piso{% endtrans %} {{ f }}{% endif %}</option>
{% endfor %}
</select>
</div>
<!-- Hide Virtual Classrooms Toggle -->
<div class="col-lg-6 col-md-5 pt-md-3">
<div class="col-lg-4 col-md-4 pt-md-3">
<div class="form-check form-switch pt-1">
<input class="form-check-input" type="checkbox" role="switch" id="filterHideVirtual">
<label class="form-check-label fw-semibold small text-dark" for="filterHideVirtual">
<i class="bi bi-laptop me-1 text-primary"></i>{% trans %}Ocultar Aulas Virtuales{% endtrans %}
<span class="badge bg-secondary-subtle text-secondary border ms-1" style="font-size: 0.72rem;">{% trans %}Capacidad ilimitada{% endtrans %}</span>
</label>
</div>
</div>
<!-- Reset Filters Button -->
<div class="col-lg-3 col-md-3 text-md-end pt-md-3">
<button type="button" id="btnResetFilters" class="btn btn-outline-secondary btn-sm px-3" title="{% trans %}Restablecer filtros{% endtrans %}">
<i class="bi bi-arrow-counterclockwise me-1"></i>{% trans %}Limpiar Filtros{% endtrans %}
<div class="col-lg-2 col-md-12 text-md-end pt-md-3">
<button type="button" class="btn btn-outline-secondary btn-sm w-100 w-md-auto" id="btnResetFilters">
<i class="bi bi-x-circle me-1"></i>{% trans %}Limpiar{% endtrans %}
</button>
</div>
</div>
@@ -209,16 +221,19 @@
</div>
</div>
<!-- 📍 Espacio / Aula / Virtual -->
<div class="d-flex align-items-center gap-3">
<div class="gc-icon-circle text-danger" id="previewLocationIcon">
<!-- 📍 Espacio / Aula / Virtual Desglosado -->
<div class="d-flex align-items-start gap-3">
<div class="gc-icon-circle text-danger mt-1" id="previewLocationIcon">
<i class="bi bi-geo-alt fs-5"></i>
</div>
<div class="flex-grow-1">
<div class="fw-semibold text-body" id="previewClassroom">Aula 304</div>
<small class="text-muted" id="previewBuilding">Piso 3 · Edificio Central (Perón 802)</small>
<div id="previewVirtualWrapper" class="d-none mt-1">
<span class="badge bg-primary-subtle text-primary border">
<div class="d-flex flex-wrap gap-1 mb-1" id="previewLocationBadges">
<span class="badge bg-primary-subtle text-primary border" id="previewBadgeBuilding">🏢 Edificio Central</span>
<span class="badge bg-secondary-subtle text-secondary border" id="previewBadgeFloor">🪜 Piso 3</span>
<span class="badge bg-success-subtle text-success border" id="previewBadgeRoom">🚪 Aula 304</span>
</div>
<div id="previewVirtualWrapper" class="d-none">
<span class="badge bg-info-subtle text-info border">
<i class="bi bi-camera-video me-1"></i>{% trans %}Campus Virtual UniCABA (Teams / Moodle){% endtrans %}
</span>
</div>
@@ -685,6 +700,7 @@ document.addEventListener('DOMContentLoaded', function() {
var filterSubj = document.getElementById('filterSubject');
var filterCar = document.getElementById('filterCareer');
var filterShift = document.getElementById('filterShift');
var filterBuilding = document.getElementById('filterBuilding');
var filterFloor = document.getElementById('filterFloor');
var filterHideVirtual = document.getElementById('filterHideVirtual');
var activeBadge = document.getElementById('activeFilterBadge');
@@ -704,6 +720,9 @@ document.addEventListener('DOMContentLoaded', function() {
if (filterCar.value && filterCar.selectedOptions[0]) {
parts.push('Carrera: ' + filterCar.selectedOptions[0].text.trim());
}
if (filterBuilding && filterBuilding.value) {
parts.push('Edificio: ' + filterBuilding.value);
}
if (filterShift && filterShift.value) {
parts.push('Turno ' + filterShift.value);
}
@@ -763,6 +782,7 @@ document.addEventListener('DOMContentLoaded', function() {
subject_id: filterSubj.value || '',
career_id: filterCar.value || '',
shift: (filterShift ? filterShift.value : '') || '',
building: (filterBuilding ? filterBuilding.value : '') || '',
floor: (filterFloor ? filterFloor.value : '') || '',
hide_virtual: (filterHideVirtual && filterHideVirtual.checked) ? '1' : ''
});
@@ -922,18 +942,24 @@ document.addEventListener('DOMContentLoaded', function() {
document.getElementById('previewDateFull').textContent = `Horario académico registrado`;
}
// Espacio Asignado
// Espacio Asignado Desglosado con Badges
var locIcon = document.getElementById('previewLocationIcon');
var virtualWrap = document.getElementById('previewVirtualWrapper');
var badgeB = document.getElementById('previewBadgeBuilding');
var badgeF = document.getElementById('previewBadgeFloor');
var badgeR = document.getElementById('previewBadgeRoom');
if (isVirtual) {
if (locIcon) locIcon.innerHTML = '<i class="bi bi-camera-video fs-5 text-primary"></i>';
document.getElementById('previewClassroom').textContent = 'Campus Virtual';
document.getElementById('previewBuilding').textContent = 'Entorno Digital UniCABA';
if (badgeB) badgeB.textContent = '🏢 Campus Virtual';
if (badgeF) badgeF.textContent = '🪜 Remoto';
if (badgeR) badgeR.textContent = '🚪 ' + classroom;
if (virtualWrap) virtualWrap.classList.remove('d-none');
} else {
if (locIcon) locIcon.innerHTML = '<i class="bi bi-geo-alt fs-5 text-danger"></i>';
document.getElementById('previewClassroom').textContent = classroom;
document.getElementById('previewBuilding').textContent = `${ext.floor !== null && ext.floor !== undefined ? (ext.floor === 0 ? 'Planta Baja' : 'Piso ' + ext.floor) + ' · ' : ''}${building}`;
if (badgeB) badgeB.textContent = '🏢 ' + (building || 'Edificio Central');
if (badgeF) badgeF.textContent = '🪜 ' + (ext.floor || 'Planta Baja');
if (badgeR) badgeR.textContent = '🚪 ' + classroom;
if (virtualWrap) virtualWrap.classList.add('d-none');
}
@@ -987,6 +1013,12 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
if (filterBuilding) {
filterBuilding.addEventListener('change', function() {
calendar.refetchEvents();
});
}
if (filterFloor) {
filterFloor.addEventListener('change', function() {
calendar.refetchEvents();
@@ -1004,6 +1036,7 @@ document.addEventListener('DOMContentLoaded', function() {
filterSubj.value = '';
filterCar.value = '';
if (filterShift) filterShift.value = '';
if (filterBuilding) filterBuilding.value = '';
if (filterFloor) filterFloor.value = '';
if (filterHideVirtual) filterHideVirtual.checked = false;
calendar.refetchEvents();