Correct "Update README"
This commit is contained in:
433
README.md
433
README.md
@@ -1,301 +1,238 @@
|
|||||||
# 🗺️ BRAVIO - Mapa Interactivo de Universidades
|
# Asistente BRAVIOO
|
||||||
|
Diagnóstico inteligente de sostenibilidad empresarial
|
||||||
|
|
||||||
Una aplicación de mapa interactivo construida con **Nuxt 3** y **Mapbox GL** que muestra universidades de América Latina con el estado de sus oficinas de defensoría. Parte del proyecto Erasmus BRAVIO.
|
Asistente BRAVIOO es una herramienta interactiva desarrollada con Vue/Nuxt 3 que permite a las empresas realizar un diagnóstico guiado de sostenibilidad, ofreciendo resultados automáticos por bloques y un informe final con recomendaciones accionables.
|
||||||
|
|
||||||

|
👉 Puedes ver la versión desplegada aquí: http://bravioo.enreda.coop/
|
||||||
|
|
||||||
## 📋 Tabla de Contenidos
|
## ¿Qué es el Asistente BRAVIOO?
|
||||||
|
|
||||||
- [Descripción General](#descripción-general)
|
Se trata de un formulario dinámico, flexible y totalmente configurable, diseñado para acompañar a organizaciones en un proceso de evaluación interna.
|
||||||
- [Características](#características)
|
El asistente guía al usuario a través de distintas pantallas (slices), recopila respuestas, calcula puntuaciones y genera un diagnóstico final.
|
||||||
- [Stack Tecnológico](#stack-tecnológico)
|
|
||||||
- [Requisitos Previos](#requisitos-previos)
|
|
||||||
- [Instalación](#instalación)
|
|
||||||
- [Configuración](#configuración)
|
|
||||||
- [Estructura del Proyecto](#estructura-del-proyecto)
|
|
||||||
- [Uso](#uso)
|
|
||||||
- [Estructura de Datos](#estructura-de-datos)
|
|
||||||
- [Personalización](#personalización)
|
|
||||||
- [Contribuir](#contribuir)
|
|
||||||
- [Licencia](#licencia)
|
|
||||||
|
|
||||||
## 🎯 Descripción General
|
## Características principales
|
||||||
|
|
||||||
BRAVIO es una aplicación de mapeo interactivo que ayuda a visualizar y explorar universidades participantes en el proyecto Erasmus BRAVIO. La aplicación proporciona información detallada sobre el estado de la oficina de defensoría de cada institución y permite a los usuarios filtrar y buscar a través de los datos.
|
- Navegación por pantallas tipo welcome, question, feedback y end.
|
||||||
|
|
||||||
### Objetivos Clave
|
- Cálculo automático de:
|
||||||
|
|
||||||
- Visualizar ubicaciones de universidades en América Latina
|
- Resultados por bloque temático.
|
||||||
- Filtrar universidades por país y estado de la defensoría
|
|
||||||
- Conocer la etapa de desarrollo de la oficina de defensoría de cada institución
|
|
||||||
- Proporcionar soporte multilingüe (español y portugués)
|
|
||||||
- Asegurar diseño responsivo para móvil y escritorio
|
|
||||||
|
|
||||||
## ✨ Características
|
- Resultado global.
|
||||||
|
|
||||||
### Características Principales
|
- Recomendaciones asociadas.
|
||||||
|
|
||||||
- **Mapa Interactivo**: Construido con Mapbox GL para navegación fluida con pan, zoom y rotación
|
- Guardado de progreso y respuestas en localStorage.
|
||||||
- **Barras Laterales Duales**:
|
|
||||||
- Barra lateral izquierda para búsqueda y filtrado
|
|
||||||
- Barra lateral derecha para información detallada de la universidad
|
|
||||||
- **Marcadores Codificados por Color**: Indicadores de estado visuales
|
|
||||||
- 🔵 Cian: Defensoría activa
|
|
||||||
- 🟠 Naranja: En desarrollo
|
|
||||||
- 🔴 Rojo: En estudio/Sin defensoría
|
|
||||||
- **Filtrado Avanzado**:
|
|
||||||
- Búsqueda por nombre de universidad o ciudad
|
|
||||||
- Filtro por país
|
|
||||||
- Filtro por estado de la defensoría
|
|
||||||
- **Diseño Responsivo**: Optimizado para móvil, tableta y escritorio
|
|
||||||
- **Soporte Multilingüe**: Español (ES) y Portugués (PT)
|
|
||||||
- **Exportación CSV**: Descarga datos filtrados para análisis adicional
|
|
||||||
|
|
||||||
### Características Específicas para Móvil
|
- Posibilidad de: Flujo lineal y Flujo condicional según respuestas.
|
||||||
|
|
||||||
- Gestión automática de barras laterales (la barra izquierda se oculta al ver detalles de universidad)
|
- Configuración 100% mediante un archivo surveyData.js.
|
||||||
- Controles optimizados para táctil
|
|
||||||
- Ajustes de diseño responsivo
|
|
||||||
|
|
||||||
## 🛠️ Stack Tecnológico
|
- Generación de informe final descargable en PDF (pdfMake).
|
||||||
|
|
||||||
- **Framework**: [Nuxt 3](https://nuxt.com/) (Vue 3 con Options API)
|
## 🧩 Arquitectura general del proyecto
|
||||||
- **Librería de Mapas**: [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/)
|
|
||||||
- **Estilos**: [Tailwind CSS](https://tailwindcss.com/)
|
|
||||||
- **Gestión de Estado**: [Vuex](https://vuex.vuejs.org/)
|
|
||||||
- **Lenguaje**: JavaScript
|
|
||||||
- **Gestor de Paquetes**: npm/yarn/pnpm
|
|
||||||
|
|
||||||
## 📦 Requisitos Previos
|
El asistente se sostiene sobre tres pilares fundamentales:
|
||||||
|
|
||||||
Antes de comenzar, asegúrate de tener instalado lo siguiente:
|
### 1. index.vue — Motor del asistente
|
||||||
|
|
||||||
- **Node.js**: v16.x o superior
|
Controla:
|
||||||
- **npm**: v7.x o superior (o yarn/pnpm)
|
|
||||||
- **Cuenta de Mapbox**: [Regístrate gratis](https://account.mapbox.com/auth/signup/) para obtener un token de acceso
|
|
||||||
|
|
||||||
## 🚀 Instalación
|
- Flujo entre pantallas,
|
||||||
|
- Almacenamiento de respuestas,
|
||||||
|
- Cálculo de puntuaciones por bloque,
|
||||||
|
- Diagnóstico final.
|
||||||
|
|
||||||
1. **Clona el repositorio**
|
Principales estados manejados:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/tu-usuario/bravio-map.git
|
|
||||||
cd bravio-map
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Instala las dependencias**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
# o
|
|
||||||
yarn install
|
|
||||||
# o
|
|
||||||
pnpm install
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Configura las variables de entorno**
|
|
||||||
|
|
||||||
Crea un archivo `.env` en el directorio raíz:
|
|
||||||
|
|
||||||
```env
|
|
||||||
NUXT_PUBLIC_MAPBOX_TOKEN=tu_token_de_acceso_mapbox_aqui
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Ejecuta el servidor de desarrollo**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
# o
|
|
||||||
yarn dev
|
|
||||||
# o
|
|
||||||
pnpm dev
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Abre tu navegador**
|
|
||||||
|
|
||||||
Navega a `http://localhost:3000`
|
|
||||||
|
|
||||||
## ⚙️ Configuración
|
|
||||||
|
|
||||||
### Token de Acceso de Mapbox
|
|
||||||
|
|
||||||
1. Regístrate en [Mapbox](https://account.mapbox.com/auth/signup/)
|
|
||||||
2. Crea un nuevo token o usa el token público predeterminado
|
|
||||||
3. Añade el token a tu archivo `.env`
|
|
||||||
4. Actualiza el token en tu componente:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// En tu componente de mapa
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
accessToken: process.env.NUXT_PUBLIC_MAPBOX_TOKEN || 'tu_token_aqui'
|
surveyData,
|
||||||
|
currentSliceId: surveyData.slices[0].id,
|
||||||
|
answers: [],
|
||||||
|
score: null,
|
||||||
|
results: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Estilo de Mapbox
|
### 2. surveyData.js — Configuración del diagnóstico
|
||||||
|
|
||||||
La aplicación usa un estilo personalizado de Mapbox. Para cambiarlo:
|
Define:
|
||||||
|
|
||||||
```javascript
|
- Todas las pantallas del asistente,
|
||||||
this.map = new mapboxgl.Map({
|
- Reglas de evaluación de cada bloque,
|
||||||
container: 'mapContainer',
|
- Reglas del diagnóstico global,
|
||||||
style: 'mapbox://styles/tu-usuario/tu-id-estilo', // Cambia esto
|
- Textos, títulos y contenidos visibles para el usuario.
|
||||||
center: [-60, -15],
|
|
||||||
zoom: 2.5
|
### 3. Componentes visuales (slices)
|
||||||
})
|
|
||||||
|
Representan cada tipo de pantalla:
|
||||||
|
|
||||||
|
- SliceWelcome.vue
|
||||||
|
- SliceQuestion.vue
|
||||||
|
- SliceFeedback.vue
|
||||||
|
- SliceEnd.vue
|
||||||
|
|
||||||
|
Cada slice se renderiza según el valor type presente en surveyData.slices.
|
||||||
|
|
||||||
|
#### 🔄 Flujo del usuario
|
||||||
|
|
||||||
|
- Pantalla de bienvenida
|
||||||
|
- Bloque de preguntas
|
||||||
|
- Pantalla de feedback parcial con recomendaciones
|
||||||
|
- Repetición del patrón para los distintos bloques
|
||||||
|
- Resumen final con diagnóstico global y descarga de informe
|
||||||
|
|
||||||
|
#### 🧮 Cálculo y lógica interna
|
||||||
|
#### 1. Navegación
|
||||||
|
|
||||||
|
Cada slice define su siguiente paso mediante la propiedad next, que puede ser:
|
||||||
|
|
||||||
|
Lineal:
|
||||||
|
```bash
|
||||||
|
"next": "B1-02"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📁 Estructura del Proyecto
|
Condicional:
|
||||||
|
```bash
|
||||||
```
|
"next": { yes: "Q2", no: "Q3" }
|
||||||
bravio-map/
|
|
||||||
├── assets/ # CSS, imágenes, fuentes
|
|
||||||
├── components/ # Componentes Vue
|
|
||||||
│ └── mapComp.vue # Componente principal del mapa
|
|
||||||
├── data/ # Archivos de datos JSON
|
|
||||||
│ └── universities.json
|
|
||||||
├── layouts/ # Layouts de Nuxt
|
|
||||||
├── pages/ # Páginas/rutas de Nuxt
|
|
||||||
├── public/ # Recursos estáticos
|
|
||||||
│ └── LOGOBraviooB.png
|
|
||||||
├── store/ # Store de Vuex
|
|
||||||
│ └── index.js # Gestión de estado de idioma
|
|
||||||
├── nuxt.config.ts # Configuración de Nuxt
|
|
||||||
├── tailwind.config.js # Configuración de Tailwind
|
|
||||||
├── package.json
|
|
||||||
└── README.md
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📖 Uso
|
index.vue gestiona:
|
||||||
|
|
||||||
### Navegación Básica
|
- Avanzar (goToNext(event)),
|
||||||
|
- Retroceder (goToPrevious()),
|
||||||
|
- Almacenar historial en localStorage.
|
||||||
|
|
||||||
1. **Desplazar el mapa**: Clic y arrastrar
|
#### 2. Registro de respuestas
|
||||||
2. **Zoom**: Usar la rueda del ratón o controles de zoom
|
|
||||||
3. **Seleccionar universidad**: Clic en un marcador o elemento de la lista
|
|
||||||
4. **Ver detalles**: La barra lateral derecha muestra información detallada
|
|
||||||
5. **Cerrar detalles**: Clic en el botón X en la barra lateral derecha
|
|
||||||
|
|
||||||
### Filtrado de Datos
|
Las respuestas se almacenan con estructura:
|
||||||
|
|
||||||
#### Búsqueda
|
```bash
|
||||||
Escribe en el cuadro de búsqueda para filtrar universidades por nombre o ciudad.
|
|
||||||
|
|
||||||
#### Filtro de País
|
|
||||||
Selecciona un país del menú desplegable para mostrar solo universidades en ese país.
|
|
||||||
|
|
||||||
#### Filtro de Estado
|
|
||||||
Filtra universidades por el estado de su defensoría:
|
|
||||||
- **Activa/Ativa**: Defensoría activa
|
|
||||||
- **En desarrollo/Em desenvolvimento**: En desarrollo
|
|
||||||
- **En estudio/Em estudo**: En estudio
|
|
||||||
|
|
||||||
#### Limpiar Filtros
|
|
||||||
Haz clic en el botón "LIMPIAR/LIMPAR" para restablecer todos los filtros.
|
|
||||||
|
|
||||||
### Cambiar Idioma
|
|
||||||
|
|
||||||
Usa el selector de idioma en la esquina inferior derecha para cambiar entre:
|
|
||||||
- 🇪🇸 Español
|
|
||||||
- 🇧🇷 Portugués
|
|
||||||
|
|
||||||
### Exportar Datos
|
|
||||||
|
|
||||||
Haz clic en "Descargar CSV/Baixar CSV" para descargar los resultados filtrados actuales como archivo CSV.
|
|
||||||
|
|
||||||
## 📊 Estructura de Datos
|
|
||||||
|
|
||||||
Las universidades se almacenan en `data/universities.json` con la siguiente estructura:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
{
|
||||||
"id": 1,
|
sectionId,
|
||||||
"university": {
|
sectionTitle,
|
||||||
"es": "Universidad Carlos III",
|
sliceId,
|
||||||
"pt": "Universidade Carlos III"
|
value,
|
||||||
},
|
score,
|
||||||
"city": {
|
questionTotalPoints
|
||||||
"es": "Buenos Aires",
|
|
||||||
"pt": "Buenos Aires"
|
|
||||||
},
|
|
||||||
"country": {
|
|
||||||
"es": "Argentina",
|
|
||||||
"pt": "Argentina"
|
|
||||||
},
|
|
||||||
"status": "activa",
|
|
||||||
"coordinates": [-58.3816, -34.6037],
|
|
||||||
"web": "https://sitio-universidad.com",
|
|
||||||
"logo": "/logos/logo-universidad.png",
|
|
||||||
"defensor": ["Juan Pérez", "María García"],
|
|
||||||
"campus": [
|
|
||||||
{ "es": "Campus Central", "pt": "Campus Central" }
|
|
||||||
],
|
|
||||||
"contact": ["contacto@universidad.edu"],
|
|
||||||
"telephone": "+54 11 1234 5678",
|
|
||||||
"yearOfCreation": 2020
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Campos Requeridos
|
#### 3. Resultados por bloque
|
||||||
|
|
||||||
- `id`: Identificador único
|
Cuando el usuario alcanza una pantalla tipo feedback, se ejecuta:
|
||||||
- `university`: Nombre de la universidad (objeto multilingüe)
|
|
||||||
- `city`: Nombre de la ciudad (objeto multilingüe)
|
|
||||||
- `country`: Nombre del país (objeto multilingüe)
|
|
||||||
- `status`: Uno de `"activa"`, `"en-desarrollo"`, `"en-estudio"`
|
|
||||||
- `coordinates`: Array `[longitud, latitud]`
|
|
||||||
|
|
||||||
### Campos Opcionales
|
- Filtrado de respuestas por bloque,
|
||||||
|
- Cómputo de puntos obtenidos,
|
||||||
|
- Cálculo de puntos máximos del bloque,
|
||||||
|
- Evaluación según surveyData.rules[sectionId].
|
||||||
|
|
||||||
- `web`: URL del sitio web de la universidad
|
Ejemplo:
|
||||||
- `logo`: Ruta al logo de la universidad
|
``` bash
|
||||||
- `defensor`: Array de nombres de defensores
|
{
|
||||||
- `campus`: Array de ubicaciones de campus (multilingüe)
|
sectionId: "B1",
|
||||||
- `contact`: Array de correos electrónicos de contacto
|
sectionTitle: "Impacto social",
|
||||||
- `telephone`: Número de teléfono
|
sectionPossibleTotalPoints: 20,
|
||||||
- `yearOfCreation`: Año de creación de la defensoría
|
score: 14,
|
||||||
|
result: "Recomendación específica..."
|
||||||
## 🎨 Personalización
|
}
|
||||||
|
|
||||||
### Colores
|
|
||||||
|
|
||||||
La aplicación usa un tema de degradado morado. Para personalizar:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<!-- Fondo de Barra Lateral Izquierda -->
|
|
||||||
<aside class="bg-gradient-to-br from-purple-900 via-purple-950 to-indigo-950">
|
|
||||||
|
|
||||||
<!-- Colores de Estado -->
|
|
||||||
<style>
|
|
||||||
.status-active { background: #22c5c2; } /* Cian */
|
|
||||||
.status-development { background: #ffa500; } /* Naranja */
|
|
||||||
.status-study { background: #ff4560; } /* Rojo */
|
|
||||||
</style>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Vista Inicial del Mapa
|
#### 4. Resultado global
|
||||||
|
|
||||||
Ajusta la posición inicial del mapa:
|
En el último slice (end):
|
||||||
|
|
||||||
```javascript
|
- Se suman los resultados parciales,
|
||||||
this.map = new mapboxgl.Map({
|
- Se calcula el máximo total,
|
||||||
container: 'mapContainer',
|
- Se aplica surveyData.finalRecommendations.total(score).
|
||||||
style: 'mapbox://styles/mariasaso/cme8hxq2w00cb01sb3jd105ue',
|
|
||||||
center: [-60, -15], // [longitud, latitud]
|
Ejemplo:
|
||||||
zoom: 2.5 // Nivel de zoom (0-22)
|
```bash
|
||||||
})
|
{
|
||||||
|
totalPossiblePoints: 80,
|
||||||
|
score: 52,
|
||||||
|
recommendations: "ISO 14001, B Corp..."
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
## 📂 Estructura del archivo surveyData.js
|
||||||
|
#### 1. Cabecera
|
||||||
|
```bash
|
||||||
|
export const surveyData = {
|
||||||
|
title: "Asistente BRAVIOO",
|
||||||
|
slices: [ ... ],
|
||||||
|
rules: { ... },
|
||||||
|
finalRecommendations: { ... }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### 2. Tipos de slices
|
||||||
|
|
||||||
### Estilos de Marcadores
|
| Tipo | Descripción |
|
||||||
|
| ---------- | -------------------------------------- |
|
||||||
|
| `welcome` | Introducción y presentación del bloque |
|
||||||
|
| `question` | Pregunta de diagnóstico con opciones |
|
||||||
|
| `feedback` | Resultados parciales por bloque |
|
||||||
|
| `end` | Diagnóstico general + descarga PDF |
|
||||||
|
|
||||||
Personaliza la apariencia de los marcadores en el método `addAllMarkers()`:
|
#### 📝 Ejemplo de slice tipo pregunta
|
||||||
|
```bash
|
||||||
|
{
|
||||||
|
id: "B2-01",
|
||||||
|
type: "question",
|
||||||
|
section: { id: "B2", title: "Transparencia y reporte" },
|
||||||
|
question: {
|
||||||
|
title: "¿Publica informes de sostenibilidad?",
|
||||||
|
description: "1 es el nivel más bajo y 5 el más alto."
|
||||||
|
},
|
||||||
|
input: {
|
||||||
|
type: "range",
|
||||||
|
options: [
|
||||||
|
{ value: "1", label: "1", score: 1 },
|
||||||
|
{ value: "2", label: "2", score: 2 },
|
||||||
|
...
|
||||||
|
]
|
||||||
|
},
|
||||||
|
questionTotalPoints: 5,
|
||||||
|
next: "B2-02"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### 🧠 Reglas de puntuación
|
||||||
|
- Por bloque:
|
||||||
|
```bash
|
||||||
|
rules: {
|
||||||
|
B0: (score) => score < 8
|
||||||
|
? "Necesita mejoras estructurales..."
|
||||||
|
: "Buen nivel de madurez.",
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Final:
|
||||||
|
```bash
|
||||||
|
finalRecommendations: {
|
||||||
|
total: (score) => {
|
||||||
|
if (score < 30) return "Acciones básicas recomendadas";
|
||||||
|
if (score < 50) return "Certificaciones iniciales sugeridas";
|
||||||
|
return "Lista para certificaciones avanzadas";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
## 📦 Generación de PDF
|
||||||
|
|
||||||
```javascript
|
En la pantalla final, el usuario puede descargar un informe PDF generado con:
|
||||||
const el = document.createElement('div');
|
|
||||||
el.style.backgroundColor = statusColor;
|
- pdfMake
|
||||||
el.style.width = '20px'; // Tamaño
|
- Fuentes integradas manualmente
|
||||||
el.style.height = '20px';
|
- Logo de Bravio
|
||||||
el.style.borderRadius = '50%'; // Forma
|
- Resultados por bloque
|
||||||
el.style.border = '3px solid white'; // Borde
|
- Diagnóstico global
|
||||||
```
|
|
||||||
|
## 🛠️ Tecnologías utilizadas
|
||||||
|
|
||||||
|
- Vue 3 + Composition API
|
||||||
|
- Nuxt 3
|
||||||
|
- TailwindCSS
|
||||||
|
- pdfMake
|
||||||
|
- localStorage
|
||||||
|
- Renderizado dinámico basado en configuración
|
||||||
Reference in New Issue
Block a user