# 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 ### ✅ 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) - [ ] **MEMB-01** — Listado de abonados - [ ] **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?