depor_os/TAREAS.md

149 lines
7.5 KiB
Markdown
Raw Normal View History

2026-03-18 11:47:06 +00:00
# DeporOS — Flutter Port (sc-admin)
> Proyecto: portar el panel de administración PHP (`sc-admin`) a Flutter (web + tablet Android, responsive).
> App en español. Backend: nueva API PHP separada (ya existe parcialmente).
> Sesiones de trabajo: incrementales, pantalla a pantalla.
---
## Contexto técnico
- **PHP origen:** `/home/conejo/private_html/sportscenter/sc-admin/`
- **Flutter destino:** `/home/conejo/public_html/depor_os/`
- **API backend:** proyecto separado (no en este repo), URL base `https://reservas.madriguera.me/2.0`
- **Plataformas:** Web + Tablet Android (responsive, preparado para móvil)
- **Auth:** Bearer token guardado en SharedPreferences. Sin logout en API, sin expiración.
- **UI:** Material 3, seed color `#1565C0` (azul), soporte light/dark
- **Dependencias:** `http ^1.2.0`, `shared_preferences ^2.3.0`, `go_router ^14.0.0`
---
## Módulos identificados en sc-admin
| Módulo | Fichero PHP principal | Estado Flutter |
|---|---|---|
| Login / Auth | `login.php`, `gui/login.php` | ✅ Hecho |
| Shell / Sidebar / Routing | — | ✅ Hecho |
| Dashboard | `main.php`, `index.php` | ✅ Hecho |
| Abonados | `members.php` | ⏳ Pendiente |
| Alumnos | `alumni.php` | ⏳ Pendiente |
| Búsqueda | `search.php` | ⏳ Pendiente |
| Reservas pistas | `booking.php` | ⏳ Pendiente |
| Reservas salas | `booking.php?rooms=true` | ⏳ Pendiente |
| Cursos | `courses.php` | ⏳ Pendiente |
| Recibos | `bills.php` | ⏳ Pendiente |
| Caja | `cash.php` | ⏳ Pendiente |
| Remesas SEPA | `remittance.php` | ⏳ Pendiente |
| Listados | `list.php` | ⏳ Pendiente |
| Utilidades | `extra.php` | ⏳ Pendiente |
| Tornos | `tools.php` | ⏳ Pendiente |
| Administradores / Permisos | `admins.php`, `tools.php` | ⏳ Pendiente |
| Emails | `emails.php` | ⏳ Pendiente |
---
## Tareas
2026-03-22 23:54:12 +00:00
### ✅ Completadas (sesión 5 — 2026-03-22)
- [x] **MEMB-02a** — Acciones de estado en ficha de abonado
- Menú dinámico: muestra "Retener/Cancelar retención" según estado, "Dar de baja/Reactivar" según si está activo
- **Retener / Cancelar retención:** diálogo de confirmación → `POST /members/retener` o `/retener-cancel` → actualiza la ficha en pantalla
- **Dar de baja:** pre-verificación (`POST /members/pre-delete`), alerta si hay recibos pendientes/devueltos, selección de fecha con date picker, motivo opcional → `POST /members/delete`
- **Reactivar:** diálogo de confirmación → `POST /members/recover`
- `Member.copyWith` para campos de estado (retenido, unregDate, unregReason, etc.)
- Mock con estado mutable: los cambios persisten al navegar entre socios
2026-03-18 11:47:06 +00:00
### ✅ Completadas (sesión 4 — 2026-03-18)
- [x] **BOOK-01** — Reservas de pistas (maquetación completa)
- Layout responsive con dos breakpoints independientes:
- **910px (contenido):** panel derecho al lado / debajo del grid
- **900px (ventana):** lista de actividades al lado del calendario / dropdown encima
- Lado izquierdo: calendario (`CalendarDatePicker`) + lista o dropdown de actividades + grid horario/pistas
- Lado derecho (≥910px) / debajo (<910px): 6 botones de acción + 3 botones de pago (Efectivo/Tarjeta/Bizum) + ticket preview
- Grid: celdas se expanden al 100% del ancho disponible; scroll horizontal solo si no caben
- Celdas coloreadas: verde=pagada, rojo=impagada, blanco=libre
- Banner de celebraciones del día
- Patrón mock/prod: `BookingRepository` abstracto, `BookingService` (HTTP), `MockBookingService`
- `lib/models/booking.dart`, `lib/services/booking_repository.dart`, `lib/services/booking_service.dart`
- `lib/services/mock/mock_booking_service.dart`, `lib/screens/booking/booking_screen.dart`
### ✅ Completadas (sesión 3 — 2026-03-18)
- [x] **MEMB-01** — Ficha de abonado (solo lectura)
- Barra de navegación: búsqueda autocomplete + botones primero/anterior/siguiente/último
- Tarjeta de información: número, fecha de alta, tipo, estado (activo/baja/retenido)
- Tarjeta de comentarios: nota heredada, nota interna, lista de comentarios
- Tabla de familiares asociados (read-only): avatar, nombre, DNI, móvil, email, fecha nac.
- Tarjeta de ficha: dirección + datos bancarios
- Responsive: 2 columnas ≥700px / 1 columna en el resto
- `lib/models/member.dart`, `lib/services/member_service.dart`, `lib/screens/members/members_screen.dart`
### ✅ Completadas (sesión 2 — 2026-03-18)
- [x] **DASH-02** — Accesos rápidos en dashboard
- 4 tarjetas: Abonados, Reservas, Recibos por abonado, Caja
- Grid responsive: 4 columnas ≥900px / 2 columnas en el resto
- Cada tarjeta usa un color tonal de Material 3 (primary/secondary/tertiary/error container)
- `lib/screens/dashboard/dashboard_screen.dart`
### ✅ Completadas (sesión 1 — 2026-03-17)
- [x] **AUTH-01** — Pantalla de Login
- `POST /login` con `email`+`password` → `access_token` guardado en SharedPreferences
- Validación, spinner, SnackBar de error, responsive, dark mode
- `lib/core/constants.dart`, `lib/services/auth_service.dart`, `lib/screens/login/login_screen.dart`
- [x] **STRUCT-01** — Estructura base: GoRouter + ShellRoute + AppShell responsive
- Breakpoint sidebar permanente: **800px**. Por debajo → Drawer + AppBar
- `lib/core/router.dart`, `lib/widgets/app_shell.dart`
- [x] **STRUCT-02** — Sidebar navegación multinivel (Material 3)
- Árbol completo extraído del PHP (`sidebar.php`), grupos expandibles con `ExpansionTile`
- Resaltado de ruta activa, auto-expansión del grupo activo, logout en pie
- `lib/models/nav_item.dart`, `lib/navigation/app_navigation.dart`, `lib/widgets/sidebar/`
- [x] **DASH-01** — Dashboard (estructura base)
- Pantalla de inicio con placeholder para accesos rápidos
- Todas las rutas del sidebar apuntan a `PlaceholderScreen` hasta que se implementen
- `lib/screens/dashboard/dashboard_screen.dart`, `lib/screens/placeholder_screen.dart`
### 🔄 En progreso
_(ninguna)_
### ⏳ Pendientes (próximas sesiones)
- [ ] **AUTH-02** — Logo/imagen en pantalla de login (pendiente de asset)
2026-03-22 23:54:12 +00:00
- [x] **MEMB-01** — Listado de abonados (no aplica, no existe en el sistema)
2026-03-18 11:47:06 +00:00
- [ ] **MEMB-02** — Ficha de abonado (detalle + edición)
- [ ] **MEMB-03** — Pre-inscripciones
- [ ] **MEMB-04** — Alta de nuevo abonado
- [ ] **ALUM-01** — Listado de alumnos + altas/bajas
- [ ] **BOOK-01b** — Reservas de pistas (acciones reales: cobrar, devolver, imprimir ticket, QR)
- [ ] **BOOK-02** — Reservas de salas
- [ ] **CAJA-01** — Caja (cobros)
- [ ] **REC-01** — Recibos por abonado
- [ ] **REC-02** — Recibos por actividad
- [ ] **REM-01** — Remesas SEPA
- [ ] **LIST-01** — Listados (varios)
- [ ] **UTIL-01** — Utilidades / parámetros
---
## Decisiones técnicas
- API base: `https://reservas.madriguera.me/2.0`
- Auth: `POST /login``{"access_token": "..."}` Bearer, sin expiración, sin logout en API
- UI: Material 3, seed `#1565C0`, light + dark
- Sidebar breakpoint: 800px (permanente) / <800px (drawer)
- Breakpoints en pantallas: usar `LayoutBuilder` para medir el contenido disponible (ya excluye sidebar). Para breakpoints basados en ventana total, usar `MediaQuery.sizeOf(context).width`. Ejemplo: en BookingScreen, el layout de paneles usa LayoutBuilder (910px contenido), pero el selector actividad usa MediaQuery (900px ventana).
- Patrón mock/prod: `kUseMock` en `constants.dart`, repositorio abstracto en `*_repository.dart`, factory en `service_locator.dart`. Nunca importar mock desde el servicio real ni viceversa.
- Dependencias: `http ^1.2.0`, `shared_preferences ^2.3.0`, `go_router ^14.0.0`
---
## Pendiente de confirmar
- ¿Hay logo para la pantalla de login?