Files
whatsapp-api-mockup/README.md
T
urieljarethandClaude Opus 5.5 4fe8f73959 Aplicar pendientes tras la integración
- render.js: botones y cards con urlBloqueada se pintan inertes.
- interactivity.js: sinFormato con la misma regla de marcadores que render.js; cita de documento con icono y nombre.
- Zoom manual (Ajustar / 100 % / 125 %) en #barra-movil, persistido en localStorage.
- Contador «Paso N/M» con estilo en iphone.css en lugar de estilos en línea.
- store/editor: campos opcionales tamano y headerTamano; editar la URL retira urlBloqueada;
  urlValida acepta URLs con forma de dominio; importar avisa de lo recortado.
- README y SPEC actualizados.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 21:39:09 -06:00

138 lines
12 KiB
Markdown

# WhatsApp Cloud API · Mockup
Plataforma de mockups de la **WhatsApp Cloud API** para crear demos visuales de conversaciones tal y como se ven en un **iPhone**: un editor en pantalla y, al lado, un teléfono con Dynamic Island, status bar y un chat de WhatsApp que replica los 13 tipos de mensaje de la API (plantillas, botones rápidos, listas, carruseles…).
Es una web **100 % estática**: sin frameworks, sin build, sin servidor y sin dependencias de red obligatorias. Todo el estado vive en tu navegador.
---
## Cómo abrirla
1. **Doble clic en `index.html`** (o arrástralo a Chrome/Edge/Firefox).
2. Listo. No hace falta servidor web, instalación ni conexión a internet.
Al abrirlo verás dos columnas: a la izquierda el **editor**, a la derecha la **vista previa** del iPhone con la demo de ejemplo **«Café Aurora» ☕**, que recorre los 13 tipos de mensaje con flujos interactivos.
### Estructura del proyecto
```
index.html → página única; ábrela con doble clic
css/ → base, iphone, whatsapp (chat) y editor
js/ → store, render, editor, interactivity, main
docs/ → research-api.md (payloads y límites) y research-ui.md (estilos)
```
---
## Editor (columna izquierda)
### Identidad de la cuenta
En el bloque **Cuenta** configuras lo que se ve en la cabecera del chat:
- **Nombre** del negocio (encabezado del chat).
- **Subtítulo** (p. ej. «en línea»); cuando el chat «está escribiendo» se cambia temporalmente por *escribiendo…* en verde.
- **Avatar**: súbelo desde un archivo (se convierte a dataURL) o pega una URL/dataURL; también puedes quitarlo (se usa un placeholder SVG).
- **Cuenta verificada**: activa o desactiva la insignia azul junto al nombre.
El **tema** (claro u oscuro) ya no está en Cuenta: se cambia con el botón *Tema* de la barra superior o con la tecla **T**, y se guarda con el resto del estado.
### Añadir, editar y reordenar mensajes
- La **paleta de tipos** (tarjetas con icono, estilo Meta) + botón **Añadir** crea un mensaje nuevo del tipo seleccionado.
- Cada mensaje es una **tarjeta colapsable** con un resumen; haz clic para desplegar sus campos.
- En cada tarjeta puedes cambiar los campos comunes: **Dirección** (Entrada/Salida), **Hora** (texto literal `HH:MM`, se muestra tal cual) y, solo en los salientes, **Estado (ticks)**: Enviado ✓ / Entregado ✓✓ / Leído ✓✓ (celeste).
- Acciones por tarjeta: **↑ / ↓** reordenar, **⧉** duplicar (con IDs regenerados) y **✕** borrar (pide confirmación).
- Todo cambio se guarda al instante y se refleja en el teléfono. En el menú **⋯** de la barra superior, **Volver al ejemplo Café Aurora** restaura la demo de ejemplo (pide confirmación y se puede deshacer).
- Los botones, filas y tarjetas sin URL tienen la casilla **Se pulsa sola en la demo**: durante *Reproducir demo* se pulsa automáticamente (la cabecera plegada muestra el chip «▶ auto»).
### Campos por tipo de mensaje
| Tipo | Campos editables |
|---|---|
| Texto | texto (admite formato WhatsApp: `*negrita*`, `_cursiva_`, `~tachado~`, `` ` ```monoespaciado``` ` ` y URLs clicables) |
| Imagen / Vídeo | archivo o URL + caption opcional |
| Audio | archivo opcional, casilla **nota de voz** (waveform + micro) y duración (`0:12`) |
| Documento | nombre de archivo con extensión (define el color del icono: pdf, docx, xlsx…), tamaño opcional («243 KB • pdf»), caption y archivo opcional |
| Sticker | imagen/WebP (se muestra sin burbuja ni hora) |
| Ubicación | latitud, longitud, nombre y dirección (el mapa es un gráfico SVG con pin) |
| Contacto | nombre, teléfono, email y empresa |
| Plantilla | cabecera (texto, imagen, vídeo o documento), cuerpo, pie y hasta **10 botones** (con o sin URL) |
| Botones rápidos | cabecera opcional, cuerpo, pie y hasta **3 botones** de respuesta |
| Lista | cabecera, cuerpo, pie, etiqueta del botón (≤ 20 caracteres) y **secciones con filas** (título ≤ 24, descripción ≤ 72) |
| Botón URL | cabecera opcional (vacía = sin cabecera), cuerpo, pie, texto del botón y URL |
| Carrusel | cuerpo opcional y de **2 a 5 tarjetas** (imagen, texto, botón y respuestas) |
Los campos de imagen/vídeo (y el resto de medios) ofrecen dos orígenes con radios **URL / Subir archivo**; en modo archivo, una zona punteada acepta clic o arrastrar-y-soltar. Si quedan vacíos se muestra un placeholder SVG, sin necesidad de red.
### Drag & drop y ayuda rápida
- **Reordenar arrastrando**: cada tarjeta de mensaje tiene un asa (⠿) a la izquierda de su cabecera; arrástrala sobre otra tarjeta y suéltala encima o debajo — una línea azul marca el punto de inserción. Dentro de un mensaje también se arrastran los **botones** (plantilla y rápidos), las **secciones y filas** de la lista y las **tarjetas del carrusel**. Las flechas **↑ / ↓** siguen funcionando igual.
- **Soltar archivos**: en cualquier campo de media (avatar, imagen, vídeo, sticker, audio, cabecera de plantilla, tarjetas del carrusel) eliges el origen con los radios **URL / Subir archivo**; en modo archivo, la zona de borde punteado abre el selector con un clic o acepta archivos **arrastrados desde el explorador** (se convierten a dataURL y se guardan con el estado).
- **Contadores de límites**: los campos con límite oficial muestran `n / límite` alineado a la derecha bajo el campo (cuerpo de texto 4096, captions 1024, cabecera/pie 60, botón de plantilla 25, quick reply 20, botón de lista 20, títulos 24, descripción de fila 72, texto de tarjeta 160…). Se ponen **ámbar al 90 %** y **rojo al pasarse**, sin cortar nunca la escritura.
- **Barra de formato**: en los cuerpos grandes (texto, plantilla y lista), los botones **B / I / S / </>** envuelven la selección del textarea con el marcado de WhatsApp (`*negrita*`, `_cursiva_`, `~tachado~`, `` `monoespaciado` ``), manteniendo el cursor en su sitio.
- **Variables de plantilla**: el botón **«+ Añadir variable»** (cuerpo y cabecera de texto de plantillas) inserta `{{1}}`, `{{2}}`… en el cursor, contando las que ya contiene el texto.
- **Cabecera opcional**: en plantillas y botones rápidos, el interruptor **Mostrar cabecera** despliega las mini-tarjetas Texto / Imagen / Vídeo / Documento y sus campos (texto de cabecera o media).
### Flujos con respuestas encadenadas
La gracia de los mockups interactivos: dentro de cada botón (de plantilla o rápido), fila de lista o tarjeta de carrusel hay un sub-editor **«Respuestas»** donde añades mensajes entrantes que llegarán al pulsarlo. Al hacer clic en el botón en el teléfono:
1. Sale tu burbuja con el **texto del botón** (ticks ✓ → ✓✓ → azul, ~800 ms cada paso).
2. Aparece el indicador **escribiendo…** (~900 ms).
3. Llegan las respuestas encadenadas una a una, con scroll al fondo.
Si un botón no tiene respuestas, al pulsarlo solo sale la burbuja con su texto. Si un botón tiene **URL**, en lugar de flujo se abre el enlace en una pestaña nueva (igual que el botón URL y las tarjetas con URL).
### Exportar e importar JSON
- **Exportar** (barra superior) descarga `wam-demo.json` con todo el estado: cuenta, tema y mensajes (incluidas las respuestas anidadas).
- **Importar** carga ese archivo: se normaliza (rellena campos que falten y corrige tipos inválidos), se guarda y se re-renderiza todo. Ideal para compartir una demo o hacer copias de seguridad, ya que `localStorage` puede perderse al limpiar el navegador.
---
## Modo demo (columna derecha)
- **Reproducir demo**: vacía el chat y revela los mensajes uno a uno (~600 ms por mensaje, con «escribiendo…» antes de cada mensaje entrante), como si la conversación ocurriera en directo. Mientras corre se ve el contador «Paso N/M»; pulsar de nuevo (**■ Detener**) lo cancela.
- **Velocidad**: el selector junto al botón ajusta la reproducción (0,5x, 1x, 2x).
- **Zoom** (solo escritorio): *Ajustar* calcula el tamaño del teléfono según el hueco; *100 %* y *125 %* lo fijan y el panel hace scroll. Se recuerda en este navegador.
- **Repetir desde el inicio** (antes «Reiniciar chat»): descarta lo pulsado y escrito en el teléfono y vuelve al guion desde el primer mensaje.
- **Nueva demo** (botón de la barra superior o tecla **N**): abre los escenarios de ejemplo y tus demos guardadas.
- **Deshacer / Rehacer**: botones de la barra superior o **Ctrl/⌘ + Z** y **Ctrl/⌘ + Shift + Z**. Cargar un escenario, una demo o el ejemplo deja siempre un punto de deshacer.
- **Mensajes libres**: escribe en el campo *Mensaje* del composer y envía (Enter o botón): sale una burbuja con la **hora actual** y ticks automáticos ✓ → ✓✓ → ✓✓ azul.
- **Hoja de lista (sheet)**: al pulsar el botón de un mensaje de tipo *Lista* se abre la hoja inferior con las secciones y filas; toca una fila para disparar su flujo, o toca el fondo oscuro para cerrarla.
- **Modo presentación**: oculta el editor y deja solo el iPhone centrado, perfecto para pantallazos o para proyectar. Se alterna con el botón *Presentación* de la barra superior.
- **Tema**: alterna claro/oscuro en toda la app (editor y chat).
- **Teclado**: el enlace **Saltar a la vista previa** (visible al tabular) y las teclas **G** / **F6** alternan el foco entre editor y teléfono. El diálogo *Atajos* lista el resto.
---
## Tipos de mensaje soportados (13)
`text` · `image` · `video` · `audio` · `document` · `sticker` · `location` · `contact` · `template` · `buttons` (quick replies) · `list` · `cta_url` · `carousel`
Detalles fieles a la API real (ver `docs/research-api.md`): máx. 3 quick replies, plantillas con hasta 10 botones (con más de 3 se muestran 2 y el plegado *«Ver todas las opciones»*), filas de lista con título y descripción, carrusel de 2 a 5 tarjetas con scroll y puntos indicadores, ticks de entrega solo en mensajes salientes, etc.
---
## Limitaciones
- **Persistencia por `localStorage`** (clave `wam-mockup-v1`), con una cuota de **~5 MB** según el navegador. Las imágenes y vídeos guardados como dataURL ocupan mucho (~33 % más que el archivo original), así que con varios medios grandes puedes agotarla; si eso pasa, los cambios simplemente dejan de guardarse (la app sigue funcionando). Exporta a JSON para no perder trabajo. Nota: al abrir por `file://`, Chrome/Edge/Firefox comparten el mismo origen, por lo que todas las demos locales comparten ese almacenamiento.
- **No envía mensajes reales**: es un mockup visual; no hay llamadas a la API de WhatsApp, números de teléfono ni tokens. Los botones con URL abren enlaces, nada más.
- **Las imágenes subidas se guardan como dataURL** (base64 dentro del propio JSON del estado). Eso hace el estado autosuficiente y portable en el export, pero infla el tamaño del JSON y de `localStorage`. Para medios pesados, usa URL remotas.
- Los iconos del composer (clip y micro) y los de llamada del encabezado son decorativos: no hacen nada.
- Vídeos sin URL/archivo se representan con una imagen placeholder (un `<video>` no puede mostrar un SVG).
---
## Consejos para capturas limpias
1. Activa el **modo presentación** para ocultar el editor y quedarte solo con el iPhone.
2. Elige el **tema** (claro u oscuro) según el fondo donde vayas a incrustar la captura.
3. Ajusta la **hora de cada mensaje** a mano (`10:24`, `9:41`…) para que la conversación se vea creíble y coherente.
4. Fija el **estado de ticks** de tus mensajes salientes (p. ej. todos en *Leído* ✓✓ azul) antes de capturar; si usas el composer, los ticks avanzan solos en ~1,6 s.
5. Usa **Reproducir demo** para grabar la pantalla mientras la conversación aparece paso a paso, o haz clic en los botones/filas para capturar el momento exacto del flujo.
6. Escribe el último mensaje desde el **composer** para que lleve la hora real de la captura.
7. Usa el **zoom del navegador** (Ctrl/⌘ + +) para agrandar el iPhone antes de la captura; todo escala limpiamente.
8. Antes de una demo ante público, **Restablecer** deja la conversación de «Café Aurora» en su estado original.