datos universidades y sidebar con datos
This commit is contained in:
447
components/mapComp copy.vue
Normal file
447
components/mapComp copy.vue
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
<template>
|
||||||
|
<section class="relative">
|
||||||
|
<!-- Left Sidebar -->
|
||||||
|
<aside
|
||||||
|
v-if="showSidebar"
|
||||||
|
class="fixed left-0 top-0 w-80 h-screen bg-gradient-to-br from-purple-900 via-purple-950 to-indigo-950 text-white overflow-y-auto z-50 shadow-2xl sidebar-custom"
|
||||||
|
>
|
||||||
|
<div class="p-5 border-b border-white/10">
|
||||||
|
<img src="/LOGOBraviooB.png" alt="logo-bravio" class="h-10 md:h-14 object-cover" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-5">
|
||||||
|
<div class="flex justify-between items-center mb-3">
|
||||||
|
<h2 class="text-lg font-semibold">
|
||||||
|
{{ langcode === 'pt' ? 'Explorar instituições' : 'Explorar instituciones' }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-sm opacity-80 mb-5 leading-relaxed">
|
||||||
|
{{ langcode === 'pt'
|
||||||
|
? 'Busque por universidade, país e estado da Defensoria.'
|
||||||
|
: 'Busca por universidad, país y estado de Defensoría.' }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Search -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm mb-2 font-medium">
|
||||||
|
{{ langcode === 'pt' ? 'Buscar Universidade' : 'Buscar Universidad' }}
|
||||||
|
</label>
|
||||||
|
<div class="relative">
|
||||||
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
type="text"
|
||||||
|
:placeholder="langcode === 'pt' ? 'Buscar...' : 'Buscar...'"
|
||||||
|
class="w-full px-3 py-2.5 pr-10 bg-white/10 border border-white/20 rounded-md text-white text-sm placeholder-white/50 focus:outline-none focus:bg-white/15 focus:border-white/40 transition-all"
|
||||||
|
/>
|
||||||
|
<span class="absolute right-3 top-1/2 -translate-y-1/2 opacity-60">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search-icon lucide-search"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Country -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm mb-2 font-medium">
|
||||||
|
{{ langcode === 'pt' ? 'País' : 'País' }}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
v-model="selectedCountry"
|
||||||
|
class="w-full px-3 py-2.5 bg-white/10 border border-white/20 rounded-md text-white text-sm appearance-none cursor-pointer focus:outline-none focus:bg-white/15 focus:border-white/40 transition-all"
|
||||||
|
>
|
||||||
|
<option value="">{{ langcode === 'pt' ? 'Selecionar' : 'Seleccionar' }}</option>
|
||||||
|
<option v-for="c in countries" :key="c.value" :value="c.value">
|
||||||
|
{{ c[langcode] }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Status -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm mb-2 font-medium">
|
||||||
|
{{ langcode === 'pt' ? 'Estado da Defensoria' : 'Estado Defensoría' }}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
v-model="selectedStatus"
|
||||||
|
class="w-full px-3 py-2.5 bg-white/10 border border-white/20 rounded-md text-white text-sm appearance-none cursor-pointer focus:outline-none focus:bg-white/15 focus:border-white/40 transition-all"
|
||||||
|
>
|
||||||
|
<option value="">{{ langcode === 'pt' ? 'Selecionar' : 'Seleccionar' }}</option>
|
||||||
|
<option value="activa">{{ langcode === 'pt' ? 'Ativa' : 'Activa' }}</option>
|
||||||
|
<option value="en-desarrollo">{{ langcode === 'pt' ? 'Em desenvolvimento' : 'En desarrollo' }}</option>
|
||||||
|
<option value="en-estudio">{{ langcode === 'pt' ? 'Em estudo' : 'En estudio' }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Clear -->
|
||||||
|
<div class="w-full flex">
|
||||||
|
<button
|
||||||
|
class="w-fit p-2.5 ml-auto bg-transparent border border-white/30 text-white/90 rounded-md cursor-pointer text-xs"
|
||||||
|
@click="clearFilters"
|
||||||
|
>
|
||||||
|
{{ langcode === 'pt' ? 'LIMPAR' : 'LIMPIAR' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Counts -->
|
||||||
|
<div class="my-5 py-4 border-t border-b border-white/10">
|
||||||
|
<p class="text-sm mb-3">
|
||||||
|
{{ langcode === 'pt' ? 'Mostrando' : 'Mostrando' }}
|
||||||
|
{{ filteredResults.length }}
|
||||||
|
{{ langcode === 'pt' ? 'de' : 'de' }}
|
||||||
|
{{ universities.length }}
|
||||||
|
{{ langcode === 'pt' ? 'universidades' : 'universidades' }}
|
||||||
|
</p>
|
||||||
|
<div class="flex gap-2.5 text-surface">
|
||||||
|
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-semibold bg-white/90">
|
||||||
|
<span class="w-3.5 h-3.5 rounded-full border-2 border-white bg-cyan-400"></span>
|
||||||
|
{{ activaCount }}
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-semibold bg-white/90">
|
||||||
|
<span class="w-3.5 h-3.5 rounded-full border-2 border-white bg-orange-400"></span>
|
||||||
|
{{ desarrolloCount }}
|
||||||
|
</span>
|
||||||
|
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-semibold bg-white/90">
|
||||||
|
<span class="w-3.5 h-3.5 rounded-full border-2 border-white bg-rose-400"></span>
|
||||||
|
{{ estudioCount }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Download -->
|
||||||
|
<button
|
||||||
|
class="w-full py-2.5 bg-transparent text-white/90 cursor-pointer text-xs mb-3 hover:underline flex items-end justify-end gap-2.5"
|
||||||
|
@click="downloadCSV"
|
||||||
|
>
|
||||||
|
{{ langcode === 'pt' ? 'Baixar CSV' : 'Descargar CSV' }}
|
||||||
|
<span><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download-icon lucide-download"><path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/></svg></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- University List -->
|
||||||
|
<div class="flex flex-col gap-2.5">
|
||||||
|
<div
|
||||||
|
v-for="u in filteredResults"
|
||||||
|
:key="u.id"
|
||||||
|
class="university-item bg-white/90 text-bg p-4 rounded-lg cursor-pointer transition-all border-2 border-transparent hover:bg-white/70"
|
||||||
|
:class="{ 'border-white/30 bg-white/15': selectedUniversity?.id === u.id }"
|
||||||
|
@click="selectUniversity(u)"
|
||||||
|
>
|
||||||
|
<h3 class="text-base font-semibold mb-1">{{ u.university[langcode] }}</h3>
|
||||||
|
<p class="text-xs opacity-80 mb-2">{{ u.city[langcode] }}, {{ u.country[langcode] }}</p>
|
||||||
|
<span class="inline-flex items-center gap-1.5 text-xs font-medium">
|
||||||
|
<span
|
||||||
|
class="w-3.5 h-3.5 rounded-full border-2 border-white inline-block"
|
||||||
|
:class="{
|
||||||
|
'bg-cyan-400': u.status === 'activa',
|
||||||
|
'bg-orange-400': u.status === 'en-desarrollo',
|
||||||
|
'bg-rose-400': u.status === 'en-estudio'
|
||||||
|
}"
|
||||||
|
></span>
|
||||||
|
{{ getStatusLabel(u.status) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<!-- Botón de colapsar / expandir -->
|
||||||
|
<button
|
||||||
|
class="aside-colap-btn fixed top-5 z-50 bg-white hover:bg-white/80 hover:cursor-pointer text-surface w-8 h-8 rounded-l-none rounded-r-md flex items-center justify-center shadow-lg transition-all"
|
||||||
|
:class="[
|
||||||
|
showSidebar
|
||||||
|
? 'left-80'
|
||||||
|
: 'left-0'
|
||||||
|
]"
|
||||||
|
@click="showSidebar = !showSidebar"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
v-if="showSidebar"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m15 18-6-6 6-6" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
v-else
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path d="m9 18 6-6-6-6" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Contenedor del mapa -->
|
||||||
|
<div id="mapContainer" class="map-container relative" style="width:100%;height:100vh;">
|
||||||
|
<!-- *** Overlay de marcadores gestionados por Vue (está dentro del mapContainer) *** -->
|
||||||
|
<div id="mapMarkers" class="absolute inset-0 pointer-events-none z-40">
|
||||||
|
<div
|
||||||
|
v-for="u in filteredResults"
|
||||||
|
:key="u.id"
|
||||||
|
class="marker pointer-events-auto"
|
||||||
|
:style="getMarkerStyle(u)"
|
||||||
|
@click="selectUniversity(u)"
|
||||||
|
>
|
||||||
|
<!-- elemento visual del punto — sin transform en hover -->
|
||||||
|
<div
|
||||||
|
class="marker-dot w-5 h-5 rounded-full border-[3px] border-white shadow-md"
|
||||||
|
:style="{ backgroundColor: getMarkerColor(u.status) }"
|
||||||
|
title="Click para ir"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- El mapa se inicializa en este div -->
|
||||||
|
<!-- Nota: el overlay está dentro, así las coordenadas proyectadas encajan exactamente -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Leyenda de estados + selector de idioma -->
|
||||||
|
<div class="fixed bottom-5 right-5 text-sm text-bg z-[1000] min-w-44">
|
||||||
|
<div class="flex flex-col justify-between items-start gap-2 w-full">
|
||||||
|
<!-- Selector de idioma -->
|
||||||
|
<div class="w-full">
|
||||||
|
<select
|
||||||
|
v-model="selectedLanguage"
|
||||||
|
class="px-2 py-1 rounded-md border border-gray-300 bg-white/90 text-xs focus:outline-none focus:ring-2 focus:ring-indigo-500 w-full"
|
||||||
|
@change="changeLanguage(selectedLanguage)"
|
||||||
|
>
|
||||||
|
<option value="es">Español</option>
|
||||||
|
<option value="pt">Português</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Columna de estados -->
|
||||||
|
<div class="bg-white/90 p-4 rounded-lg text-xs w-full">
|
||||||
|
<h3 class="font-semibold mb-1">
|
||||||
|
{{ langcode === 'pt' ? 'Estado' : 'Estado' }}
|
||||||
|
</h3>
|
||||||
|
<ul class="space-y-1">
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="w-3.5 h-3.5 rounded-full border-2 border-white bg-cyan-400"></span>
|
||||||
|
<span>{{ langcode === 'pt' ? 'Ativa' : 'Activa' }}</span>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="w-3.5 h-3.5 rounded-full border-2 border-white bg-orange-400"></span>
|
||||||
|
<span>{{ langcode === 'pt' ? 'Em desenvolvimento' : 'En desarrollo' }}</span>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-2">
|
||||||
|
<span class="w-3.5 h-3.5 rounded-full border-2 border-white bg-rose-400"></span>
|
||||||
|
<span>{{ langcode === 'pt' ? 'Sem defensoria' : 'Sin defensoría' }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mapboxgl from 'mapbox-gl'
|
||||||
|
import { mapGetters, mapActions } from 'vuex'
|
||||||
|
import universitiesData from '@/data/universities.json'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
accessToken: 'pk.eyJ1IjoibWFyaWFzYXNvIiwiYSI6ImNsYThnemI4bjAzYzEzdm52cG1jZnptbXQifQ.CK4LGjX7ZFCVr-unLdzUSQ',
|
||||||
|
map: null,
|
||||||
|
universities: universitiesData,
|
||||||
|
searchQuery: '',
|
||||||
|
selectedCountry: '',
|
||||||
|
selectedStatus: '',
|
||||||
|
selectedLanguage: 'es',
|
||||||
|
selectedUniversity: null,
|
||||||
|
showSidebar: true,
|
||||||
|
countries: [
|
||||||
|
{ value: 'honduras', es: 'Honduras', pt: 'Honduras' },
|
||||||
|
{ value: 'bolivia', es: 'Bolivia', pt: 'Bolívia' },
|
||||||
|
{ value: 'argentina', es: 'Argentina', pt: 'Argentina' },
|
||||||
|
{ value: 'chile', es: 'Chile', pt: 'Chile' },
|
||||||
|
{ value: 'resto', es: 'Resto de países - Latinoamérica', pt: 'Resto de países - Latinoamérica' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['langcode']),
|
||||||
|
filteredResults() {
|
||||||
|
return this.universities.filter(u => {
|
||||||
|
const matchSearch =
|
||||||
|
!this.searchQuery ||
|
||||||
|
u.university[this.langcode].toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
||||||
|
u.city[this.langcode].toLowerCase().includes(this.searchQuery.toLowerCase())
|
||||||
|
|
||||||
|
// País
|
||||||
|
let matchCountry = true
|
||||||
|
if (this.selectedCountry) {
|
||||||
|
const countryLower = u.country[this.langcode].toLowerCase()
|
||||||
|
if (this.selectedCountry === 'resto') {
|
||||||
|
// Si selecciona "resto", solo mostramos los países que NO son estos cuatro
|
||||||
|
const principales = ['honduras', 'bolivia', 'argentina', 'chile']
|
||||||
|
matchCountry = !principales.includes(countryLower)
|
||||||
|
} else {
|
||||||
|
matchCountry = countryLower === this.selectedCountry.toLowerCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const matchStatus = !this.selectedStatus || u.status === this.selectedStatus
|
||||||
|
|
||||||
|
return matchSearch && matchCountry && matchStatus
|
||||||
|
})
|
||||||
|
},
|
||||||
|
activaCount() { return this.universities.filter(u => u.status === 'activa').length },
|
||||||
|
desarrolloCount() { return this.universities.filter(u => u.status === 'en-desarrollo').length },
|
||||||
|
estudioCount() { return this.universities.filter(u => u.status === 'en-estudio').length }
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
// cuando cambian resultados, forzamos re-render para reposicionar overlays
|
||||||
|
filteredResults() {
|
||||||
|
// forzamos calculo de estilos (re-render)
|
||||||
|
this.$nextTick(() => this.$forceUpdate())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.createMap()
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
...mapActions(['setLangcode']),
|
||||||
|
createMap() {
|
||||||
|
mapboxgl.accessToken = this.accessToken
|
||||||
|
this.map = new mapboxgl.Map({
|
||||||
|
container: 'mapContainer',
|
||||||
|
style: 'mapbox://styles/mariasaso/cme8hxq2w00cb01sb3jd105ue',
|
||||||
|
center: [-60, -15],
|
||||||
|
zoom: 2.5
|
||||||
|
})
|
||||||
|
|
||||||
|
// controles Mapbox
|
||||||
|
this.map.addControl(new mapboxgl.NavigationControl(), 'top-right')
|
||||||
|
this.map.addControl(new mapboxgl.FullscreenControl(), 'top-right')
|
||||||
|
|
||||||
|
// Recalcula las posiciones de los overlays cuando el mapa se mueve/zoom/resiza
|
||||||
|
this.map.on('move', () => this.$forceUpdate())
|
||||||
|
this.map.on('zoom', () => this.$forceUpdate())
|
||||||
|
this.map.on('resize', () => this.$forceUpdate())
|
||||||
|
|
||||||
|
// al cargar, forzamos render
|
||||||
|
this.map.on('load', () => this.$forceUpdate())
|
||||||
|
},
|
||||||
|
|
||||||
|
getMarkerColor(status) {
|
||||||
|
return {
|
||||||
|
'activa': '#22c5c2',
|
||||||
|
'en-desarrollo': '#ffa500',
|
||||||
|
'en-estudio': '#ff4560'
|
||||||
|
}[status] || '#999'
|
||||||
|
},
|
||||||
|
|
||||||
|
getMarkerStyle(u) {
|
||||||
|
// Devuelve left/top en px relativos al contenedor del mapa (map.project funciona si map existe)
|
||||||
|
if (!this.map) return { left: '0px', top: '0px', transform: 'translate(-50%, -50%)' }
|
||||||
|
|
||||||
|
// u.coordinates está en formato [lng, lat]
|
||||||
|
const p = this.map.project(u.coordinates) // { x, y }
|
||||||
|
return {
|
||||||
|
left: `${Math.round(p.x)}px`,
|
||||||
|
top: `${Math.round(p.y)}px`,
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
position: 'absolute'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
selectUniversity(u) {
|
||||||
|
this.selectedUniversity = u
|
||||||
|
// Solo flyTo/zoom: sin popups ni cambios visuales de marcador
|
||||||
|
if (this.map) {
|
||||||
|
this.map.flyTo({ center: u.coordinates, zoom: 12, duration: 1200 })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clearFilters() {
|
||||||
|
this.searchQuery = ''
|
||||||
|
this.selectedCountry = ''
|
||||||
|
this.selectedStatus = ''
|
||||||
|
},
|
||||||
|
|
||||||
|
getStatusLabel(status) {
|
||||||
|
const labels = {
|
||||||
|
'activa': this.langcode === 'pt' ? 'Ativa' : 'Activa',
|
||||||
|
'en-desarrollo': this.langcode === 'pt' ? 'Em desenvolvimento' : 'En desarrollo',
|
||||||
|
'en-estudio': this.langcode === 'pt' ? 'Em estudo' : 'En estudio'
|
||||||
|
}
|
||||||
|
return labels[status] || status
|
||||||
|
},
|
||||||
|
|
||||||
|
downloadCSV() {
|
||||||
|
const headers = ['Universidad', 'Web', 'Defensor', 'Contacto', 'Ciudad', 'País', 'Estado']
|
||||||
|
const rows = this.filteredResults.map(u => [u.university[this.langcode], u.web, u.defensor[this.langcode], u.contact, u.city[this.langcode], u.country[this.langcode], u.status])
|
||||||
|
const csv = headers.join(',') + '\n' + rows.map(r => r.join(',')).join('\n')
|
||||||
|
const blob = new Blob([csv], { type: 'text/csv' })
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = 'universidades.csv'
|
||||||
|
a.click()
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
},
|
||||||
|
|
||||||
|
changeLanguage(lang) {
|
||||||
|
this.setLangcode(lang)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* Transición suave para el sidebar al mostrarse/ocultarse */
|
||||||
|
.sidebar-custom, .aside-colap-btn {
|
||||||
|
transition: transform 0.4s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-custom[style*="display: none"] {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Aseguramos que el overlay y el mapa estén alineados exactamente */
|
||||||
|
.map-container { position: relative; }
|
||||||
|
|
||||||
|
/* Contenedor absoluto que centra cada marker por su propio translate(-50%, -50%) */
|
||||||
|
.marker {
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: center center;
|
||||||
|
/* translate aplicado desde getMarkerStyle (inline style) */
|
||||||
|
/* pointer-events-auto para permitir clicks */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Punto visual sin transformaciones en hover, para que no cambie su layout */
|
||||||
|
.marker-dot {
|
||||||
|
width: 20px; height: 20px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
border: 3px solid white;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Opcional: cursor pointer */
|
||||||
|
.marker { cursor: pointer; }
|
||||||
|
|
||||||
|
/* Scrollbar y controles (mantener tus estilos previos) */
|
||||||
|
.sidebar-custom::-webkit-scrollbar { width: 6px; }
|
||||||
|
.sidebar-custom::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.3); border-radius: 3px; }
|
||||||
|
.mapboxgl-ctrl-group { background: white !important; box-shadow: 0 0 0 2px rgba(0,0,0,.1) !important; }
|
||||||
|
</style>
|
||||||
@@ -125,8 +125,8 @@
|
|||||||
:class="{ 'border-white/30 bg-white/15': selectedUniversity?.id === u.id }"
|
:class="{ 'border-white/30 bg-white/15': selectedUniversity?.id === u.id }"
|
||||||
@click="selectUniversity(u)"
|
@click="selectUniversity(u)"
|
||||||
>
|
>
|
||||||
<h3 class="text-base font-semibold mb-1">{{ u.name }}</h3>
|
<h3 class="text-base font-semibold mb-1">{{ u.university[langcode] }}</h3>
|
||||||
<p class="text-xs opacity-80 mb-2">{{ u.city }}, {{ u.country }}</p>
|
<p class="text-xs opacity-80 mb-2">{{ u.city[langcode] }}, {{ u.country[langcode] }}</p>
|
||||||
<span class="inline-flex items-center gap-1.5 text-xs font-medium">
|
<span class="inline-flex items-center gap-1.5 text-xs font-medium">
|
||||||
<span
|
<span
|
||||||
class="w-3.5 h-3.5 rounded-full border-2 border-white inline-block"
|
class="w-3.5 h-3.5 rounded-full border-2 border-white inline-block"
|
||||||
@@ -244,6 +244,119 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Sidebar - University Details -->
|
||||||
|
<aside
|
||||||
|
v-if="selectedUniversity && showRightSidebar"
|
||||||
|
class="fixed right-0 top-0 w-80 h-screen bg-surface text-white overflow-y-auto z-50 shadow-2xl sidebar-custom"
|
||||||
|
>
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="p-5 border-b border-white/10 flex justify-between items-start bg-bg">
|
||||||
|
<div class="flex-1">
|
||||||
|
<h2 class="text-xl font-bold mb-2">{{ selectedUniversity.university[langcode] }}</h2>
|
||||||
|
<p class="text-xs opacity-80">{{ selectedUniversity.city[langcode] }}, {{ selectedUniversity.country[langcode] }}</p>
|
||||||
|
<div class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs bg-white/90 text-surface mt-4">
|
||||||
|
<span
|
||||||
|
class="w-3.5 h-3.5 rounded-full border-2 border-white inline-block"
|
||||||
|
:class="{
|
||||||
|
'bg-cyan-400': selectedUniversity.status === 'activa',
|
||||||
|
'bg-orange-400': selectedUniversity.status === 'en-desarrollo',
|
||||||
|
'bg-rose-400': selectedUniversity.status === 'en-estudio'
|
||||||
|
}"
|
||||||
|
></span>
|
||||||
|
{{ getStatusLabel(selectedUniversity.status) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="bg-white/90 hover:bg-surface-light text-surface transition-colors rounded-sm"
|
||||||
|
@click="closeRightSidebar"
|
||||||
|
>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M18 6 6 18"/><path d="m6 6 12 12"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Information Section -->
|
||||||
|
<div class="p-5">
|
||||||
|
<h3 class="text-base mb-4">
|
||||||
|
{{ langcode === 'pt' ? 'Informação' : 'Información' }}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div class="space-y-3 text-sm">
|
||||||
|
<!-- Estado -->
|
||||||
|
<div>
|
||||||
|
<span class="font-semibold">{{ langcode === 'pt' ? 'Estado:' : 'Estado:' }}</span>
|
||||||
|
<span class="ml-2 text-muted">{{ getStatusLabel(selectedUniversity.status) }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Web -->
|
||||||
|
<div v-if="selectedUniversity.web">
|
||||||
|
<span class="font-semibold">Web:</span>
|
||||||
|
<a
|
||||||
|
:href="selectedUniversity.web"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="ml-2 text-cyan-300 hover:text-cyan-400 inline-flex items-center gap-1 cursor-pointer"
|
||||||
|
>
|
||||||
|
{{ selectedUniversity.web }}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" x2="21" y1="14" y2="3"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Reglamento -->
|
||||||
|
<div v-if="selectedUniversity.reglamento">
|
||||||
|
<span class="text-white/70">{{ langcode === 'pt' ? 'Regulamento:' : 'Reglamento:' }}</span>
|
||||||
|
<a
|
||||||
|
:href="selectedUniversity.reglamento"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="ml-2 text-cyan-300 hover:text-cyan-200 inline-flex items-center gap-1"
|
||||||
|
>
|
||||||
|
{{ langcode === 'pt' ? 'Ver regulamento' : 'Ver reglamento' }}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Contacto -->
|
||||||
|
<div v-if="selectedUniversity.contacto">
|
||||||
|
<span class="text-white/70">{{ langcode === 'pt' ? 'Contato:' : 'Contacto:' }}</span>
|
||||||
|
<a
|
||||||
|
:href="`mailto:${selectedUniversity.contacto}`"
|
||||||
|
class="ml-2 text-cyan-300 hover:text-cyan-200"
|
||||||
|
>
|
||||||
|
{{ selectedUniversity.contacto }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Última actualización -->
|
||||||
|
<div v-if="selectedUniversity.ultimaActualizacion">
|
||||||
|
<span class="text-white/70">{{ langcode === 'pt' ? 'Última atualização:' : 'Última actualización:' }}</span>
|
||||||
|
<span class="ml-2">{{ selectedUniversity.ultimaActualizacion }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Share Button -->
|
||||||
|
<div class="px-5 pb-5 border-t border-white/10 pt-5">
|
||||||
|
<button
|
||||||
|
class="w-full px-4 py-2.5 bg-transparent border border-white/30 rounded-lg text-sm font-medium hover:bg-white/10 transition-colors flex items-center justify-center gap-2"
|
||||||
|
@click="shareUniversity"
|
||||||
|
>
|
||||||
|
{{ langcode === 'pt' ? 'COMPARTILHAR LINK' : 'COMPARTIR ENLACE' }}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -264,6 +377,7 @@ export default {
|
|||||||
selectedLanguage: 'es',
|
selectedLanguage: 'es',
|
||||||
selectedUniversity: null,
|
selectedUniversity: null,
|
||||||
showSidebar: true,
|
showSidebar: true,
|
||||||
|
showRightSidebar: true,
|
||||||
countries: [
|
countries: [
|
||||||
{ value: 'honduras', es: 'Honduras', pt: 'Honduras' },
|
{ value: 'honduras', es: 'Honduras', pt: 'Honduras' },
|
||||||
{ value: 'bolivia', es: 'Bolivia', pt: 'Bolívia' },
|
{ value: 'bolivia', es: 'Bolivia', pt: 'Bolívia' },
|
||||||
@@ -280,13 +394,13 @@ export default {
|
|||||||
return this.universities.filter(u => {
|
return this.universities.filter(u => {
|
||||||
const matchSearch =
|
const matchSearch =
|
||||||
!this.searchQuery ||
|
!this.searchQuery ||
|
||||||
u.name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
u.university[this.langcode].toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
||||||
u.city.toLowerCase().includes(this.searchQuery.toLowerCase())
|
u.city[this.langcode].toLowerCase().includes(this.searchQuery.toLowerCase())
|
||||||
|
|
||||||
// País
|
// País
|
||||||
let matchCountry = true
|
let matchCountry = true
|
||||||
if (this.selectedCountry) {
|
if (this.selectedCountry) {
|
||||||
const countryLower = u.country.toLowerCase()
|
const countryLower = u.country[this.langcode].toLowerCase()
|
||||||
if (this.selectedCountry === 'resto') {
|
if (this.selectedCountry === 'resto') {
|
||||||
// Si selecciona "resto", solo mostramos los países que NO son estos cuatro
|
// Si selecciona "resto", solo mostramos los países que NO son estos cuatro
|
||||||
const principales = ['honduras', 'bolivia', 'argentina', 'chile']
|
const principales = ['honduras', 'bolivia', 'argentina', 'chile']
|
||||||
@@ -371,6 +485,7 @@ export default {
|
|||||||
if (this.map) {
|
if (this.map) {
|
||||||
this.map.flyTo({ center: u.coordinates, zoom: 12, duration: 1200 })
|
this.map.flyTo({ center: u.coordinates, zoom: 12, duration: 1200 })
|
||||||
}
|
}
|
||||||
|
this.showRightSidebar = true
|
||||||
},
|
},
|
||||||
|
|
||||||
clearFilters() {
|
clearFilters() {
|
||||||
@@ -379,6 +494,11 @@ export default {
|
|||||||
this.selectedStatus = ''
|
this.selectedStatus = ''
|
||||||
},
|
},
|
||||||
|
|
||||||
|
closeRightSidebar() {
|
||||||
|
this.showRightSidebar = false
|
||||||
|
this.selectedUniversity = null
|
||||||
|
},
|
||||||
|
|
||||||
getStatusLabel(status) {
|
getStatusLabel(status) {
|
||||||
const labels = {
|
const labels = {
|
||||||
'activa': this.langcode === 'pt' ? 'Ativa' : 'Activa',
|
'activa': this.langcode === 'pt' ? 'Ativa' : 'Activa',
|
||||||
@@ -389,8 +509,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
downloadCSV() {
|
downloadCSV() {
|
||||||
const headers = ['ID', 'Universidad', 'Ciudad', 'País', 'Estado']
|
const headers = ['Universidad', 'Web', 'Defensor', 'Contacto', 'Ciudad', 'País', 'Estado']
|
||||||
const rows = this.filteredResults.map(u => [u.id, u.name, u.city, u.country, u.status])
|
const rows = this.filteredResults.map(u => [u.university[this.langcode], u.web, u.defensor[this.langcode], u.contact, u.city[this.langcode], u.country[this.langcode], u.status])
|
||||||
const csv = headers.join(',') + '\n' + rows.map(r => r.join(',')).join('\n')
|
const csv = headers.join(',') + '\n' + rows.map(r => r.join(',')).join('\n')
|
||||||
const blob = new Blob([csv], { type: 'text/csv' })
|
const blob = new Blob([csv], { type: 'text/csv' })
|
||||||
const url = URL.createObjectURL(blob)
|
const url = URL.createObjectURL(blob)
|
||||||
|
|||||||
@@ -1,46 +1,241 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "Universidad Carlos III",
|
"university": {
|
||||||
"city": "Buenos Aires",
|
"es": "Universidad Carlos III De Madrid",
|
||||||
"country": "Argentina",
|
"pt": "Universidade Carlos III De Madrid"
|
||||||
|
},
|
||||||
|
"web": "www.uc3m.es",
|
||||||
"status": "activa",
|
"status": "activa",
|
||||||
"coordinates": [
|
"defensor": {
|
||||||
-58.3816,
|
"es": "",
|
||||||
-34.6037
|
"pt": ""
|
||||||
]
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Madrid",
|
||||||
|
"pt": "Madri"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "España",
|
||||||
|
"es": "España",
|
||||||
|
"pt": "Espanha"
|
||||||
|
},
|
||||||
|
"coordinates": [-3.725597993169734, 40.3176755755589]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"name": "Universidad de Chile",
|
"university": {
|
||||||
"city": "Santiago",
|
"es": "Universidad Pedagógica Nacional Francisco Morazán",
|
||||||
"country": "Chile",
|
"pt": "Universidade Pedagógica Nacional Francisco Morazán"
|
||||||
|
},
|
||||||
|
"web": "www.upnfm.edu.hn",
|
||||||
"status": "en-desarrollo",
|
"status": "en-desarrollo",
|
||||||
"coordinates": [
|
"defensor": {
|
||||||
-70.6693,
|
"es": "",
|
||||||
-33.4489
|
"pt": ""
|
||||||
]
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Tegucigalpa",
|
||||||
|
"pt": "Tegucigalpa"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Honduras",
|
||||||
|
"es": "Honduras",
|
||||||
|
"pt": "Honduras"
|
||||||
|
},
|
||||||
|
"coordinates": [-87.18740272077417, 14.075717287034017]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "Universidad Nacional de Colombia",
|
"university": {
|
||||||
"city": "Bogotá",
|
"es": "Universidade Da Beira Interior",
|
||||||
"country": "Colombia",
|
"pt": "Universidade Da Beira Interior"
|
||||||
"status": "en-estudio",
|
},
|
||||||
"coordinates": [
|
"web": "www.ubi.pt",
|
||||||
-74.0721,
|
"status": "activa",
|
||||||
4.6097
|
"defensor": {
|
||||||
]
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Covilhã",
|
||||||
|
"pt": "Covilhã"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"es": "Portugal",
|
||||||
|
"pt": "Portugal"
|
||||||
|
},
|
||||||
|
"coordinates": [-7.508451922517487, 40.27799405606521]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"name": "Universidad Nacional Autónoma de México",
|
"university": {
|
||||||
"city": "Ciudad de México",
|
"es": "Universidad Nacional De Córdoba",
|
||||||
"country": "México",
|
"pt": "Universidade Nacional De Córdoba"
|
||||||
|
},
|
||||||
|
"web": "www.unc.edu.ar",
|
||||||
"status": "activa",
|
"status": "activa",
|
||||||
"coordinates": [
|
"defensor": {
|
||||||
-99.1332,
|
"es": "",
|
||||||
19.4326
|
"pt": ""
|
||||||
]
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Córdoba",
|
||||||
|
"pt": "Córdoba"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Argentina",
|
||||||
|
"es": "Argentina",
|
||||||
|
"pt": "Argentina"
|
||||||
|
},
|
||||||
|
"coordinates": [-64.184932209089, -31.435327153796624]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"university": {
|
||||||
|
"es": "Universidad Nacional Del Nordeste",
|
||||||
|
"pt": "Universidade Nacional Do Nordeste"
|
||||||
|
},
|
||||||
|
"web": "www.unne.edu.ar",
|
||||||
|
"status": "en-estudio",
|
||||||
|
"defensor": {
|
||||||
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Corrientes",
|
||||||
|
"pt": "Corrientes"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Argentina",
|
||||||
|
"es": "Argentina",
|
||||||
|
"pt": "Argentina"
|
||||||
|
},
|
||||||
|
"coordinates": [-58.741910473784884, -27.458327515738873]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"university": {
|
||||||
|
"es": "Universidad Tecnológica Privada De Santa Cruz",
|
||||||
|
"pt": "Universidade Tecnológica Privada De Santa Cruz"
|
||||||
|
},
|
||||||
|
"web": "www.utepsa.edu",
|
||||||
|
"status": "en-desarrollo",
|
||||||
|
"defensor": {
|
||||||
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Santa Cruz de la Sierra",
|
||||||
|
"pt": "Santa Cruz de la Serra"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Bolivia",
|
||||||
|
"es": "Bolivia",
|
||||||
|
"pt": "Bolívia"
|
||||||
|
},
|
||||||
|
"coordinates": [-63.20079139360426, -17.767319358283732]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"university": {
|
||||||
|
"es": "Universidad Privada Del Valle",
|
||||||
|
"pt": "Universidade Privada Do Vale"
|
||||||
|
},
|
||||||
|
"web": "www.univalle.edu",
|
||||||
|
"status": "en-desarrollo",
|
||||||
|
"defensor": {
|
||||||
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Santa Cruz de la Sierra",
|
||||||
|
"pt": "Santa Cruz de la Serra"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Bolivia",
|
||||||
|
"es": "Bolivia",
|
||||||
|
"pt": "Bolívia"
|
||||||
|
},
|
||||||
|
"coordinates": [-62.96585176506137, -16.80943599512555]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"university": {
|
||||||
|
"es": "Universidad Adolfo Ibáñez",
|
||||||
|
"pt": "Universidade Adolfo Ibáñez"
|
||||||
|
},
|
||||||
|
"web": "www.uai.cl",
|
||||||
|
"status": "activa",
|
||||||
|
"defensor": {
|
||||||
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Santiago",
|
||||||
|
"pt": "Santiago"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Chile",
|
||||||
|
"es": "Chile",
|
||||||
|
"pt": "Chile"
|
||||||
|
},
|
||||||
|
"coordinates": [-70.45588799584354, -33.440714804658725]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 9,
|
||||||
|
"university": {
|
||||||
|
"es": "Universidad De La Frontera",
|
||||||
|
"pt": "Universidade Da Fronteira"
|
||||||
|
},
|
||||||
|
"web": "www.ufro.cl",
|
||||||
|
"status": "en-estudio",
|
||||||
|
"defensor": {
|
||||||
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Temuco",
|
||||||
|
"pt": "Temuco"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Chile",
|
||||||
|
"es": "Chile",
|
||||||
|
"pt": "Chile"
|
||||||
|
},
|
||||||
|
"coordinates": [-72.11255058627309, -38.641845610984866]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 10,
|
||||||
|
"university": {
|
||||||
|
"es": "Universidad Nacional Autónoma De Honduras",
|
||||||
|
"pt": "Universidade Nacional Autônoma De Honduras"
|
||||||
|
},
|
||||||
|
"web": "www.unah.edu.hn",
|
||||||
|
"status": "activa",
|
||||||
|
"defensor": {
|
||||||
|
"es": "",
|
||||||
|
"pt": ""
|
||||||
|
},
|
||||||
|
"contact": "",
|
||||||
|
"city": {
|
||||||
|
"es": "Tegucigalpa",
|
||||||
|
"pt": "Tegucigalpa"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"value": "Honduras",
|
||||||
|
"es": "Honduras",
|
||||||
|
"pt": "Honduras"
|
||||||
|
},
|
||||||
|
"coordinates": [-87.1373663874526, 14.358837369169507]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Reference in New Issue
Block a user