# Rediseño de los dashboards de la PWA por rol (#43 · Fase B)

- **Fecha:** 2026-07-23
- **Issue:** [#43](https://github.com/jdredondo/credify/issues/43) — UI/UX: modo oscuro iOS-26 aqua-emerald + dashboard moderno (Fase B)
- **Rama:** `feat/pwa-dashboards-redesign`
- **Estado:** diseño aprobado en brainstorming (Approach C), pendiente de plan de implementación

## Objetivo

Redefinir los **tres dashboards** de la PWA (admin, supervisor, cobrador) en **fondo y forma**: repensar la arquitectura de información (qué ve y qué puede hacer cada rol) *y* elevar la estética a nivel "app premium", inspirados en la referencia bancaria (Banco Popular) que aportó el usuario. Debe verse de primera clase en **modo claro y oscuro** (la PWA ya es theme-aware). La Fase A del #43 (tokens aqua-emerald, glass, contraste) ya está desplegada; esto es la Fase B.

## Principio rector: cada rol ve solo lo suyo

La restricción central del rediseño. El alcance de datos por rol (ya lo aplica el backend vía `RoleAwareQueries` y los métodos `*Dashboard()` de `DashboardController`) **no se debe romper** al enriquecer las vistas:

| Dato | Admin (dueño) | Supervisor (equipo) | Cobrador (personal) |
|---|:---:|:---:|:---:|
| Caja / Patrimonio / **Utilidad** / Gastos operativos | ✅ | ❌ | ❌ |
| Cobrado hoy · cartera · mora | ✅ empresa | ✅ **su equipo** | ✅ **solo suyo** |
| Desglose por cobrador | ✅ | ✅ | ❌ |
| Meta / ruta / vencido personal | — | — | ✅ |
| Gastos pendientes de aprobación | ✅ | ✅ | ❌ |

La **utilidad, la caja y los gastos operativos son P&L del dueño** → solo admin. El supervisor ve el rendimiento **agregado de su equipo + desglose por cobrador**, nunca el P&L. El cobrador ve **exclusivamente** su meta, su cobrado y su cartera; nada de la empresa ni de compañeros.

## Estructura compartida (Approach C)

Los tres dashboards comparten el mismo **esqueleto** (da la consistencia entre roles que pide el #43), pero se llena con datos y acciones distintas por rol:

```
┌─────────────────────────────────────┐
│ Header  (saludo · fecha · badge rol · campana)      │
├─────────────────────────────────────┤
│ Quick-actions   (3 acciones + "Más")                │
├─────────────────────────────────────┤
│ Carrusel de KPIs   (deslizable ←→, número completo) │
├─────────────────────────────────────┤
│ [Alerta gastos por aprobar]  (admin/supervisor, si hay)│
├─────────────────────────────────────┤
│ Secciones del rol   (Hoy · Cartera · Equipo · …)    │
└─────────────────────────────────────┘
        Bottom nav (existente)
```

### Carrusel de KPIs (cambio de diseño clave)

Reemplaza la grilla fija de 3 tarjetas abreviadas por un **carrusel horizontal deslizable** (`overflow-x` + `scroll-snap-type: x mandatory`):

- Tarjetas **más anchas** (~152px) que muestran el **número completo** en pesos (`$12.450.000`, no `$12,45M`).
- Cabe **más de 3 KPIs** sin apretar; un "peek" de la siguiente tarjeta señala que hay más.
- Cada tarjeta: etiqueta (uppercase, muted) · número (`tabular-nums`) · línea de contexto/tendencia opcional (▲/▼ %).
- Una tarjeta puede ir **acentuada** (borde/fondo aqua más fuerte) para marcar el KPI protagonista del rol.

### Quick-actions (gateadas por permiso real)

Fila de 3 acciones visibles + "Más" (bottom-sheet con las secundarias del rol). Basadas en la matriz **real** de `AuthController::getPermissionsForRole()` y ancladas a rutas **existentes** de la PWA:

| Rol | Acción 1 | Acción 2 | Acción 3 | "Más" (sheet) |
|---|---|---|---|---|
| **Admin** | Registrar pago → `/pwa/collections` | Nuevo crédito → `/pwa/credits/new` | Registrar gasto → `/pwa/expenses/new` | Nuevo cliente · Aprobaciones · Finanzas · Cartera · Socios |
| **Supervisor** | Nuevo crédito → `/pwa/credits/new` | Cobros del día → `/pwa/collections` | Equipo → `/pwa/team` | Nuevo cliente · Registrar visita · Aprobaciones · Cartera |
| **Cobrador** | Registrar pago → `/pwa/collections` | Mi ruta → `/pwa/credits/order` | Nuevo cliente → `/pwa/clients/new` | Nuevo crédito · Registrar visita |

Notas de permisos (fuente: `getPermissionsForRole`):
- **El supervisor NO puede registrar pagos** (`can_register_payments` = collector + admin). Por eso su acción de gestión es *crear/monitorear*, no cobrar.
- Todos pueden **crear crédito y cliente** (`can_create_credits`, `can_create_clients` = los tres).
- No existe pantalla "nuevo pago" suelta: registrar un pago siempre pasa por un crédito, así que "Registrar pago" abre `/pwa/collections` (a quién cobrar hoy).
- Cada acción se renderiza solo si el flag de permiso correspondiente está en el payload de `/auth/me` (ya expuesto al front vía el store `auth`).

## Especificación por rol

### Admin (dueño — P&L completo)
- **KPIs (carrusel):** Patrimonio · **Utilidad mes** · Caja · Mora.
- **Secciones:**
  - **Hoy** — cobrado hoy vs meta (barra) + desembolsado + gastos del día.
  - **Cartera** — saldo por cobrar con **sparkline de tendencia** + barra de composición vigente/vencida.
  - **Alerta** gastos por aprobar (si hay).

### Supervisor (equipo — sin P&L del dueño)
- **KPIs (carrusel):** Cobrado equipo · Cartera vigente · Mora equipo · Cobradores (activos/total).
- **Secciones:**
  - **Rendimiento por cobrador** (sección distintiva) — lista de sus cobradores: avatar, cobrado/meta del día, mini-barra, %.
  - **Cartera del equipo** — composición vigente/vencida.
  - **Alerta** gastos por aprobar (si hay).
- **Nunca:** caja, utilidad, gastos operativos.

### Cobrador (personal — solo su ruta)
- **KPIs (carrusel):** Meta hoy · Cobrado hoy · Mi vencido · Semana.
- **Secciones (conserva lo que ya funciona hoy):**
  - **Meta del día** — tarjeta de progreso (cobrado vs meta, % avance, faltan). *Existe.*
  - **Mi cartera vencida** — aging buckets. *Existe.*
  - **Mi semana** — `WeeklyProgressChart`. *Existe.*
  - **Pagos por sincronizar** — banner offline. *Existe.*
- **Nunca:** datos de empresa ni de compañeros.

## Arquitectura frontend

Extraer componentes compartidos (hoy cada Home repite markup inline) para aislar responsabilidades y evitar deriva entre roles:

- `components/home/DashboardHeader.vue` — saludo, fecha, badge de rol, campana. Extraído de `HomeView.vue`.
- `components/dashboard/QuickActionRow.vue` — recibe `actions: [{icon, label, to, permission}]`; filtra por permiso.
- `components/dashboard/KpiCarousel.vue` + `KpiCard.vue` — carrusel deslizable; `KpiCard` recibe `{label, value, hint, trend, accent}`.
- `components/dashboard/SectionCard.vue` — wrapper glass con título (unifica el look de tarjetas de sección).
- `components/dashboard/PendingApprovalsAlert.vue` — alerta admin/supervisor (reusa `stores/approvals`).
- Reutilizar `components/dashboard/WeeklyProgressChart.vue` (ya existe).
- `AdminHome.vue` / `SupervisorHome.vue` / `CollectorHome.vue` pasan a **componer** estos bloques en vez de markup inline.

Tokens: reutilizar `resources/js/pwa/assets/pwa.css` (aqua-emerald oscuro + claro ya definidos). Añadir solo tokens/clases nuevas para la tarjeta KPI y la fila de quick-actions, cuidando **claro y oscuro** por igual.

## Trabajo de backend (marcado por disponibilidad)

Lo honesto: parte de lo que se ve en los mocks **no existe hoy** y hay que construirlo. Clasificación:

**Ya existe y se reutiliza** (`DashboardController` + servicios de métricas):
- Admin: `business_total` (patrimonio), `cash_base` (caja), `interest_earned` (utilidad — *verificar si es mensual*), `por_cobrar{current,overdue}`, `delinquency_rate`, `collected_today`, `disbursements_today`, `operational_expenses_today`.
- Supervisor: `collected_today`, `active_portfolio`, `overdue{amount,count}`, `active_collectors`.
- Cobrador: `due_today{amount,count,clients}`, `collected_today`, `overdue_aging`, `weekly_progress`, `week_total`.
- Gastos por aprobar: `approvalsStore.pendingCount` (endpoint existente).

**Nuevo / a extender (backend):**
1. **Tendencias (▲/▼ % vs período anterior)** de los KPIs — requiere comparación histórica; hoy no se calcula.
2. **Sparkline de cartera** (serie histórica del saldo por cobrar) — no existe.
3. **Utilidad del mes** — confirmar si `interest_earned` ya es mensual o hace falta una variante mensual + su delta.
4. **Desglose por cobrador (rendimiento del día)** para el supervisor — `supervisorDashboard` no lo devuelve; `collectors()` lista cobradores pero probablemente sin cobrado/meta del día. Extender o nuevo endpoint.
5. **Meta del equipo** (supervisor) — suma de `due_today` de su equipo; `supervisorDashboard` hoy no la trae.

## Fases de implementación (propuestas — se detallan en writing-plans)

1. **Fase 1 — Frontend con datos existentes.** Componentes compartidos + reestructurar los tres Home usando *solo* lo que el backend ya devuelve. Los elementos que dependen de backend nuevo (tendencias, sparkline, desglose por cobrador) se ocultan con *empty state* elegante o se omiten hasta la Fase 2. Ship del rediseño visual + quick-actions + carrusel KPI con datos reales de hoy.
2. **Fase 2 — Enriquecimiento backend.** Tendencias, sparkline, utilidad mensual, desglose por cobrador, meta de equipo. Se cablean a los KPIs/secciones ya construidos.
3. **Fase 3 — Pulido.** Micro-interacciones (card-press), auditoría de modo claro, migración del resto de `text-slate-*` crudo a tokens (deriva pendiente del #43 Fase B).

## Pruebas

- **Alcance por rol (crítico):** afirmar que el payload de `/pwa/dashboard` de cada rol contiene **solo** su alcance — el de supervisor y cobrador **no** debe incluir caja/utilidad/gastos del dueño; el del cobrador no debe incluir datos de equipo.
- **Permisos de quick-actions:** cada acción se muestra solo con su flag (`can_*`) en verde; p.ej. el supervisor no ve "Registrar pago".
- **Endpoints nuevos** (Fase 2): tests de las métricas de tendencia / desglose por cobrador.
- Sin regresión en la suite PWA existente; PHPStan nivel 5 + Pint limpios.

## Fuera de alcance

- **Bug del badge de rol en `ProfileView.vue`** ("Cobrador" hardcodeado) — anotado en el #43 como corrección separada.
- Rediseño de pantallas internas (créditos, clientes, cobros): este spec cubre **los dashboards de inicio**, no el resto de la app (aunque la migración a tokens de la Fase 3 los roza).

## Referencias

- Mocks aprobados (brainstorming): baseline admin actual, Approach C admin/supervisor/cobrador (modo oscuro).
- Imagen de referencia del usuario: app Banco Popular (acción-primero, tarjetas limpias).
