diff --git a/front/src/app/page.tsx b/front/src/app/page.tsx index fb80fb1..05e01be 100644 --- a/front/src/app/page.tsx +++ b/front/src/app/page.tsx @@ -1,8 +1,10 @@ import { EmbalseSearch } from "@/pods/embalse-search"; -import Link from "next/link"; +import { getEmbalsesCollection } from "@/pods/embalse-search/api"; -const RootPage = () => { - return ; +const RootPage = async () => { + const embalses = await getEmbalsesCollection(); + + return ; }; export default RootPage; diff --git a/front/src/pods/embalse-search/api/api.model.ts b/front/src/pods/embalse-search/api/api.model.ts index e706396..3715b4e 100644 --- a/front/src/pods/embalse-search/api/api.model.ts +++ b/front/src/pods/embalse-search/api/api.model.ts @@ -1,5 +1,5 @@ export interface Embalse { _id: string; - name: string; - province: string; + nombre: string; + provincia: string; } diff --git a/front/src/pods/embalse-search/api/embalse-search.mock.ts b/front/src/pods/embalse-search/api/embalse-search.mock.ts deleted file mode 100644 index cf888c7..0000000 --- a/front/src/pods/embalse-search/api/embalse-search.mock.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { Embalse } from "./api.model"; - -export const embalseSearchMock: Embalse[] = [ - { - _id: "alarcón", - name: "Embalse de Alarcón", - province: "Cuenca", - }, - { - _id: "la-serena", - name: "Embalse de La Serena", - province: "Badajoz", - }, - { - _id: "alcántara", - name: "Embalse de Alcántara", - province: "Cáceres", - }, - { - _id: "buendía", - name: "Embalse de Buendía", - province: "Guadalajara", - }, - { - _id: "entrepeñas", - name: "Embalse de Entrepeñas", - province: "Guadalajara", - }, - { - _id: "yesa", - name: "Embalse de Yesa", - province: "Navarra", - }, - { - _id: "mequinenza", - name: "Embalse de Mequinenza", - province: "Zaragoza", - }, - { - _id: "mediano", - name: "Embalse de Mediano", - province: "Huesca", - }, - { - _id: "el-grado", - name: "Embalse de El Grado", - province: "Huesca", - }, - { - _id: "la-tranquera", - name: "Embalse de La Tranquera", - province: "Zaragoza", - }, - { - _id: "santillana", - name: "Embalse de Santillana", - province: "Madrid", - }, - { - _id: "valmayor", - name: "Embalse de Valmayor", - province: "Madrid", - }, - { - _id: "el-atazar", - name: "Embalse de El Atazar", - province: "Madrid", - }, - { - _id: "san-juan", - name: "Embalse de San Juan", - province: "Madrid", - }, - { - _id: "navacerrada", - name: "Embalse de Navacerrada", - province: "Madrid", - }, - { - _id: "iznájar", - name: "Embalse de Iznájar", - province: "Córdoba", - }, - { - _id: "la-viñuela", - name: "Embalse de La Viñuela", - province: "Málaga", - }, - { - _id: "conde-de-guadalhorce", - name: "Embalse de Conde de Guadalhorce", - province: "Málaga", - }, - { - _id: "guadalteba", - name: "Embalse de Guadalteba", - province: "Málaga", - }, - { - _id: "la-colada", - name: "Embalse de La Colada", - province: "Córdoba", - }, - { - _id: "la-breña", - name: "Embalse de La Breña", - province: "Córdoba", - }, - { - _id: "guadalcacín", - name: "Embalse de Guadalcacín", - province: "Cádiz", - }, - { - _id: "zahara", - name: "Embalse de Zahara", - province: "Cádiz", - }, - { - _id: "bembézar", - name: "Embalse de Bembézar", - province: "Córdoba", - }, - { - _id: "negratín", - name: "Embalse de Negratín", - province: "Granada", - }, - { - _id: "canales", - name: "Embalse de Canales", - province: "Granada", - }, - { - _id: "los-bermejales", - name: "Embalse de Los Bermejales", - province: "Granada", - }, - { - _id: "cubillas", - name: "Embalse de Cubillas", - province: "Granada", - }, - { - _id: "rules", - name: "Embalse de Rules", - province: "Granada", - }, - { - _id: "el-gergal", - name: "Embalse de El Gergal", - province: "Sevilla", - }, - { - _id: "melonares", - name: "Embalse de Melonares", - province: "Sevilla", - }, - { - _id: "el-pintado", - name: "Embalse de El Pintado", - province: "Sevilla", - }, - { - _id: "la-minilla", - name: "Embalse de La Minilla", - province: "Sevilla", - }, - { - _id: "aracena", - name: "Embalse de Aracena", - province: "Huelva", - }, - { - _id: "andévalo", - name: "Embalse de Andévalo", - province: "Huelva", - }, - { - _id: "chanza", - name: "Embalse de Chanza", - province: "Huelva", - }, - { - _id: "el-encinarejo", - name: "Embalse de El Encinarejo", - province: "Jaén", - }, - { - _id: "el-rumblar", - name: "Embalse de El Rumblar", - province: "Jaén", - }, - { - _id: "el-tranco", - name: "Embalse de El Tranco", - province: "Jaén", - }, - { - _id: "giribaile", - name: "Embalse de Giribaile", - province: "Jaén", - }, - { - _id: "guadalmena", - name: "Embalse de Guadalmena", - province: "Jaén", - }, - { - _id: "la-bolera", - name: "Embalse de La Bolera", - province: "Jaén", - }, - { - _id: "tous", - name: "Embalse de Tous", - province: "Valencia", - }, - { - _id: "benagéber", - name: "Embalse de Benagéber", - province: "Valencia", - }, - { - _id: "orellana", - name: "Embalse de Orellana", - province: "Badajoz", - }, - { - _id: "cíjara", - name: "Embalse de Cíjara", - province: "Badajoz", - }, - { - _id: "zújar", - name: "Embalse de Zújar", - province: "Badajoz", - }, -]; diff --git a/front/src/pods/embalse-search/api/embalse.api.ts b/front/src/pods/embalse-search/api/embalse.api.ts index 4e3c24f..9f1cabe 100644 --- a/front/src/pods/embalse-search/api/embalse.api.ts +++ b/front/src/pods/embalse-search/api/embalse.api.ts @@ -1,6 +1,6 @@ +import { getEmbalsesFromDb } from "../embalse-search.repository"; import { Embalse } from "./api.model"; -import { embalseSearchMock } from "./embalse-search.mock"; export const getEmbalsesCollection = async (): Promise => { - return embalseSearchMock; + return getEmbalsesFromDb(); }; diff --git a/front/src/pods/embalse-search/api/index.ts b/front/src/pods/embalse-search/api/index.ts index 2431999..b512195 100644 --- a/front/src/pods/embalse-search/api/index.ts +++ b/front/src/pods/embalse-search/api/index.ts @@ -1,3 +1,2 @@ export * from "./api.model"; export * from "./embalse.api"; -export * from "./embalse-search.mock"; diff --git a/front/src/pods/embalse-search/embalse-search.mapper.ts b/front/src/pods/embalse-search/embalse-search.mapper.ts new file mode 100644 index 0000000..229d5b9 --- /dev/null +++ b/front/src/pods/embalse-search/embalse-search.mapper.ts @@ -0,0 +1,9 @@ +import * as vm from "./embalse-search.vm"; +import * as api from "db-model"; + +export const mapEmbalseToSearch = ( + embalse: api.Embalse, +): vm.EmbalseSearchModel => ({ + slug: embalse._id, + name: `${embalse.nombre} (${embalse.provincia})`, +}); diff --git a/front/src/pods/embalse-search/embalse-search.repository.ts b/front/src/pods/embalse-search/embalse-search.repository.ts new file mode 100644 index 0000000..e2d9156 --- /dev/null +++ b/front/src/pods/embalse-search/embalse-search.repository.ts @@ -0,0 +1,38 @@ +"use server"; + +import { getDb } from "@/lib/mongodb"; +import type { Embalse } from "./api/api.model"; + +export async function getEmbalsesFromDb(): Promise { + const db = await getDb(); + const docs = await db + .collection("embalses") + .find( + {}, + { + projection: { + _id: 1, + nombre: 1, + provincia: 1, + slug: 1, + }, + }, + ) + .toArray(); + + return docs.map((doc) => ({ + _id: doc.slug ?? createSlug(doc.nombre ?? ""), + nombre: doc.nombre ?? "", + provincia: doc.provincia ?? "", + })); +} + +const createSlug = (nombre: string): string => { + return nombre + .toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/ñ/g, "n") + .replace(/[^a-z0-9]+/g, "-") + .replace(/^-+|-+$/g, ""); +}; diff --git a/front/src/pods/embalse-search/embalse-search.tsx b/front/src/pods/embalse-search/embalse-search.tsx index a5717ce..3238694 100644 --- a/front/src/pods/embalse-search/embalse-search.tsx +++ b/front/src/pods/embalse-search/embalse-search.tsx @@ -1,36 +1,32 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState } from "react"; import { useCombobox } from "downshift"; import { useRouter } from "next/navigation"; import { SearchIcon } from "./components/search-icon"; -import { Embalse, getEmbalsesCollection } from "./api"; -import { EmbalseSearchModel } from "./embalse-search.model"; +import { Embalse } from "./api"; +import { EmbalseSearchModel } from "./embalse-search.vm"; +import { mapEmbalseToSearch } from "./embalse-search.mapper"; -const mapEmbalseToSearch = (embalse: Embalse): EmbalseSearchModel => ({ - slug: embalse._id, - name: `${embalse.name} (${embalse.province})`, -}); +interface Props { + embalses: Embalse[]; +} -export const EmbalseSearch: React.FC = () => { - const router = useRouter(); - const [embalses, setEmbalses] = useState([]); +export const EmbalseSearch: React.FC = (props) => { + const { embalses } = props; + const router = useRouter(); const [filteredEmbalses, setFilteredEmbalses] = useState< EmbalseSearchModel[] >([]); - useEffect(() => { - getEmbalsesCollection().then(setEmbalses); - }, []); - const getFilteredEmbalses = (inputValue: string): EmbalseSearchModel[] => { const lower = inputValue.toLowerCase(); return embalses .filter( (e) => - e.name.toLowerCase().includes(lower) || - e.province.toLowerCase().includes(lower), + e.nombre.toLowerCase().includes(lower) || + e.provincia.toLowerCase().includes(lower), ) .map(mapEmbalseToSearch); }; diff --git a/front/src/pods/embalse-search/embalse-search.model.ts b/front/src/pods/embalse-search/embalse-search.vm.ts similarity index 62% rename from front/src/pods/embalse-search/embalse-search.model.ts rename to front/src/pods/embalse-search/embalse-search.vm.ts index a6dae0b..84b37b2 100644 --- a/front/src/pods/embalse-search/embalse-search.model.ts +++ b/front/src/pods/embalse-search/embalse-search.vm.ts @@ -1,4 +1,4 @@ export interface EmbalseSearchModel { - slug: string; // embalse id used in the URL + slug: string; // Name of the reservoir for the URL name: string; // Combination of name (province) }