Elige la ruta de envío para que podamos asignarte el almacén correcto y mostrarte las opciones disponibles.
01El marco: seis pasos y un candado
create-shipment/_layout · stepper.tsx (mobile-ui) · use-shipment-draftEl wizard se presenta como modal fullscreen desde el ítem «Nuevo envío» del sheet de crear (MF-03), con el requireCompleteProfile que ya guarda esa puerta. Header del producto: atrás, título, y a la derecha el QR mini con candado — la promesa de la pantalla final viajando por todo el flujo. Debajo, el stepper de mobile-ui comprimido a seis; abajo, la barra de acción con el susurro de autoguardado: el borrador se guarda solo en cada paso, la ✕ no pregunta nada.
¿Dónde entregarás tu mercancía?
Selecciona el almacén Mogos donde tu proveedor enviará los paquetes. Desde ahí los consolidamos y enviamos a tu país.
Modal, no pestaña
presentation:'modal'de expo-router sobre el shell. La ✕ no existe: atrás baja un paso y, en el paso 1, cierra. Nada se pierde: el borrador ya está guardado.El candado que promete
El QR mini (34 px, radio 9) lleva el patrón difuminado y el candado marino. No es decoración: es la misma tarjeta de anticipación de MF-04 comprimida a insignia, y se abre en la última pantalla.
Stepper de seis, comprimido
El
stepperde mobile-ui con círculo 22 y rótulo 9,5 — seis caben en 358 px. Los hechos quedan en azul con check y se puede volver; los pendientes no responden.Una pregunta por pantalla
El título del paso es una pregunta en display 22. Los textos son los de la web (
account.createShipment.*): mismo i18n, misma voz, es/en/zh.La barra que susurra
«Guardado ✓» en 11,5 gris junto al CTA. El debounce de 500 ms de
use-shipment-draftya existe en la web; aquí persiste en MMKV por usuario.El corredor se hereda
Si el chip del shell ya filtra una ruta, el paso 1 abre directo en los almacenes. Sin corredor, la puerta de ruta aparece primero (§02).
Los dos almacenes reales del corredor China salen de warehouses (rol ORIGIN, marítimo primero) y las etiquetas de modo de sus ShippingLocations — el mismo dato que valida el API, nunca el nombre. Un solo almacén → se autoselecciona; ninguno → estado vacío con soporte. Nada se marca «recomendado»: el cliente elige.
02Origen: la puerta, el aéreo y la transición
corridor-selection-gate.tsx · air-warehouse-dialog.tsx · warehouse-address-card.tsx · shipping-mark-anticipation-card.tsxTres variantes del paso 1. Sin corredor elegido, la puerta de ruta abre el paso — la misma tarjeta discontinua brand de la web. Elegir un almacén aéreo mantiene la selección pero abre el sheet de contacto: los aéreos se conversan por WhatsApp antes. Y al continuar, la transición «así nos la envías»: la única pantalla del flujo que el cliente necesita antes de que su mercancía viaje — la dirección del almacén lista para copiar o compartir al proveedor, y la tarjeta de anticipación del QR con candado que MF-04 ya diseñó.
¿Dónde entregarás tu mercancía?
La puerta de ruta usa el mismo lenguaje que la web (border-2 dashed brand-300 sobre lavado brand). El sheet aéreo reemplaza al AirWarehouseDialog: en el teléfono los diálogos de una acción son sheets; el verde es el de WhatsApp, no un token Mogos — igual que el botón de WhatsApp del perfil web. La transición reusa verbatim la anticipación de MF-04 (shipping-mark-anticipation-card.tsx): mismo héroe celeste al 50 %, misma numeración mono, misma nota ámbar. «Compartir» abre el share sheet nativo con el bloque de dirección completo — lo que la web resuelve con dos botones de copiar.
03Destino: retiro, guardadas o el mapa
address-section.tsx · new-address-capture.tsx (MF-04) · address-capture.tsx (MF-02)El paso 2 replica la regla de la web: «retirar en almacén destino» no es una dirección — es la ausencia de una, y por eso va fijada arriba, seleccionada por defecto para quien no marcó dirección primaria. Tocar una dirección guardada es un solo gesto que decide las dos cosas (entrega a domicilio + cuál). Y «Nueva dirección» no abre un formulario: abre el mapa fullscreen que MF-02 ya construyó — el mismo que MF-04 ya reusa en la edición.
¿A dónde llevamos tu envío?
Elige una dirección guardada o crea una nueva.
Direcciones guardadas
Av. Ppal de Los Ruices, Edif. Centro Empresarial Miranda, piso 3, Caracas, Miranda, Venezuela
Calle París con calle Mucuchíes, Las Mercedes, Caracas
Necesita verificación Corrige esta dirección primero para poder usarla en tu envío.Av. Francisco de Miranda, Los Palos Grandes, Chacao 1060, Miranda
Usar esta ubicaciónEl retiro no es una fila más
Va arriba, con su tarjeta propia: es el default de quien no tiene dirección primaria — la misma regla que el API aplica en
resolveDeliveryMethod. Nombra el almacén real (useDestinationWarehouses).Un gesto, dos decisiones
Tocar una dirección la selecciona y cambia a entrega a domicilio; guardar una nueva hace lo mismo. Nada de elegir «método» y después «cuál».
La verificación bloquea, y explica
Una dirección con
needsVerificationse muestra al 60 %, con la insignia ámbar y la línea que dice qué hacer. Se corrige en Perfil (MF-09) o creando una nueva aquí.El mapa no se rediseña
Es
address-capturede MF-02 presentado como superficie perezosa — el patrón exacto denew-address-capture.tsxde MF-04:React.lazy, el SDK de mapas fuera del grafo del wizard.Tres alturas, teclado incluido
La hoja colapsada mide lo que mida la dirección detectada; media para el formulario; completa cuando el teclado empuja. Todo eso ya existe (
use-address-sheet-keyboard).Al guardar, avanza
La dirección nueva vuelve seleccionada (la respuesta del API, con su alias sugerido) y el paso queda listo para continuar. El alias se edita inline, como en la web.
La teja del mapa es de Google — no es superficie de marca: tierra gray-100, manzanas gray-50, agua celeste-soft, parques lima-soft, exactamente la convención que fijó la pieza de MF-02. El pin no se arrastra: se mueve el mapa debajo, con la sombra en el suelo.
04Mercancía: la IA va primero
packing-list-card.tsx (packages/ui) · use-packing-list-parser · packing-list-extractions · multi-select.tsxLa decisión de estructura del paso 3: el packing list se ofrece antes de pedir nada a mano — si el cliente lo sube, categorías y medidas llegan llenas y los dos pasos siguientes son confirmar, no teclear. La tarjeta es la única mancha celeste del formulario, y sus cuatro estados son los del contrato de la web: adjunto, analizando, listo con resumen, y el error clasificado que nunca bloquea — siempre se puede seguir a mano.
¿Qué estás enviando?
Súbelo y completamos volumen, cajas, peso y categorías por ti.
¿Qué estás enviando?
Suele tardar menos de un minuto. Puedes seguir completando mientras tanto.
¿Qué estás enviando?
Datos completados. Categorías, volumen, cajas y peso ya están llenos — puedes editarlos.
¿Qué estás enviando?
El contrato de estados es el de packing-list-card.tsx de packages/ui: validación local (tipo, 5 MB) → toast, sin adjuntar; error del API → la píldora roja en el chip y el mensaje debajo de la tarjeta, clasificado por packing-list-extraction.config.ts; éxito → resumen en el idioma del usuario y autorelleno con la nota ✨. El polling corre en background: salir del paso no lo cancela, y si el cliente ya escribió un valor a mano, la IA no lo pisa — la misma regla de la web.
¿Qué estás enviando?
¿Qué estás enviando?
Las categorías le dicen a aduana qué viaja en tus cajas. Elige todas las que apliquen: un envío puede llevar ropa y calzado a la vez.
Si nada calza, marca Otro y descríbelo en el campo de tipo de mercancía — ahí sí es obligatorio.
Mercancía peligrosa (baterías, aerosoles, líquidos inflamables) y réplicas se declaran en el paso Medidas: afectan cómo podemos transportarla.
La ayuda es un sheet estático con el copy de los topics de la web (cargo-type, volumetric-weight) — decisión 5: sin IA hasta MF-11, que conecta este mismo botón al panel de Mogui sin tocar el diseño.
05Medidas que ya vienen llenas
numeric-input-with-suffix.tsx · lib/units · use-corridor-units · segmented.tsx¿Cuánto ocupa tu carga?
M³ · KGLas unidades son del corredor
lib/unitsdecide M³/KG o FT³/LB según la ruta; el banner lo anuncia una vez y los sufijos lo repiten en cada campo. Los números vantabular-nums.La chispa marca lo que puso la IA
El ✨ celeste vive dentro del campo mientras el valor venga del packing list; editarlo a mano lo apaga. Es la traza visible de la extracción — no un adorno.
Sí/No como segmentado
La web usa selects de dos opciones; en el teléfono un select para «Sí/No» son dos toques y un sheet. El
segmentedde mobile-ui lo resuelve en uno. Desviación con razón nombrada.El tracking nombra el país
«Número de tracking (China)» — el mismo interpolado del i18n web con el país de origen del corredor. Los borradores viejos con
internalTrackingNumberse leen igual.Nada aquí es obligatorio
El esquema de la web solo exige categorías (y detalle si «Otro»). Medidas vacías → la orden se crea igual y el almacén mide al recibir. El CTA nunca se bloquea en este paso.
El teclado correcto
Volumen y peso abren
decimal-pad; cajas y tracking,number-pad. La coma decimal respeta el locale — lo que la web delega al navegador, aquí se declara.
06Archivos: cámara, galería, documentos
file-upload-zone.tsx · use-upload-file (s3-files/presigned-url) · action-sheet.tsxEl paso 5 traduce el drag & drop de la web a lo que un teléfono hace mejor: la cámara. Fotos de las cajas y factura, cada grupo con sus formatos y su máximo (los de la web: 5 MB por archivo, 10 fotos, 5 documentos). Todo es opcional — la línea de la web lo dice igual: se pueden agregar después desde el detalle del envío.
Fotos y documentos
¿No los tienes a la mano? Puedes agregarlos después desde el detalle de tu envío.
Fotos de las cajas
JPG, PNG o PDF · máx. 10 archivosFactura de la mercancía
PDF, XLS o XLSX · máx. 5 archivosFotos y documentos
Fotos de las cajas
Cada archivo sube con su presigned-url apenas se elige — no en el submit final: la confirmación del paso 6 no puede esperar tres fotos por LTE. La fila con barra es una subida en curso; la roja, el error recuperable con su «Reintentar». La validación local (tipo, 5 MB) rechaza antes de subir, con el mensaje de la web.
07Resumen, y el QR que se abre
shipment-summary-confirmation.tsx · use-manage-order (POST orders) · shipping-mark (MF-04)El paso 6 agrupa todo lo elegido con un «Editar» que salta al paso — no un acordeón que se reabre. Si falta algo, la lista ámbar de la web lo enumera y el CTA lo cuenta. Y al confirmar, el único momento orquestado del flujo: la banda marino sube, el barco zarpa, y el candado que acompañó los seis pasos se abre sobre el QR vivo. El aterrizaje es la pantalla de shipping mark que MF-04 ya construyó.
Resumen de tu envío
Al confirmar, se creará tu envío y recibirás un código de tracking.
Resumen de tu envío
Completa los pasos pendientes para revisar y confirmar tu envío.
- Selecciona las categorías de mercancía
El momento. El POST arranca la coreografía — la banda es el estado de carga: sube mientras la orden viaja, el barco cruza mientras se espera la respuesta, y el QR aparece cuando llega el 201. Tres fotogramas congelados con --at:
Resumen de tu envío
Resumen de tu envío
La banda es el loading
No hay spinner: la banda marino que sube es la espera del POST. Si el API tarda, el barco sigue navegando en bucle suave; si falla, la banda se retira y el error habla (§08).
640 ms, tres actos
Banda 0→100 % en 420
ease-out· barco entra a los 180 con la estela · QR con candado abierto a los 460,ease-spring. El mismo presupuesto del orbe de MF-03.Aéreo cambia el actor
Envío AIR → el avión del manual reemplaza al barco y el toast dice ✈️ — el mismo morph temático del toast web («¡Orden en camino!»).
El aterrizaje es MF-04
La pantalla final es
my-shipments/[id]/shipping-marktal cual existe — QR nítido, descargar, compartir, «Enviar a mi proveedor». El wizard se descarta del stack: atrás desde aquí va al detalle, no al formulario.Reduced motion
Sin coreografía: overlay estático «Generando tu QR…» y navegación directa al aterrizaje. El anuncio de VoiceOver es el del toast.
El borrador muere aquí
clearDraft()recién cuando llega el 201 — cerrar la app a mitad de la animación no pierde nada: la orden ya existe y el borrador ya no.
08El borrador y los días malos
use-shipment-draft · support-dialog.tsx · contrato de red (DECISIONS #13)Decisión 4: autoguardado silencioso, reanudar explícito. El wizard guarda en cada paso; salir no pregunta nada. Al volver, la pantalla previa ofrece continuar con lo elegido a la vista — o empezar de nuevo. Y los dos días malos del flujo: el destino sin resolver (el diálogo bloqueante de soporte que la web ya convirtió de toast a alertdialog) y la red caída, donde el borrador es la garantía.
Tenías un envío a medio crear
Puedes continuar donde lo dejaste o empezar de nuevo.
Resumen de tu envío
¿Qué estás enviando?
Necesitas conexión para analizarlo. Puedes seguir completando a mano.
La pastilla de red es la ConnectionPill del shell (MF-03) — no un toast nuevo. Sin conexión el wizard no se cierra: los pasos que no necesitan API (medidas, notas) siguen; los que sí (packing list, subir archivos, confirmar) se degradan con su razón dicha. El susurro cambia a «Guardado en este teléfono». El diálogo de soporte replica el SupportDialog de la web: role="alertdialog", foco atrapado, persistente hasta actuar.
09Lo que hay que escribir en Moti
Moti + Reanimated · escala de MF-01 · useReducedMotion| Pieza | Qué anima | Duración · easing | Reduced motion |
|---|---|---|---|
| Cambio de paso | slide horizontal 24 px + fade del cuerpo; el stepper tiñe el círculo | 260 ms · ease-out | fade 80 ms |
| Chip del packing list | píldora Analizando → Listo con pop 1 → 1,12 → 1; la nota ✨ entra con rise 12 | 260 ms · ease-spring | swap directo |
| Autorelleno de campos | los valores entran con fade + la chispa aparece; nunca mientras se edita | 160 ms · ease-out · stagger 40 | swap directo |
| Sheets (aéreo, categorías, ayuda, fuente) | slide-up con el velo marino al 70 % | 260 ms · ease-out | fade 80 ms |
| El momento | banda 0→100 % (420) · barco/avión entra a los 180 · QR + candado abierto a los 460 | 640 ms · ease-out + spring | overlay estático y navegación directa |
| Susurro de guardado | check hace pop al guardar; el texto no se mueve | 160 ms · ease-out | sin pop |
Fuente de la escala: packages/mobile-ui/src/theme/motion.ts (MF-01). El momento reusa el presupuesto del orbe de MF-03: nada del flujo supera los 640 ms.
10Lo que queda decidido
docs/specs/2026-09-12-mobile-crear-envio.md- Decisión 1 · Fabrizio 2026-09-12
Wizard por pasos; el chat muere
El chat web (
/create-shipment/chat) no se enlaza desde ningún lado y le faltan corredor, almacén, categorías, IA, borrador y shipping mark. La app toma el modelo de datos del formulario + el ritmo del chat: seis pasos, una decisión por pantalla. El chat no se porta. - Decisión 2 · Fabrizio 2026-09-12
Seis pasos, la IA al frente
El packing list abre el paso de mercancía: si lo sube, categorías y medidas llegan llenas. La transición «así nos la envías» — dirección copiable + anticipación del QR — vive entre origen y destino.
- Decisión 3 · Fabrizio 2026-09-12
Sin estimado de costo
Paridad con la web:
CostEstimateCardestá apagada por producto (2026-08-10). El resumen cierra con el disclaimer, sin cifras. Cuando la web la encienda, se diseña aquí como iteración. - Decisión 4 · Fabrizio 2026-09-12
Autoguardado + reanudar
Guarda solo en cada paso (MMKV por usuario); la salida no pregunta. Al volver: «Continuar donde ibas / Empezar de nuevo» con lo elegido a la vista.
clearDraft()recién con el 201. - Decisión 5 · Fabrizio 2026-09-12
Ayuda local, sin IA
Los ⓘ abren sheets estáticos con el copy de los topics de la web. MF-11 conecta esos mismos botones al panel de Mogui sin rediseñar.
- Decisión 6 · Fabrizio 2026-09-12
«El QR que se gana»
Wizard calmo, campos del producto; la marca aparece donde carga significado: la tarjeta celeste de la IA, el candado que viaja y el zarpe final de 640 ms. Un solo momento orquestado.
- Reuso · consecuencia
El mapa no se rediseña ni se reimplementa
Nueva dirección =
address-capturede MF-02 como superficie perezosa, el patrón exacto denew-address-capture.tsx(MF-04). Elinteractive-map-dialog.tsxweb (796 líneas) no se porta. - Deuda anotada · para goal-phases
Embudo sin eventos, y dos piezas muertas en la web
La web no emite eventos de creación: definir
shipment_create_*(paso visto, IA usada, confirmado) es fase de esta MF, alineado con PostHog web. Y quedan anotados para limpieza web (no de esta MF): el chat huérfano yNextDeparturesBanner, definido y jamás montado.