feat(dashboard): eliminar boton de reserva en panel docente y agregar monitoreo de aulas asignadas y sin asignar con percentiles en admin y bedelia

This commit is contained in:
2026-09-19 11:42:02 -03:00
parent b9a11d810a
commit 620e470614
3 changed files with 303 additions and 31 deletions
+226 -26
View File
@@ -178,6 +178,117 @@
</div>
</div>
<!-- Panel de Balance y Percentiles de Asignación de Aulas (Admin) -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-body-tertiary border-0 py-3 d-flex justify-content-between align-items-center flex-wrap gap-2">
<div class="d-flex align-items-center gap-2">
<i class="bi bi-pie-chart-fill text-primary fs-5"></i>
<div>
<h5 class="mb-0 h6 fw-bold">Estado y Percentiles de Asignación de Aulas Físicas</h5>
<small class="text-muted">Balance de capacidad instalada en Edificio Central (Total: {{ stats.physical_classrooms }} aulas físicas)</small>
</div>
</div>
<div class="d-flex gap-2 align-items-center flex-wrap">
<span class="badge bg-success-subtle text-success border border-success-subtle px-2 py-1">
<i class="bi bi-check2-circle me-1"></i>{{ stats.assigned_classrooms }} Asignadas ({{ stats.assigned_classrooms_pct }}%)
</span>
<span class="badge bg-warning-subtle text-warning-emphasis border border-warning-subtle px-2 py-1">
<i class="bi bi-door-open me-1"></i>{{ stats.unassigned_classrooms }} Sin Asignar ({{ stats.unassigned_classrooms_pct }}%)
</span>
</div>
</div>
<div class="card-body p-3">
<div class="row g-3 align-items-center">
<!-- Tarjeta 1: Asignadas -->
<div class="col-md-3">
<a href="/classrooms/list_classrooms?view_mode=physical" class="text-decoration-none text-reset d-block h-100">
<div class="p-3 rounded bg-success bg-opacity-10 border border-success-subtle h-100 text-center transition-all">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-success small fw-bold text-uppercase">Aulas Asignadas</span>
<span class="badge bg-success text-white font-monospace">{{ stats.assigned_classrooms_pct }}%</span>
</div>
<div class="d-flex align-items-baseline justify-content-center gap-2 my-2">
<h2 class="mb-0 fw-bold text-success">{{ stats.assigned_classrooms }}</h2>
<span class="text-muted small">/ {{ stats.physical_classrooms }} aulas</span>
</div>
<div class="text-success small pt-2 border-top border-success-subtle d-flex align-items-center justify-content-between">
<span>Con cursadas activas</span>
<i class="bi bi-arrow-right"></i>
</div>
</div>
</a>
</div>
<!-- Tarjeta 2: Sin Asignar -->
<div class="col-md-3">
<a href="/classrooms/list_classrooms?view_mode=physical" class="text-decoration-none text-reset d-block h-100">
<div class="p-3 rounded bg-warning bg-opacity-10 border border-warning-subtle h-100 text-center transition-all">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-warning-emphasis small fw-bold text-uppercase">Aulas Sin Asignar</span>
<span class="badge bg-warning text-dark font-monospace">{{ stats.unassigned_classrooms_pct }}%</span>
</div>
<div class="d-flex align-items-baseline justify-content-center gap-2 my-2">
<h2 class="mb-0 fw-bold text-warning-emphasis">{{ stats.unassigned_classrooms }}</h2>
<span class="text-muted small">/ {{ stats.physical_classrooms }} aulas</span>
</div>
<div class="text-warning-emphasis small pt-2 border-top border-warning-subtle d-flex align-items-center justify-content-between">
<span>Espacios disponibles</span>
<i class="bi bi-arrow-right"></i>
</div>
</div>
</a>
</div>
<!-- Tarjeta 3: Barras Comparativas de Percentil (Cuatrimestre y Hoy) -->
<div class="col-md-6">
<div class="p-3 rounded bg-body-tertiary border h-100 d-flex flex-column justify-content-center">
<!-- Nivel 1: Cuatrimestre -->
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="small fw-semibold text-body">
<i class="bi bi-calendar-check me-1 text-primary"></i>Planificación Cuatrimestral:
</span>
<span class="small font-monospace text-muted">
<strong class="text-success">{{ stats.assigned_classrooms_pct }}%</strong> Asignado ({{ stats.assigned_classrooms }} aulas) · <strong class="text-warning-emphasis">{{ stats.unassigned_classrooms_pct }}%</strong> Libre ({{ stats.unassigned_classrooms }} aula)
</span>
</div>
<div class="progress mb-3" style="height: 14px;">
<div class="progress-bar bg-success progress-bar-striped" role="progressbar" style="width: {{ stats.assigned_classrooms_pct }}%;"
aria-valuenow="{{ stats.assigned_classrooms_pct }}" aria-valuemin="0" aria-valuemax="100"
title="Asignadas: {{ stats.assigned_classrooms }} ({{ stats.assigned_classrooms_pct }}%)">
{{ stats.assigned_classrooms_pct }}%
</div>
<div class="progress-bar bg-warning" role="progressbar" style="width: {{ stats.unassigned_classrooms_pct }}%;"
aria-valuenow="{{ stats.unassigned_classrooms_pct }}" aria-valuemin="0" aria-valuemax="100"
title="Sin Asignar: {{ stats.unassigned_classrooms }} ({{ stats.unassigned_classrooms_pct }}%)">
{{ stats.unassigned_classrooms_pct }}%
</div>
</div>
<!-- Nivel 2: Día Operativo -->
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="small fw-semibold text-body">
<i class="bi bi-clock-history me-1 text-info"></i>Ocupación Operativa de Hoy:
</span>
<span class="small font-monospace text-muted">
<strong class="text-info">{{ stats.assigned_today_classrooms }}</strong> en uso ({{ stats.assigned_today_pct }}%) · <strong class="text-secondary">{{ stats.unassigned_today_classrooms }}</strong> libres ({{ stats.unassigned_today_pct }}%)
</span>
</div>
<div class="progress" style="height: 10px;">
<div class="progress-bar bg-info" role="progressbar" style="width: {{ stats.assigned_today_pct }}%;"
aria-valuenow="{{ stats.assigned_today_pct }}" aria-valuemin="0" aria-valuemax="100"
title="En uso hoy: {{ stats.assigned_today_classrooms }}">
</div>
<div class="progress-bar bg-secondary-subtle" role="progressbar" style="width: {{ stats.unassigned_today_pct }}%;"
aria-valuenow="{{ stats.unassigned_today_pct }}" aria-valuemin="0" aria-valuemax="100"
title="Libres hoy: {{ stats.unassigned_today_classrooms }}">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Admin Visual Menu Launchpad -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-body-tertiary border-0 py-3">
@@ -411,6 +522,117 @@
</div>
</div>
<!-- Panel de Balance y Percentiles de Asignación de Aulas (Bedelía) -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-body-tertiary border-0 py-3 d-flex justify-content-between align-items-center flex-wrap gap-2">
<div class="d-flex align-items-center gap-2">
<i class="bi bi-pie-chart-fill text-warning fs-5"></i>
<div>
<h5 class="mb-0 h6 fw-bold">Gestión y Percentiles de Asignación de Aulas (Bedelía)</h5>
<small class="text-muted">Control de asignación de espacios físicos (Total: {{ stats.physical_classrooms }} aulas físicas en Sede Central)</small>
</div>
</div>
<div class="d-flex gap-2 align-items-center flex-wrap">
<span class="badge bg-success-subtle text-success border border-success-subtle px-2 py-1">
<i class="bi bi-check2-circle me-1"></i>{{ stats.assigned_classrooms }} Asignadas ({{ stats.assigned_classrooms_pct }}%)
</span>
<span class="badge bg-warning-subtle text-warning-emphasis border border-warning-subtle px-2 py-1">
<i class="bi bi-door-open me-1"></i>{{ stats.unassigned_classrooms }} Sin Asignar ({{ stats.unassigned_classrooms_pct }}%)
</span>
</div>
</div>
<div class="card-body p-3">
<div class="row g-3 align-items-center">
<!-- Tarjeta 1: Asignadas -->
<div class="col-md-3">
<a href="/classrooms/list_classrooms?view_mode=physical" class="text-decoration-none text-reset d-block h-100">
<div class="p-3 rounded bg-success bg-opacity-10 border border-success-subtle h-100 text-center transition-all">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-success small fw-bold text-uppercase">Aulas Asignadas</span>
<span class="badge bg-success text-white font-monospace">{{ stats.assigned_classrooms_pct }}%</span>
</div>
<div class="d-flex align-items-baseline justify-content-center gap-2 my-2">
<h2 class="mb-0 fw-bold text-success">{{ stats.assigned_classrooms }}</h2>
<span class="text-muted small">/ {{ stats.physical_classrooms }} aulas</span>
</div>
<div class="text-success small pt-2 border-top border-success-subtle d-flex align-items-center justify-content-between">
<span>Ver aulas con cursada</span>
<i class="bi bi-arrow-right"></i>
</div>
</div>
</a>
</div>
<!-- Tarjeta 2: Sin Asignar -->
<div class="col-md-3">
<a href="/schedule/add_reservation" class="text-decoration-none text-reset d-block h-100">
<div class="p-3 rounded bg-warning bg-opacity-10 border border-warning-subtle h-100 text-center transition-all">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-warning-emphasis small fw-bold text-uppercase">Aulas Sin Asignar</span>
<span class="badge bg-warning text-dark font-monospace">{{ stats.unassigned_classrooms_pct }}%</span>
</div>
<div class="d-flex align-items-baseline justify-content-center gap-2 my-2">
<h2 class="mb-0 fw-bold text-warning-emphasis">{{ stats.unassigned_classrooms }}</h2>
<span class="text-muted small">/ {{ stats.physical_classrooms }} aulas</span>
</div>
<div class="text-warning-emphasis small pt-2 border-top border-warning-subtle d-flex align-items-center justify-content-between">
<span>Asignar espacio libre</span>
<i class="bi bi-plus-circle"></i>
</div>
</div>
</a>
</div>
<!-- Tarjeta 3: Barras Comparativas de Percentil (Cuatrimestre y Hoy) -->
<div class="col-md-6">
<div class="p-3 rounded bg-body-tertiary border h-100 d-flex flex-column justify-content-center">
<!-- Nivel 1: Cuatrimestre -->
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="small fw-semibold text-body">
<i class="bi bi-calendar-check me-1 text-primary"></i>Asignación Cuatrimestral:
</span>
<span class="small font-monospace text-muted">
<strong class="text-success">{{ stats.assigned_classrooms_pct }}%</strong> Asignado ({{ stats.assigned_classrooms }} aulas) · <strong class="text-warning-emphasis">{{ stats.unassigned_classrooms_pct }}%</strong> Disponible ({{ stats.unassigned_classrooms }} aula)
</span>
</div>
<div class="progress mb-3" style="height: 14px;">
<div class="progress-bar bg-success progress-bar-striped" role="progressbar" style="width: {{ stats.assigned_classrooms_pct }}%;"
aria-valuenow="{{ stats.assigned_classrooms_pct }}" aria-valuemin="0" aria-valuemax="100"
title="Asignadas: {{ stats.assigned_classrooms }} ({{ stats.assigned_classrooms_pct }}%)">
{{ stats.assigned_classrooms_pct }}%
</div>
<div class="progress-bar bg-warning" role="progressbar" style="width: {{ stats.unassigned_classrooms_pct }}%;"
aria-valuenow="{{ stats.unassigned_classrooms_pct }}" aria-valuemin="0" aria-valuemax="100"
title="Sin Asignar: {{ stats.unassigned_classrooms }} ({{ stats.unassigned_classrooms_pct }}%)">
{{ stats.unassigned_classrooms_pct }}%
</div>
</div>
<!-- Nivel 2: Día Operativo -->
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="small fw-semibold text-body">
<i class="bi bi-clock-history me-1 text-info"></i>Ocupación Operativa de Hoy:
</span>
<span class="small font-monospace text-muted">
<strong class="text-info">{{ stats.assigned_today_classrooms }}</strong> en uso ({{ stats.assigned_today_pct }}%) · <strong class="text-secondary">{{ stats.unassigned_today_classrooms }}</strong> libres ({{ stats.unassigned_today_pct }}%)
</span>
</div>
<div class="progress" style="height: 10px;">
<div class="progress-bar bg-info" role="progressbar" style="width: {{ stats.assigned_today_pct }}%;"
aria-valuenow="{{ stats.assigned_today_pct }}" aria-valuemin="0" aria-valuemax="100"
title="En uso hoy: {{ stats.assigned_today_classrooms }}">
</div>
<div class="progress-bar bg-secondary-subtle" role="progressbar" style="width: {{ stats.unassigned_today_pct }}%;"
aria-valuenow="{{ stats.unassigned_today_pct }}" aria-valuemin="0" aria-valuemax="100"
title="Libres hoy: {{ stats.unassigned_today_classrooms }}">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bedelía Operational Launchpad -->
<div class="card border-0 shadow-sm mb-4">
<div class="card-header bg-body-tertiary border-0 py-3">
@@ -537,7 +759,7 @@
<!-- Docente KPI Cards -->
<div class="row mb-4 g-3">
<div class="col-md-6 col-xl-3">
<div class="col-md-4 col-xl-4">
<div class="card border-0 shadow-sm h-100 dashboard-stat-card transition-all glass-card">
<div class="card-body p-3">
<div class="d-flex justify-content-between align-items-center">
@@ -557,7 +779,7 @@
</div>
</div>
<div class="col-md-6 col-xl-3">
<div class="col-md-4 col-xl-4">
<a href="/schedule/list_reservations" class="text-decoration-none text-reset d-block h-100">
<div class="card border-0 shadow-sm h-100 dashboard-stat-card transition-all glass-card">
<div class="card-body p-3">
@@ -579,8 +801,8 @@
</a>
</div>
<div class="col-md-6 col-xl-3">
<a href="/classrooms/list_classrooms" class="text-decoration-none text-reset d-block h-100">
<div class="col-md-4 col-xl-4">
<a href="/classrooms/list_classrooms?view_mode=virtual" class="text-decoration-none text-reset d-block h-100">
<div class="card border-0 shadow-sm h-100 dashboard-stat-card transition-all glass-card">
<div class="card-body p-3">
<div class="d-flex justify-content-between align-items-center">
@@ -600,28 +822,6 @@
</div>
</a>
</div>
<div class="col-md-6 col-xl-3">
<a href="/schedule/add_reservation" class="text-decoration-none text-reset d-block h-100">
<div class="card border-0 shadow-sm h-100 dashboard-stat-card transition-all bg-primary bg-opacity-10 border border-primary-subtle">
<div class="card-body p-3">
<div class="d-flex justify-content-between align-items-center">
<div>
<span class="text-primary small fw-bold text-uppercase">Nueva Solicitud</span>
<h4 class="mb-0 fw-bold mt-1 text-primary">Reservar Aula</h4>
</div>
<div class="bg-primary text-white rounded-circle p-3">
<i class="bi bi-plus-lg fs-3"></i>
</div>
</div>
<div class="d-flex align-items-center justify-content-between pt-3 mt-2 border-top text-primary small fw-bold">
<span>Solicitar espacio para clase</span>
<i class="bi bi-arrow-right"></i>
</div>
</div>
</div>
</a>
</div>
</div>
<!-- Docente Launchpad -->