Aplicación web móvil ultra-rápida para encontrar ayuda médica en segundos. PWA (Progressive Web App) desarrollada con React, Vite y Tailwind CSS.
- Búsqueda rápida de ayuda médica: Distingue entre centros médicos/urgencias y farmacias
- Radio amplio de búsqueda: 20 km para cubrir zonas rurales o periféricas
- Optimización de costes: No carga el mapa ni hace peticiones API hasta que el usuario lo solicita
- Sistema de protección: Circuit breaker que limita las llamadas API a 10 por día
- PWA completa: Funciona offline y se puede instalar en el dispositivo
- Diseño Mobile First: Interfaz optimizada para móviles con diseño limpio y alertas visuales claras
- Indicador de centros privados: Badge visual para distinguir centros sanitarios privados
- Horarios completos: Muestra horarios de apertura y cierre (especialmente para farmacias)
- Llamadas directas: Teléfono clicable para llamar directamente desde la app
- Multiidioma automático: Detecta el idioma del dispositivo y muestra la interfaz en español, inglés, francés, alemán, portugués o italiano (inglés por defecto si no está soportado)
- Node.js 18+ y npm
- Cuenta de Google Cloud Platform con tu propia API Key:
- Google Maps JavaScript API habilitada
- Google Places API (New) habilitada
- IMPORTANTE: Debes crear tu propia API Key en Google Cloud Console. Esta aplicación NO incluye una API Key y necesitas configurar la tuya propia.
- API Key con las restricciones apropiadas (recomendado: restringir por dominio/IP en producción)
- Clona el repositorio:
git clone <url-del-repositorio>
cd sos-helper- Instala las dependencias:
npm install- Crea un archivo
.enven la raíz del proyecto:
cp .env.example .env-
Obtén tu propia API Key de Google Cloud Platform:
- Ve a Google Cloud Console
- Crea un nuevo proyecto o selecciona uno existente
- Habilita las siguientes APIs:
- Google Maps JavaScript API
- Google Places API (New)
- Ve a "Credenciales" → "Crear credenciales" → "Clave de API"
- Copia tu API Key
-
Edita
.envy agrega tu API Key de Google Maps:
VITE_GOOGLE_MAPS_API_KEY=tu_api_key_aqui
.env.
npm run devLa aplicación estará disponible en http://localhost:5173
npm run build
npm run preview- Botón Rojo (URGENCIAS / CENTROS MÉDICOS): Busca hospitales, urgencias, ambulatorios, clínicas y centros sanitarios privados abiertos ahora. Cualquier lugar donde pueda atender un médico.
- Botón Verde (FARMACIAS): Busca únicamente farmacias abiertas ahora
- Botón Flotante: Llamada directa al 112 (configurable en
src/components/HomeScreen.jsx) - Protocolo de Emergencia: Tarjeta informativa siempre visible con instrucciones básicas
- Mapa interactivo (45% de pantalla): Muestra tu ubicación y los lugares encontrados con marcadores
- Lista de resultados (55% de pantalla): Ordenada por distancia (más cercano primero)
- Información de cada lugar:
- Nombre y badge "P" si es privado
- Dirección
- Distancia exacta en km
- Estado de apertura (Abierto ahora)
- Horarios: Para farmacias muestra "9:00 AM - 8:00 PM", para centros médicos muestra "Cierra: 8:00 PM"
- Teléfono clicable (abre la app de llamadas)
- Botón "IR AHORA" que abre Google Maps para navegación
La aplicación incluye un sistema de circuit breaker que:
- Limita las llamadas a la API a 10 por día
- Resetea el contador automáticamente cada día
- Muestra una alerta si se alcanza el límite: "Límite de seguridad diario alcanzado. Por favor llama al 112 manualmente"
- Usa
localStoragepara persistir el contador
Edita src/components/HomeScreen.jsx y modifica la constante EMERGENCY_NUMBER:
const EMERGENCY_NUMBER = '911' // Para países que usan 911Edita src/utils/apiLimiter.js y modifica la constante DAILY_LIMIT:
const DAILY_LIMIT = 20 // Cambiar a 20 llamadas por díaEdita src/utils/googlePlaces.js y modifica la constante RADIUS:
const RADIUS = 30000; // 30 km en metrosLa aplicación detecta automáticamente el idioma del dispositivo usando navigator.language.
Idiomas soportados:
- Español (es)
- Inglés (en) - idioma por defecto
- Francés (fr)
- Alemán (de)
- Portugués (pt)
- Italiano (it)
Si el idioma del dispositivo no está soportado, la aplicación se mostrará en inglés.
Para añadir o modificar traducciones, edita src/utils/i18n.js y añade las claves de traducción correspondientes.
sos-helper/
├── public/
│ ├── icon-192x192.png # Icono PWA 192x192
│ ├── icon-512x512.png # Icono PWA 512x512
│ └── vite.svg
├── src/
│ ├── components/
│ │ ├── EmergencyProtocol.jsx # Tarjeta de protocolo de emergencia
│ │ ├── HomeScreen.jsx # Pantalla inicial con botones de acción
│ │ ├── PlaceCard.jsx # Componente de tarjeta de resultado
│ │ └── ResultsScreen.jsx # Pantalla de resultados con mapa y lista
│ ├── utils/
│ │ ├── apiLimiter.js # Circuit breaker para limitar llamadas API
│ │ ├── googlePlaces.js # Utilidades Google Places (búsqueda, horarios, navegación)
│ │ ├── placesCache.js # Sistema de caché para resultados de búsqueda
│ │ └── i18n.js # Sistema de internacionalización (multiidioma)
│ ├── App.jsx # Componente principal
│ ├── main.jsx # Punto de entrada
│ └── index.css # Estilos globales con Tailwind
├── scripts/
│ ├── create-github-repo.sh # Script para crear repositorio en GitHub
│ └── generate-icons.js # Script para generar iconos PNG
├── .env.example # Ejemplo de variables de entorno
├── index.html
├── package.json
├── tailwind.config.js
├── postcss.config.js
├── vite.config.js # Configuración Vite con PWA
├── vercel.json # Configuración para despliegue en Vercel
└── README.md
- React 19: Framework UI
- Vite 7: Build tool y dev server
- Tailwind CSS 4: Estilos utility-first (Mobile First)
- @vis.gl/react-google-maps: Integración con Google Maps
- vite-plugin-pwa: Capacidades PWA (service worker, manifest)
- lucide-react: Iconos modernos y consistentes
La aplicación está configurada para desplegarse fácilmente en Vercel:
-
Desde la web:
- Ve a vercel.com y crea una cuenta
- Conecta tu repositorio de GitHub
- Vercel detectará automáticamente que es un proyecto Vite
- Añade la variable de entorno
VITE_GOOGLE_MAPS_API_KEYen la configuración del proyecto - Deploy automático en cada push
-
Desde la CLI:
npm install -g vercel vercel login vercel
- Sigue las instrucciones interactivas
- Añade la variable de entorno
VITE_GOOGLE_MAPS_API_KEYen el dashboard de Vercel
Importante: Asegúrate de configurar la variable de entorno VITE_GOOGLE_MAPS_API_KEY en Vercel (Settings → Environment Variables).
El archivo vercel.json ya está configurado para el despliegue correcto de la PWA.
La aplicación también puede desplegarse en otras plataformas como Netlify, Firebase Hosting o Cloudflare Pages, pero necesitarás crear los archivos de configuración correspondientes.
- API Key propia requerida:
- DEBES crear tu propia API Key en Google Cloud Platform
- Esta aplicación NO incluye ninguna API Key
- Sin una API Key válida, la aplicación no funcionará
- Asegúrate de configurar las restricciones apropiadas en Google Cloud Console (recomendado: restringir por dominio/IP en producción)
- Costes: Google Places API tiene costes asociados. El sistema de circuit breaker ayuda a limitar llamadas, pero monitorea tu uso en Google Cloud Console
- HTTPS: Las PWA requieren HTTPS en producción (excepto localhost)
- Geolocalización: La app requiere permisos de geolocalización del navegador
- Detección de privado: La app detecta automáticamente centros privados basándose en palabras clave en el nombre y dirección
- Horarios: Los horarios se extraen de Google Places API y se muestran en formato 12h (AM/PM)
- Verifica que hayas creado tu propia API Key en Google Cloud Console
- Verifica que tu API Key esté correctamente configurada en
.env - Asegúrate de que Google Maps JavaScript API esté habilitada en tu proyecto de Google Cloud
- Verifica que la API Key tenga permisos para usar Google Maps JavaScript API
- Revisa la consola del navegador para errores (puede mostrar errores de API Key inválida)
- En producción, verifica que la variable de entorno
VITE_GOOGLE_MAPS_API_KEYesté configurada
- Verifica que Google Places API (New) esté habilitada
- Asegúrate de tener permisos de geolocalización activados
- Comprueba que hay lugares abiertos en un radio de 20 km
- Verifica que el filtro
openNow: trueno esté excluyendo todos los resultados
- El límite diario es de 10 llamadas por defecto
- Espera hasta el día siguiente o ajusta el límite en
src/utils/apiLimiter.js - Considera aumentar el límite si es necesario
- Algunos lugares pueden no tener horarios disponibles en Google Places API
- La app intenta extraer horarios de múltiples formatos
- Si no hay horarios, solo se mostrará "Abierto ahora"
Este proyecto es de código abierto y está disponible bajo la licencia MIT.
Las contribuciones son bienvenidas. Por favor, abre un issue o pull request.
Desarrollado como una aplicación crítica de emergencia médica con enfoque en:
- Velocidad: Carga rápida, sin peticiones innecesarias
- UX/UI: Diseño limpio, botones grandes, alertas visuales claras
- Confiabilidad: Sistema de protección de costes, manejo de errores robusto
- Accesibilidad: Funciona offline, instalable como PWA