Plan: creación de documentos por pasos en móvil (DocumentDrawer)
Objetivo
Que el flujo de crear/editar un documento desde DocumentDrawer en viewports móviles sea por etapas (wizard), con la misma filosofía que Configuración → Importaciones (ImportWizard: pasos numerados, avanzar/retroceder, contenido una pantalla a la vez), reduciendo scroll largo y sobrecarga cognitiva.
Referencia en el código actual
| Pieza | Ubicación | Qué reutilizar como patrón |
|---|---|---|
| Wizard por pasos | ../../Frontend/components/ImportWizard.tsx | steps[], currentStep, handleNext / handleBack, canProceed(), AnimatePresence por paso, stepper visual |
| Entrada en settings | ../../Frontend/components/settings/sections/ImportSettings.tsx | Contenedor mínimo que monta el wizard |
| Documento | ../../Frontend/components/DocumentDrawer.tsx | Estado unificado del documento; ya usa useMediaQuery / isNarrowViewport y estilos max-md: en acciones |
ImportWizard hoy muestra los 5 pasos a la vez en el stepper (horizontal). En móvil suele convenir un stepper compacto (p. ej. “Paso 2 de 5” + barra de progreso, o dots) para no comprimir títulos; eso puede ser una variante responsive del mismo componente visual.
Alcance
- Incluido: comportamiento solo cuando
isNarrowViewport(o breakpoint acordado, p. ej.< md), manteniendo el layout actual en desktop/tablet anchos. - Incluido: documentos “estándar” (encabezado, líneas, totales, guardar) y extensiones que ya viven en el drawer (adjuntos, pagos, costos importación, campos personalizados), ordenadas en pasos lógicos.
- Excluido (fase inicial): reescritura completa de
DocumentDrawer; el plan favorece una capa de orquestación sobre el contenido existente.
Principios de UX
- Un foco por pantalla: cada paso muestra un subconjunto de UI; evitar duplicar formularios completos en dos pasos.
- Navegación clara: botones fijos Atrás / Siguiente (y Guardar solo en el último paso o siempre visible según decisión de producto).
- Validación por etapa: no permitir “Siguiente” si faltan datos obligatorios de esa etapa (equivalente a
canProceedenImportWizard). - Sin pérdida de datos: el estado sigue siendo el de
DocumentDrawer(mismos hooks/estado); solo cambia qué bloques se renderizan visibles. - Coherencia con importaciones: reutilizar tokens,
Card, animaciones (framer-motion) y textos de i18n donde aplique.
Propuesta de etapas (base)
Los nombres son orientativos; deben vivir en lib/i18n.
| Paso | Contenido sugerido | Validación mínima para avanzar |
|---|---|---|
| 1 | Tipo/contexto ya elegido al abrir + socio de negocio, fechas, moneda, punto de emisión, canal | Cliente/proveedor y fechas según reglas actuales del documento |
| 2 | Líneas (DocumentItems / retenciones / bundles según tipo) | Al menos una línea válida o reglas del tipo de documento |
| 3 | Totales, descuentos globales, observaciones breves | Opcional o según tipo fiscal |
| 4 | Extras: adjuntos, pagos anticipados, costos de importación, relaciones, campos personalizados | Opcional; puede dividirse en sub-pasos si el tipo de documento lo exige |
| 5 | Revisión (resumen lectura) + acciones Guardar / Confirmar / enviar | Misma validación final que hoy antes de submit |
Nota: Para tipos especiales (p. ej. retención 05, programación de facturas), los pasos 2–4 pueden variar mediante una pequeña tabla getMobileStepsForDocumentType(type) para no forzar un único flujo.
Arquitectura técnica recomendada
Opción A — Recomendada: “Mobile step shell”
- Nuevo componente, p. ej.
DocumentDrawerMobileSteps, que:- Recibe
currentStep,setCurrentStep, definición de pasos (id + render function ochildrenpor paso). - Envuelve el mismo contenido que hoy, pero con
display/ montaje condicional por paso (ovisibility+inertpara accesibilidad).
- Recibe
DocumentDrawerContentdetectaisNarrowViewporty:- Si móvil: renderiza el shell de pasos + barra inferior (Atrás / Siguiente / Guardar).
- Si no: renderiza el layout actual (una sola columna scrollable).
Ventaja: el estado y la lógica de guardado permanecen en un solo sitio.
Opción B — Extraccer secciones
- Partir
DocumentDraweren secciones ya nombradas (DocumentHeader,DocumentItems, …) y solo ordenarlas en pasos en móvil. Es más trabajo de refactor previo; puede ser fase 2.
Componente compartido de stepper
- Extraer de
ImportWizardunWizardStepper(props:steps,currentStep,variant: 'full' | 'compact') para usar en importaciones y en documentos, evitando duplicar markup.
Estado y comportamiento
- Un solo árbol de estado: no crear un segundo “documento en progreso”;
currentStepes solo UI. - Al abrir el drawer: resetear
currentStepa 1 (o al paso adecuado si es edición y se quiere ir directo a líneas — decisión de producto). - Al cerrar: resetear paso para la próxima apertura.
- Edición de documento existente: mismos pasos; el paso 5 puede enfatizar “Cambios” vs creación.
Validación
- Centralizar por paso una función
canGoNext(step): booleanque reutilice validaciones ya existentes (Zod, checks previos ahandleSave, etc.) para no duplicar reglas. - Mostrar mensajes cortos bajo el step o con
toastal bloquear “Siguiente”.
Accesibilidad y teclado
- Foco al cambiar de paso (contenedor del paso con
tabIndex={-1}yfocus()opcional). - Evitar trampas de foco en drawers anidados (ya hubo trabajo con Sheet/portal en otras pantallas).
Internacionalización
- Claves nuevas bajo un prefijo común, p. ej.
documentWizard.step1Title,documentWizard.next,documentWizard.back,documentWizard.review.
Fases de implementación sugeridas
| Fase | Entrega | Riesgo |
|---|---|---|
| 1 | Stepper compacto + 3 pasos (Encabezado → Líneas → Revisión + guardar) solo para un subconjunto de tipos (p. ej. factura venta) | Bajo |
| 2 | Incorporar totales/observaciones como paso propio; barra de acciones alineada con diseño | Medio |
| 3 | Adjuntos, pagos, importación, custom fields como pasos o sub-sección del paso 4 | Alto (muchos modales anidados) |
| 4 | Matriz por documentType (compras, NC, retenciones, programadas) + pruebas E2E móvil | Alto |
Pruebas
- Manual: iPhone/Android + Chrome devtools responsive.
- Comprobar: rotación, teclado virtual cubriendo botones, scroll solo dentro del paso activo.
- Regresión: desktop sin cambios visuales relevantes.
Riesgos y mitigación
| Riesgo | Mitigación |
|---|---|
DocumentDrawer muy grande | Shell en archivo nuevo; tocar el mínimo de líneas en el drawer principal |
| Doble scroll (drawer + paso) | min-h-0 + overflow-y-auto solo en el cuerpo del paso |
| Drawers secundarios (crear cliente, etc.) | Mantener como hoy; no meterlos “dentro” de un paso sin revisar z-index |
Criterios de éxito
- En ancho móvil, el usuario completa un documento típico sin scroll interminable en una sola vista.
- Tiempo y errores percibidos menores al flujo actual en móvil (validación opcional con usuarios).
Documento de planificación; la implementación puede ajustar nombres de componentes y número de pasos según prioridad de producto.
Implementación (resumen técnico)
- Activo cuando: viewport estrecho (
max-width: 767px), documento editable (!readOnly) ymode === 'document'(no afecta solo lectura ni otros modos del drawer). - Componentes:
Frontend/components/document/DocumentDrawerMobileWizard.tsx(DocumentDrawerMobileWizardProgress,DocumentDrawerMobileWizardNav, constanteMOBILE_DOC_WIZARD_STEPS = 5). - Pasos: 1 Datos (
DocumentHeader) → 2 Líneas → 3 Totales y observaciones (DocumentFooter) → 4 Pagos, DTE, costos importación, campos personalizados, adjuntos → 5 Resumen + barra Guardar. - i18n: claves
doc.mobileWizard.*enFrontend/lib/i18n.tsx. - Validación al pulsar “Siguiente”: paso 1 (cliente, condición de pago si aplica, fechas, punto de emisión, retención 05 si aplica); paso 2 (
validateItems()).