Skip to content

Commit

Permalink
Merge pull request #44 from enflujo/buscador
Browse files Browse the repository at this point in the history
✨ Implementación del buscador, falta enlaces y diseño #38
  • Loading branch information
1cgonza authored Feb 19, 2024
2 parents 11ddb20 + d0c9c36 commit 2374db5
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 24 deletions.
1 change: 1 addition & 0 deletions estaticos/datosBuscador.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@astrojs/check": "^0.5.2",
"@enflujo/alquimia": "^2.0.0",
"astro": "^4.3.5",
"fuzzysort": "^2.0.4",
"mapbox-gl": "^3.1.2",
"marked": "^12.0.0",
"nanostores": "^0.9.5",
Expand Down
7 changes: 5 additions & 2 deletions procesador/egresados.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ const camposMultiplesEgresados: CamposEgresados = [

const camposEgresados = [...camposMultiplesEgresados];

export default async function procesarEgresados(archivo: string, listasEgresados: ListasEgresados): Promise<void> {
export default async function procesarEgresados(
archivo: string,
listasEgresados: ListasEgresados
): Promise<Egresado[]> {
const egresados: Egresado[] = [];

return new Promise(async (resolver) => {
Expand Down Expand Up @@ -136,7 +139,7 @@ export default async function procesarEgresados(archivo: string, listasEgresados
console.log('fin egresados');
guardarJSON(egresados, 'egresados');
guardarJSON(listasEgresados, 'listasEgresados');
resolver();
resolver(egresados);
});
});

Expand Down
46 changes: 44 additions & 2 deletions procesador/procesador.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
LLavesMultiples,
Listas,
LllavesSingulares,
OpcionBuscadorDatos,
Proyecto
} from '../src/tipos.ts';
import { getXlsxStream } from 'xlstream';
Expand All @@ -16,7 +17,7 @@ import procesarEgresados from './egresados.js';
import { existsSync, readdirSync } from 'fs';
import { resolve } from 'path';
import { imageSize } from 'image-size';
import type { ListasEgresados } from './egresados.js';
import type { Egresado, ListasEgresados } from './egresados.js';

const datosEmpiezanEnFila = 2;
const camposSingulares: Campos = [
Expand Down Expand Up @@ -61,18 +62,59 @@ const listasEgresados: ListasEgresados = {
const archivo = './procesador/datos/Listado de proyectos - 60 años dpto antropología 1902.xlsx';

async function procesar() {
await procesarEgresados(archivo, listasEgresados);
const egresados = await procesarEgresados(archivo, listasEgresados);
await procesarProyectos();
console.log('Proyectos procesados');
await procesarLugares(archivo, listas);

console.log('fin de lugares');
await procesarLugaresEgresados(archivo, listasEgresados);

procesarDatosBuscador(egresados);
console.log('listos datos buscador');

console.log('fin');
}

procesar().catch(console.error);

function procesarDatosBuscador(egresados: Egresado[]) {
const opciones: OpcionBuscadorDatos[] = [];

proyectos.forEach((proyecto) => {
opciones.push({ nombre: proyecto.nombre.nombre, tipo: 'proyecto' });
});

egresados.forEach((egresado) => {
opciones.push({ nombre: egresado.nombre, tipo: 'egresado' });
});

for (const llaveListaP in listas) {
const lista = listas[llaveListaP as keyof Listas];
lista.forEach((elemento) => {
const elementoBuscador: OpcionBuscadorDatos = {
nombre: elemento.nombre,
tipo: llaveListaP
};
opciones.push(elementoBuscador);
});
}

for (const llaveListaE in listasEgresados) {
const lista = listasEgresados[llaveListaE as keyof ListasEgresados];
lista.forEach((elemento) => {
const elementoBuscador: OpcionBuscadorDatos = {
nombre: elemento.nombre,
tipo: llaveListaE
};

opciones.push(elementoBuscador);
});
}

guardarJSON(opciones, 'datosBuscador');
}

async function procesarProyectos(): Promise<void> {
const flujo = await getXlsxStream({
filePath: archivo,
Expand Down
128 changes: 128 additions & 0 deletions src/componentes/Buscador.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
import type { Listas } from '@/tipos';
import { nombresListasEgresados, nombresListasProyectos } from '@/utilidades/cerebro';
const listas = { ...nombresListasProyectos, ...nombresListasEgresados };
---

<div id="contenedorBuscador">
<input id="buscador" type="search" name="nombreLugar" placeholder="Buscar" list="sugerencias" />
<div id="sugerencias">
{
Object.keys(listas).map((tipo) => (
<div id={`caja-${tipo}`} class="cajaBuscador">
<h4>{listas[tipo as keyof Listas]}</h4>
<ul class="subLista" />
</div>
))
}
</div>
</div>

<script>
import fuzzysort from 'fuzzysort';
import { opcionesBuscador } from '@/utilidades/cerebro';
import type { ElementoBuscador } from '@/tipos';
const buscador = document.getElementById('buscador') as HTMLInputElement;
const sugerencias = document.getElementById('sugerencias') as HTMLDataListElement;
const cajas = sugerencias.querySelectorAll<HTMLDivElement>('.cajaBuscador');
const sinResultados = document.createElement('span');
sinResultados.className = 'sinResultados';

interface ListasBuscador {
tipo: string;
puntaje: number;
elementos: HTMLSpanElement[];
}
opcionesBuscador.subscribe((opciones) => {
if (!opciones) return;

buscador.oninput = buscar;

function buscar() {
const texto = buscador.value.trim();

// sugerencias.innerHTML = '';
sinResultados.innerText = '';
cajas.forEach((caja) => caja.classList.remove('visible'));

if (!texto || !texto.length) {
sugerencias.classList.remove('visible');
return;
}

const busqueda = fuzzysort.go<ElementoBuscador>(texto, opciones as ElementoBuscador[], {
key: 'nombre',
threshold: -1000,
limit: 100
});

if (busqueda.total > 0) {
sugerencias.classList.add('visible');

const resultadoEnListas = busqueda.reduce((listas: ListasBuscador[], actual) => {
const llave = actual.obj.tipo;
const enLista = listas.find((lista: ListasBuscador) => lista.tipo === llave);

if (!enLista) {
listas.push({ puntaje: actual.score, tipo: llave, elementos: [actual.obj.opcion] });
} else {
if (enLista.puntaje < actual.score) enLista.puntaje = actual.score;
enLista.elementos.push(actual.obj.opcion);
}

return listas;
}, []);

resultadoEnListas.forEach((obj) => {
const contenedor = document.getElementById(`caja-${obj.tipo}`) as HTMLDivElement;
const ul = contenedor.querySelector<HTMLUListElement>('.subLista') as HTMLUListElement;
sugerencias.insertBefore(contenedor, sugerencias.lastChild);
ul.innerHTML = '';
contenedor.classList.add('visible');

obj.elementos.forEach((elemento) => ul.appendChild(elemento));
});
} else {
sinResultados.innerText = `No hay resultados para la busqueda: ${texto}`;
sugerencias.appendChild(sinResultados);
}
}
});
</script>

<style lang="scss">
#contenedorBuscador {
z-index: 99;
}

#sugerencias {
background-color: var(--magenta);
position: absolute;
left: 50%;
transform: translateX(-50%);
top: var(--altoMenu);
padding: 1.2em;
width: 80vw;
display: none;
flex-wrap: wrap;
overflow: auto;
height: calc(100vh - 50px);
text-transform: none;

&.visible {
display: flex;
}

.cajaBuscador {
width: 33%;
border: 1px dotted white;
padding: 0.5em;
display: none;
flex-direction: column;

&.visible {
display: flex;
}
}
}
</style>
5 changes: 4 additions & 1 deletion src/componentes/Cabezote.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
import Buscador from './Buscador.astro';
const urlBase = import.meta.env.BASE_URL;
---

Expand All @@ -16,6 +18,8 @@ const urlBase = import.meta.env.BASE_URL;
<li class="botonVista" id="botonProyectos"><a href=`${urlBase}/`>Proyectos</a></li>
<li class="botonVista" id="botonEgresados"><a href=`${urlBase}/egresados`>Egresados</a></li>
</ul>

<Buscador />
</div>
</nav>

Expand Down Expand Up @@ -86,7 +90,6 @@ const urlBase = import.meta.env.BASE_URL;
.cajaGusanos {
// content: '';
background-image: url(/enflujo-haciendocaminos/imgs/gusanitos.svg);
position: absolute;
height: 50px;
width: 100px;
background-repeat: no-repeat;
Expand Down
9 changes: 9 additions & 0 deletions src/tipos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,12 @@ export interface ElementoListaEgresados {
relaciones: { tipo: keyof Listas | string; conteo: number; indice: number; slug: string }[];
egresados?: number[];
}

export interface OpcionBuscadorDatos {
nombre: string;
tipo: string;
}

export interface ElementoBuscador extends OpcionBuscadorDatos {
opcion: HTMLLIElement;
}
32 changes: 13 additions & 19 deletions src/utilidades/cerebro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import type {
RelacionesFicha,
ElementoFicha,
ElementoEgresado,
ElementoBuscador
ElementoBuscador,
OpcionBuscadorDatos
} from '@/tipos';
import type { FeatureCollection, Point } from 'geojson';
import type { Egresado, ListasEgresados } from '../../procesador/egresados';
Expand Down Expand Up @@ -57,27 +58,20 @@ onMount(datosListas, () => {

pedirDatos<Proyecto[]>(`${import.meta.env.BASE_URL}/proyectos.json`).then((proyectos) => {
datosProyectos.set(proyectos);
});
});
});

const opciones: ElementoBuscador[] = [];

for (const llaveLista in listas) {
const lista = listas[llaveLista as keyof Listas];
lista.forEach((elemento, i) => {
const opcion = document.createElement('option');
opcion.value = elemento.nombre;

const elementoBuscador: ElementoBuscador = {
nombre: elemento.nombre,
tipo: llaveLista,
indice: i,
opcion
};
opciones.push(elementoBuscador);
});
}
onMount(opcionesBuscador, () => {
pedirDatos<OpcionBuscadorDatos[]>(`${import.meta.env.BASE_URL}/datosBuscador.json`).then((datosBuscador) => {
const opciones: ElementoBuscador[] = datosBuscador.map((opcion) => {
const elemento = document.createElement('li');
elemento.innerText = opcion.nombre;

opcionesBuscador.set(opciones);
return { opcion: elemento, ...opcion };
});

opcionesBuscador.set(opciones);
});
});

Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,11 @@ function-bind@^1.1.2:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==

fuzzysort@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/fuzzysort/-/fuzzysort-2.0.4.tgz#a21d1ce8947eaf2797dc3b7c28c36db9d1165f84"
integrity sha512-Api1mJL+Ad7W7vnDZnWq5pGaXJjyencT+iKGia2PlHUcSsSzWwIQ3S1isiMpwpavjYtGd2FzhUIhnnhOULZgDw==

gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
Expand Down

0 comments on commit 2374db5

Please sign in to comment.