# Sprint 6: Modales CRUD y Filtros Desplegables

## 1. Objetivo del Sprint
Unificar la experiencia de usuario en todas las vistas CRUD reemplazando formularios inline por modales, agregar filtros desplegables en todas las tablas de datos, y corregir inconsistencias entre formularios y base de datos.

## 2. Planificación de Historias de Usuario
| Código | Descripción Técnica | Puntos | Tiempo (Días) |
| :--- | :--- | :---: | :---: |
| **HU26** | Conversión de formularios inline a modales en 5 vistas admin (docentes, usuarios, periodos, franjas, feriados). Patrón: botón "Nuevo X" → modal unificado crear/editar con JS IIFE. | 5 | 2.5 |
| **HU27** | Filtros desplegables en todas las tablas CRUD: 5 vistas admin + 5 vistas coordinador. Selects con opciones reales de la BD vía PHP `array_unique(array_map(...))`. Filtrado 100% client-side. | 5 | 2.0 |
| **HU28** | Corrección de inconsistencias: campos `correo_personal` y `direccion_domicilio` agregados al modal de docentes (admin/coordinador). Formato de hora `HH:MM:SS` → `HH:MM` en inputs de tipo time. JSON del coordinador DocentesController actualizado. | 2 | 0.5 |
| **Total** | | **12 SP** | **5.0 Días** |

## 3. Criterios de Éxito
- Todas las vistas CRUD usan modales unificados para crear y editar.
- Ninguna tabla CRUD queda sin filtros desplegables.
- Los filtros usan `<select>` con opciones reales de la BD (no inputs de texto).
- Los campos `correo_personal` y `direccion_domicilio` son editables en el modal de docentes.
- Los campos de hora se cargan correctamente al editar (sin segundos).
- El JSON de datos para edición incluye todos los campos necesarios.

## 4. Estado de Implementación

| HU       |  Estado   | Detalle |
| :------- | :-------: | :------ |
| **HU26** | **Completado** | 6 vistas convertidas de formularios inline a modales. Cada modal usa IIFE con `abrirModalParaCrear()` + `abrirModalParaEditar(id)`. Mismo modal para crear/editar, cambia título, action URL y botón. Cierre con overlay, tecla Escape y botón X. |
| **HU27** | **Completado** | 10 tablas con filtros desplegables. Cada vista tiene barra de filtros con `<select>` generados por PHP. Opciones: "Todas/Todos" + valores únicos de la BD. Filtrado client-side comparando texto de celdas. |
| **HU28** | **Completado** | Agregados campos `correo_personal` y `direccion_domicilio` a modales de docentes. JS populate actualizado. JSON coordinador incluye esos campos. Horas con `.substring(0, 5)` para quitar segundos. |

## 5. Notas Técnicas

### 5.1 Patrón Modal Unificado
Cada vista CRUD sigue el mismo patrón:
```html
<!-- Botón en header -->
<button id="btn-nuevo-X">Nuevo X</button>

<!-- Modal (mismo para crear/editar) -->
<div id="modal-X" class="fixed inset-0 z-50 hidden">
  <form id="form-X" method="post">
    <!-- campos del formulario -->
  </form>
</div>

<script>
(function() {
  // Variables locales
  var modal = document.getElementById('modal-X');
  var form = document.getElementById('form-X');
  var storeUrl = '<?= url_to("admin.X.store") ?>';
  var data = <?= $XJson ?>;

  function abrirModalParaCrear() { /* ... */ }
  function abrirModalParaEditar(id) { /* ... */ }
  function cerrarModal() { /* ... */ }

  // Event listeners: overlay, close, cancel, Escape
})();
</script>
```

### 5.2 Filtros Desplegables
Cada tabla CRUD tiene una barra de filtros sobre el encabezado:
```html
<div class="p-4 border-b border-slate-100 flex flex-col sm:flex-row gap-3 flex-wrap">
  <select id="filtro-X">
    <option value="">Todas las X</option>
    <?php foreach (array_unique(array_map(fn($item) => $item['campo'] ?? '', $data)) as $valor): ?>
      <?php if ($valor !== ''): ?>
        <option value="<?= esc($valor) ?>"><?= esc($valor) ?></option>
      <?php endif; ?>
    <?php endforeach; ?>
  </select>
  <select id="filtro-estado">
    <option value="">Todos</option>
    <option value="Activo">Activo</option>
    <option value="Inactivo">Inactivo</option>
  </select>
</div>
```

El JS de filtrado compara el valor seleccionado con el contenido de la celda correspondiente:
```javascript
function aplicarFiltros() {
    var valor = filtro.value;
    filas.forEach(function(fila) {
        var celda = fila.children[indiceColumna].textContent.trim();
        fila.style.display = (!valor || celda === valor) ? '' : 'none';
    });
}
filtro.addEventListener('change', aplicarFiltros);
```

### 5.3 Campos Faltantes Corregidos
- **admin/docentes.php** y **coordinador/docentes.php**: Agregados inputs `correo_personal` (email) y `direccion_domicilio` (text) al modal, con populate en JS.
- **Coordinador/DocentesController.php**: Agregados `correo_personal` y `direccion_domicilio` al array `docentesData` que genera el JSON.
- **Formato de hora**: En `admin/franjas.php`, el JS usa `.substring(0, 5)` para convertir `HH:MM:SS` (MySQL TIME) a `HH:MM` (HTML input time).

### 5.4 Vistas con Filtros por Vista

| Vista | Filtros Desplegables |
| :--- | :--- |
| admin/docentes | DNI, Nombres, Usuario, Estado |
| admin/usuarios | Usuario, Persona, Rol, Estado |
| admin/periodos | Código, Estado |
| admin/franjas | Nombre, Tipo, Estado |
| admin/feriados | Descripción, Laborable |
| coordinador/docentes | DNI, Nombres, Usuario, Estado |
| coordinador/cursos | Código, Nombre, Ciclo, Tipo, Estado |
| coordinador/asignaciones | Curso, Docente, Periodo |
| coordinador/horarios | Asignación, Docente, Día, Estado |

## 6. Archivos Modificados

| Archivo | Cambio |
| :--- | :--- |
| `app/Views/admin/docentes.php` | Formulario inline → modal + filtros desplegables |
| `app/Views/admin/usuarios.php` | Formulario inline → modal + filtros desplegables |
| `app/Views/admin/periodos.php` | Formulario inline → modal + filtros desplegables |
| `app/Views/admin/franjas.php` | Formulario inline → modal + filtros desplegables + fix hora |
| `app/Views/admin/feriados.php` | Formulario inline → modal + filtros desplegables |
| `app/Views/coordinador/docentes.php` | Solo lectura + filtros desplegables |
| `app/Views/coordinador/cursos.php` | Filtros desplegables agregados |
| `app/Views/coordinador/asignaciones.php` | Filtros desplegables agregados |
| `app/Views/coordinador/horarios.php` | Filtros desplegables agregados |
| `app/Controllers/Coordinador/DocentesController.php` | JSON actualizado con `correo_personal` y `direccion_domicilio` |

## 7. Impacto
- **Vistas con modales:** 6 (antes usaban formularios inline)
- **Vistas con filtros desplegables:** 10 (todas las tablas CRUD)
- **Campos recuperados:** 2 (`correo_personal`, `direccion_domicilio`)
- **Bugfixes:** 2 (formato hora, JSON incompleto)
- **Archivos modificados:** 11

---
- Regresar al [[index|Inicio]]
