Gastos · Plan de refactor UX

Unificar Resumen + Gastos

Consolidar dos vistas que ya comparten datos y competencia, sin perder la regla core (comprar ≠ pagar).

📅 2026-07-31 📁 ~/Web/gastos/ 🎯 Nav 6 → 5, home densa con lista corta, historia completa en subruta 🚫 No modifica código en esta fase

1 · Diagnóstico — qué hace cada vista hoy

Ambas viven del mismo hook useFinance().cashflow(y, m0) y muestran lo que sale del bolsillo este mes (§6). El overlap es real, no cosmético.

Resumen / — KPI hero, lista por monto, charts en columna derecha (desktop)

Qué muestra

  • Hero: "Queda este mes" (grande) + Ingresos / Salidas del mes.
  • <RecurringIncomeMonth /> — sueldos recurrentes, monto editable inline.
  • Lista "Gastos del mes" ordenada por monto desc, sin agrupar por día.
  • Charts (solo desktop): PieByCategory + IncomeVsOutflow.
  • Link "Qué vas a pagar desde [próximo mes]" → Forecast.

Datos e interacción

  • Datos: useFinance(), useExpenses(), useCategories(), useMonth().
  • No permite editar desde la lista (los items no son clickeables).
  • Selector de mes vive en el header persistente (AppShell).
  • Charts ausentes en mobile — quedan solo para pantallas anchas.
Gastos /gastos — toggle pago/compra, lista por día, edición inline

Qué muestra

  • Toggle "Por pago" / "Por compra" — dos vistas alternativas del mismo mes.
  • Por pago: agrupado por día de pago (mismo cashflow del Resumen).
  • Por compra: agrupado por fecha de compra, con tag "se paga en X" / "sale ahora".
  • Íconos por método de pago (cash, debit, transfer, qr, credit).

Datos e interacción

  • Datos: mismos hooks que Resumen + useCards(), useCardPeriods().
  • Editable: click en un ítem abre QuickAddSheet con el expense.
  • Sin KPIs — vas a Gastos ya sabiendo lo que querés ver.
  • Sin filtros por categoría / medio / búsqueda hoy en día.
Otras vistas del nav — para entender qué NO se toca
  • Forecast (/forecast): meses hacia adelante, agrupado por tipo (compras / cuotas / fijos / cash). Regla §7 — no se toca.
  • Gráficas (/graficas): duplica los charts del Resumen + el ForecastBars. candidato a absorber
  • Ingresos (/ingresos): ingresos sueltos + plantillas recurrentes. No aparece en el nav (se accede desde el hero recurrente).
  • Tarjetas / Categorías: configuración. No se tocan.

Nav actual (mobile bottom + desktop side): NAV_ITEMS tiene 6 items — Resumen, Gastos, Forecast, Gráficas, Tarjetas, Categorías. Unificar libera un slot.

Overlap real — por qué unificar tiene sentido
FeatureResumenGastos (Por pago)
Fuente de datos cashflow(y, m0).items cashflow(y, m0).items idéntico
Orden por monto desc por día de pago asc
Editable no
KPI del mes sí (hero) no
Charts sí (desktop) no

Conclusión: dos vistas del mismo mes con features complementarias. El costo de saltar entre ellas para "ver cuánto queda y editar un gasto" no se justifica.

2 · Variantes de unificación

Tres shapes candidatos. Wireframes lado a lado, mobile y desktop.

A · Home con lista corta + subruta refinada

Hero KPIs → últimos 10 movimientos (gastos, ingresos y pagos de tarjeta, cada uno con tag chico) → botón "Ver más movimientos →" → charts lazy (mount al viewport). La lista completa con filtros vive en la subruta /resumen/movimientos, que reusa Gastos.tsx tal cual está — cero refactor de componentes.

Mobile · hero + últimos 10 + ver más + charts lazy
Inicio · julio
Queda este mes $142.300
Ingresos$820k
Salidas$678k
Últimos movimientos · 10
SueldoingresoJulio$820k
AlquilergastoFijo$210k
Resumen Visapago tarjetavence hoy$52k
Súper CotogastoDébito$18k
NetflixgastoFijo$8k
UbergastoQR$4k
FarmaciagastoDébito$6k
NaftagastoDébito$25k
FreelanceingresoTransf.$120k
Resumen Amexpago tarjetavence 24$35k
Ver más movimientos →
📊 Charts (categoría, ingresos vs salidas, forecast) — lazy render al scroll
+
Desktop · hero + últimos 10 + ver más → subruta; charts lazy abajo
gastos
Inicio
Forecast
Tarjetas
Categorías
Inicio · julio 2026
Queda este mes $142.300
Ingresos$820k
Salidas$678k
Últimos movimientos · 10
SueldoingresoTransf.$820k
AlquilergastoFijo · Cash$210k
Resumen Visapago tarjetavence hoy$52k
SupermercadogastoDébito · Alim.$18k
FreelanceingresoTransf.$120k
Ver más movimientos → /resumen/movimientos
📊 Charts lazy
categoría · ingresos vs salidas · forecast
montan al llegar al viewport
→ Forecast desde ago
+

✓ Pros

  • Mínimo cambio conceptual — es el Resumen "terminado".
  • Todo visible sin ocultar nada detrás de una interacción.
  • Charts entran en mobile (colapsables) sin perder densidad.
  • Refactor más chico: casi copy-paste de ByPayment dentro de Resumen + edit handler.

✗ Cons

  • En mobile el scroll puede ser largo si hay 20+ gastos.
  • La vista "Por compra" pierde protagonismo (queda como toggle secundario o desaparece).
  • El foco de "cuánto queda" y el de "editar tal gasto" compiten por la misma pantalla.

B · Tabs internas (Resumen · Movimientos · Gráficas)

Una sola ruta con tabs adentro. El header con selector de mes + KPI hero es siempre visible; solo cambia el bloque de abajo. Preserva la separación conceptual sin gastar espacio en el nav global.

Mobile · tabs internas bajo el hero
Inicio · julio
Queda este mes $142.300
Ingresos$820k
Salidas$678k
Resumen
Movimientos
Gráficas
Todos 💳 🔎
Mar 04 jul
SupermercadoDébito$18k
Resumen Visavence hoy$52k
Vie 07 jul
AlquilerFijo$210k
+
Desktop · tabs con hero fijo
gastos
Inicio
Forecast
Tarjetas
Categorías
Inicio · julio 2026
Queda este mes $142.300
Ingresos$820k
Salidas$678k
Resumen
Movimientos
Gráficas
Mar 04 jul
SupermercadoDébito · Alimentación$18.400
Resumen Visavence hoy$52.100
Vie 07 jul
AlquilerFijo · Cash$210.000
+

✓ Pros

  • Foco claro: cada tab una intención (mirar / actuar / analizar).
  • KPI del mes nunca se pierde de vista (hero fijo arriba).
  • Discoverability de gráficas mejora — antes solo aparecían en desktop.
  • Fácil sumar tabs futuras (ej. "Por compra") sin tocar nav.

✗ Cons

  • 3 tabs internas + hero = mucha UI antes del contenido en mobile.
  • Estado de tab: ¿URL query ?tab=movimientos? Deep-link o no.
  • La "vista Resumen" queda medio vacía si el hero ya está arriba.
  • Complejidad extra vs Variante A.

C · Master-detail (desktop) + scroll (mobile)

En desktop, layout de dos columnas: lista de movimientos a la izquierda, panel de detalle/edición + charts a la derecha. En mobile cae a la Variante A. Pensada para uso ancho, tipo dashboard financiero.

Mobile · idéntico a Variante A
Inicio · julio
Queda este mes $142.300
Ingresos$820k
Salidas$678k
Mar 04 jul
SupermercadoDébito$18k
Resumen Visavence hoy$52k
+
Desktop · master a la izquierda, detalle + charts a la derecha
gastos
Inicio
Forecast
Tarjetas
Categorías
Inicio · julio 2026
Queda este mes $142.300
Ingresos$820k
Salidas$678k
Todos💳🔎
Mar 04 jul
Supermercadoseleccionado$18k
Resumen Visavence hoy$52k
Vie 07 jul
AlquilerFijo$210k
Detalle
Supermercado · Coto
04 jul · Débito
Alimentación

Editar
+

✓ Pros

  • Densidad máxima en desktop — todo visible sin scroll.
  • Editar sin abrir modal (o con panel lateral en lugar de QuickAddSheet).
  • Se lee como dashboard "de escritorio", tipo YNAB.

✗ Cons

  • Complejidad alta — pattern nuevo en la app.
  • Requiere reemplazar / duplicar QuickAddSheet con un panel inline.
  • Mobile no gana nada respecto a Variante A.
  • El diseño actual no tiene precedentes de master-detail — ruptura visual.

3 · Comparación de variantes

CriterioA · Scroll largoB · Tabs internasC · Master-detail
Densidad mobilealtamediaalta
Densidad desktopmediamediamuy alta
Discoverability chartsaltaaltasolo desktop
Foco "cuánto queda"hero arribahero fijohero arriba
Complejidad refactorbajamediaalta
Reduce nav a 5
Vista "Por compra"toggle o se eliminatab extrano encaja
Reusa código existente~90%~80%~50%

4 · Recomendación

Elegir

Variante A · Scroll largo — refinada

Refinada con lista corta (últimos 10) + subruta /resumen/movimientos para la historia completa + charts lazy.

Es lo que menos discute con lo que ya funciona. El Resumen es de hecho la home; los usuarios ya llegan ahí a mirar "cuánto queda". Sumarle un vistazo rápido de los últimos movimientos con la capacidad de editar cierra el circuito, sin sepultar el hero bajo una lista larga.

5 · Plan de migración — checklist

Interactivo: marca lo que ya está hecho. Sin persistencia — es solo para trackear en la sesión.

6 · Riesgos

mitigado Perder el foco del mes actual

Si la lista editable domina la pantalla, el KPI hero deja de ser lo primero que se lee.

Resuelto por el refinamiento: lista corta a 10 items + "Ver más" que empuja a subruta. El hero + últimos movimientos entran en un viewport de mobile sin scroll excesivo. La historia completa vive en /resumen/movimientos.

alto Confusión compra vs pago

El core §4 es que una compra con tarjeta no descuenta este mes. Al agregar filtros y edición, hay riesgo de que el user filtre "solo crédito" y vea nada, o edite una compra pensando que está viendo su día. Mitigar: mantener los tags "sale ahora" / "se paga en X"; al editar, mostrar la fecha de pago en el sheet.

mitigado Charts pesados en scroll largo

PieByCategory + IncomeVsOutflow renderizan con datos completos del mes.

Resuelto por lazy render: los charts se montan con IntersectionObserver al llegar al viewport. En mobile, si el user no baja, no se ejecutan. Memoizar los cálculos del useFinance() derivados sigue siendo buena idea.

medio La "Vista Por compra" tiene fans

Si algún user usa la vista por fecha de compra activamente, desaparecerla molesta. Mitigar: no borrar todavía; mantener como toggle secundario adentro del bloque de lista o como deep-link.

medio Filtros mal ubicados

Filtros arriba de la lista compiten con el hero por atención. Mitigar: chips discretos, ancho reducido, entre hero y lista. No mezclar con la selección de mes (que ya está en el AppShell).

bajo Bookmarks / URLs viejas a /gastos

Users con la app instalada como PWA pueden tener shortcuts. Mitigar: redirect por 1 release antes de borrar.