feat(propuesta): pasarela paso a paso con autodetección de ubicación y FAB
- Campo universal de ubicación (Google Maps/Waze/OSM/coordenadas/dirección) sobre proveedores extensibles (src/utils/ubicacion) con resolver e inferencia inversa Nominatim (nombre/provincia pre-rellenados, alias cooficiales) - FAB flotante abajo a la derecha que abre la pasarela en un modal accesible (Escape, foco contenido, responsive); sin descripción ni puntuación; avisos de duplicado y filtro de palabras dentro del modal - Aviso PWA reposicionado: tarjeta abajo a la izquierda en móvil, botón compacto arriba a la izquierda en PC (no tapa el FAB) - Suite de pruebas: 88 unitarias/componente (vitest + RTL, offline) y 10 de integración (supertest + SQLite :memory: y Nominatim real opt-in) - CI: workflow de Gitea Actions con npm test + build en push/PR e integración manual
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# Pasarela para proponer locales
|
||||
|
||||
## Why
|
||||
|
||||
El botón "Proponer local" actual vive en la cabecera y despliega un formulario largo en línea con muchos campos a la vez (nombre, provincia, categoría, ubicación con dos modos, descripción y puntuación). En móvil resulta abrumador y la ubicación exige que el usuario elija manualmente entre "dirección" o "enlace de Google Maps". Queremos una experiencia guiada, campo a campo, que arranque por la ubicación (un único campo universal que acepte enlaces de Google Maps, Waze, OpenStreetMap o coordenadas) y que infiera automáticamente nombre y provincia, reduciendo el esfuerzo del proponente y los errores de datos.
|
||||
|
||||
## What Changes
|
||||
|
||||
- El botón "Proponer local" pasa de la cabecera a un **botón flotante (FAB) fijo en la esquina inferior derecha**, visible y usable tanto en PC como en móvil.
|
||||
- Al pasar el ratón por encima (hover / foco), muestra un **tooltip** que explica que sirve para añadir un nuevo local.
|
||||
- Al pulsarlo se abre una **pasarela (wizard) en un modal**: cada campo se especifica en su propia pantalla, con navegación atrás/siguiente e indicador de progreso.
|
||||
- **Primera pantalla: Ubicación**, un solo campo universal que autodetecta el origen del input: enlace de Google Maps, enlace de Waze, enlace de OpenStreetMap o coordenadas geográficas (y texto de dirección como fallback vía Nominatim).
|
||||
- **Nombre y Provincia se infieren** automáticamente a partir de la ubicación introducida (geocodificación inversa con Nominatim), quedando pre-rellenados en sus pantallas para que el usuario los confirme o corrija.
|
||||
- **Integraciones con backends de mapas extensible**: varias clases (adaptadores) implementan una misma interfaz (`detecta`/`extrae`), registradas en un resolver que autodetecta el proveedor. El resultado de `extrae` es un objeto extensible (coordenadas hoy, otros campos en el futuro). Añadir un proveedor nuevo no debe requerir tocar el resto del código.
|
||||
- **Se elimina el campo comentario/descripción** del formulario de propuesta (se gestionará en otro cambio posterior).
|
||||
- **Se elimina el campo puntuación** del formulario de propuesta.
|
||||
- Se mantiene la lógica existente de validación: filtro de palabras prohibidas, comprobación de duplicados (avisos dentro del modal) y aceptación de la política de privacidad antes de enviar.
|
||||
- No hay cambios de API: el backend ya tolera `descripcion` y `puntuacion` ausentes (valores por defecto).
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `boton-flotante-proponer-local`: botón de acción flotante fijo en la esquina inferior derecha, responsive (PC y móvil), con tooltip al hover y apertura de la pasarela al pulsarlo.
|
||||
- `pasarela-proponer-local`: modal de propuesta paso a paso con una pantalla por campo (Ubicación → Nombre → Provincia → Categoría → Tipo específico → Revisión y envío), sin campos de comentario ni puntuación.
|
||||
- `proveedores-ubicacion`: sistema extensible de integraciones con backends de ubicación (Google Maps, Waze, OpenStreetMap, coordenadas y geocodificación Nominatim) bajo una interfaz común, capaz de extraer coordenadas e inferir nombre y provincia, ampliable a otras extracciones futuras.
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- No existen specs previas en openspec/specs/ — todas las capacidades son nuevas -->
|
||||
|
||||
## Impact
|
||||
|
||||
- **`src/App.jsx`**: se elimina el botón de cabecera y el formulario en línea (`mostrarForm`); se sustituye por el FAB + modal. La lógica de envío (filtro de palabras, duplicados, `enviarPropuesta`) se reutiliza.
|
||||
- **Nuevos componentes** (`src/components/`): botón flotante, modal de la pasarela y pantallas de cada paso.
|
||||
- **Nuevos módulos** (`src/utils/proveedores/`): interfaz común, adaptadores por proveedor y resolver de autodetección.
|
||||
- **`src/utils/geo.js`**: se reutiliza/amplía (geocodificación inversa vía Nominatim; extracción de coordenadas por proveedor).
|
||||
- **Sin cambios de backend**: `server/index.js` y la base de datos ya aceptan propuestas sin `descripcion` ni `puntuacion` (defaults `null`/`0`); el panel de administración no se modifica.
|
||||
- **`src/AppMovil.jsx`** no está referenciado por `main.jsx` (código muerto): no se toca.
|
||||
- Accesibilidad: tooltip también vía `aria-label`, foco atrapado en el modal, cierre con Escape.
|
||||
Reference in New Issue
Block a user