From 40307f0c2711dc157c8722da3173fc68b78f44f9 Mon Sep 17 00:00:00 2001 From: josemi1189 Date: Fri, 27 Feb 2026 16:11:04 +0100 Subject: [PATCH 1/5] add page and link to river basin list --- front/src/app/embalse-cuenca/page.tsx | 5 +++++ front/src/layouts/footer.component.tsx | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 front/src/app/embalse-cuenca/page.tsx diff --git a/front/src/app/embalse-cuenca/page.tsx b/front/src/app/embalse-cuenca/page.tsx new file mode 100644 index 0000000..57dddaf --- /dev/null +++ b/front/src/app/embalse-cuenca/page.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function EmbalsesCuencasPage() { + return
EmbalsesCuencasPage
; +} diff --git a/front/src/layouts/footer.component.tsx b/front/src/layouts/footer.component.tsx index 5783e29..9a4312c 100644 --- a/front/src/layouts/footer.component.tsx +++ b/front/src/layouts/footer.component.tsx @@ -14,6 +14,12 @@ export const FooterComponent: FC = () => { > Embalses por provincias + + Embalses por cuencas + Date: Mon, 2 Mar 2026 19:14:57 +0100 Subject: [PATCH 2/5] Feat: add river basin list page and components --- front/src/app/embalse-cuenca/page.tsx | 8 +++-- front/src/common/models/cuencas.model.ts | 24 +++++++++++++ front/src/common/models/index.ts | 1 + front/src/core/constants/cuencas.constants.ts | 36 +++++++++++++++++++ .../embalse-cuenca-list.component.tsx | 29 +++++++++++++++ .../embalse-cuenca-list.pod.tsx | 6 ++++ .../embalse-cuenca-list.repository.ts | 26 ++++++++++++++ .../embalse-cuenca.mapper.ts | 11 ++++++ front/src/pods/embalse-cuenca-list/index.ts | 1 + 9 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 front/src/common/models/cuencas.model.ts create mode 100644 front/src/core/constants/cuencas.constants.ts create mode 100644 front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx create mode 100644 front/src/pods/embalse-cuenca-list/embalse-cuenca-list.pod.tsx create mode 100644 front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts create mode 100644 front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts create mode 100644 front/src/pods/embalse-cuenca-list/index.ts diff --git a/front/src/app/embalse-cuenca/page.tsx b/front/src/app/embalse-cuenca/page.tsx index 57dddaf..92728e6 100644 --- a/front/src/app/embalse-cuenca/page.tsx +++ b/front/src/app/embalse-cuenca/page.tsx @@ -1,5 +1,9 @@ -import React from "react"; +import { EmbalseCuencaListPod } from "@/pods/embalse-cuenca-list"; +import { Metadata } from "next"; +export const metadata: Metadata = { + title: "Embalses por cuencas", +}; export default function EmbalsesCuencasPage() { - return
EmbalsesCuencasPage
; + return ; } diff --git a/front/src/common/models/cuencas.model.ts b/front/src/common/models/cuencas.model.ts new file mode 100644 index 0000000..1466836 --- /dev/null +++ b/front/src/common/models/cuencas.model.ts @@ -0,0 +1,24 @@ +import { Lookup } from "./lookup.model"; + +export interface CuencasModel { + id: string; + name: string; +} + +export interface CuencasModelApi { + _id: string; + nombre: string; +} + +export interface EmbalsesCuencaListApi { + embalse_id: string; + nombre: string; + slug: string; + cuenca: CuencasModelApi; +} + +export interface EmbalsesCuencaList { + id: string; + name: string; + slug?: string; +} diff --git a/front/src/common/models/index.ts b/front/src/common/models/index.ts index a13e258..4baf92a 100644 --- a/front/src/common/models/index.ts +++ b/front/src/common/models/index.ts @@ -1 +1,2 @@ export * from "./lookup.model"; +export * from "./cuencas.model"; diff --git a/front/src/core/constants/cuencas.constants.ts b/front/src/core/constants/cuencas.constants.ts new file mode 100644 index 0000000..8f58b15 --- /dev/null +++ b/front/src/core/constants/cuencas.constants.ts @@ -0,0 +1,36 @@ +export const cuencas = { + SEGURA: { nombre: "Segura", slug: "segura" }, + MINO_SIL: { nombre: "Miño - Sil", slug: "mino-sil" }, + EBRO: { nombre: "Ebro", slug: "ebro" }, + GUADALQUIVIR: { nombre: "Guadalquivir", slug: "guadalquivir" }, + JUCAR: { nombre: "Júcar", slug: "jucar" }, + DUERO: { nombre: "Duero", slug: "duero" }, + CANTABRICO_ORIENTAL: { + nombre: "Cantábrico Oriental", + slug: "cantabrico-oriental", + }, + CUENCA_MEDITERRANEA_ANDALUZA: { + nombre: "Cuenca Mediterránea Andaluza", + slug: "cuenca-mediterranea-andaluza", + }, + GUADIANA: { nombre: "Guadiana", slug: "guadiana" }, + CANTABRICO_OCCIDENTAL: { + nombre: "Cantábrico Occidental", + slug: "cantabrico-occidental", + }, + TINTO_ODIEL_Y_PIEDRAS: { + nombre: "Tinto, Odiel y Piedras", + slug: "tinto-odiel-y-piedras", + }, + TAJO: { nombre: "Tajo", slug: "tajo" }, + GALICIA_COSTA: { nombre: "Galicia Costa", slug: "galicia-costa" }, + GUADALETE_BARBATE: { nombre: "Guadalete-Barbate", slug: "guadalete-barbate" }, + CUENCAS_INTERNAS_DEL_PAIS_VASCO: { + nombre: "Cuencas Internas del País Vasco", + slug: "cuencas-internas-del-pais-vasco", + }, + CUENCAS_INTERNAS_DE_CATALUNA: { + nombre: "Cuencas Internas de Cataluña", + slug: "cuencas-internas-de-cataluna", + }, +} as const; diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx new file mode 100644 index 0000000..fed72d9 --- /dev/null +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx @@ -0,0 +1,29 @@ +import { Card } from "@/common/components/card.component"; +import { mapRiverBasinListFromApiToView } from "./embalse-cuenca.mapper"; +import { getRiverBasins } from "./embalse-cuenca-list.repository"; +import Link from "next/link"; +import { generateSlug } from "db-model"; + +export const EmbalsesCuencaList: React.FC = async () => { + const cuencasAPI = await getRiverBasins(); + const cuencasList = mapRiverBasinListFromApiToView(cuencasAPI); + + return ( + +
+

Embalses por cuencas

+
+ {cuencasList.map(({ id, name }) => ( + + {name} + + ))} +
+
+
+ ); +}; diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.pod.tsx b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.pod.tsx new file mode 100644 index 0000000..cd2c8c7 --- /dev/null +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.pod.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import { EmbalsesCuencaList } from "./embalse-cuenca-list.component"; + +export const EmbalseCuencaListPod: React.FC = () => { + return ; +}; diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts new file mode 100644 index 0000000..527ab6e --- /dev/null +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts @@ -0,0 +1,26 @@ +"use server"; + +import { getDb } from "@/lib/mongodb"; +import type { CuencasModelApi } from "@/common/models/cuencas.model"; + +export async function getRiverBasins(): Promise { + try { + const db = await getDb(); + const docs = await db + .collection("cuencas") + .find({}, { projection: { _id: 1, nombre: 1 } }) + .toArray(); + + return docs.map((doc) => ({ + _id: doc.slug ?? String(doc._id), + nombre: doc.nombre ?? "", + })); + } catch (error) { + console.warn( + "getEmbalsesByRiverBasin: MongoDB not available (build time?), returning empty array.", + "Error:", + error instanceof Error ? error.message : error, + ); + } + return []; +} diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts b/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts new file mode 100644 index 0000000..c6aec44 --- /dev/null +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts @@ -0,0 +1,11 @@ +import { CuencasModel, CuencasModelApi } from "@/common/models/cuencas.model"; + +export const mapRiverBasinListFromApiToView = ( + cuencas: CuencasModelApi[], +): CuencasModel[] => + Array.isArray(cuencas) + ? cuencas.map((cuenca) => ({ + id: cuenca._id, + name: cuenca.nombre, + })) + : []; diff --git a/front/src/pods/embalse-cuenca-list/index.ts b/front/src/pods/embalse-cuenca-list/index.ts new file mode 100644 index 0000000..7ee1112 --- /dev/null +++ b/front/src/pods/embalse-cuenca-list/index.ts @@ -0,0 +1 @@ +export * from "./embalse-cuenca-list.pod"; From a2b54a3974c552a2f0db24df3035a9de4656d677 Mon Sep 17 00:00:00 2001 From: josemi1189 Date: Mon, 2 Mar 2026 19:19:07 +0100 Subject: [PATCH 3/5] Feat: Add reservoirs list by river basin --- .../src/app/embalse-cuenca/[cuenca]/page.tsx | 46 +++++++++++++++++++ .../embalse-cuenca.component.tsx | 42 +++++++++++++++++ .../embalse-cuenca/embalse-cuenca.mapper.ts | 14 ++++++ .../embalse-cuenca/embalse-cuenca.pod.tsx | 19 ++++++++ .../embalse-cuenca.repository.ts | 28 +++++++++++ front/src/pods/embalse-cuenca/index.ts | 2 + 6 files changed, 151 insertions(+) create mode 100644 front/src/app/embalse-cuenca/[cuenca]/page.tsx create mode 100644 front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx create mode 100644 front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts create mode 100644 front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx create mode 100644 front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts create mode 100644 front/src/pods/embalse-cuenca/index.ts diff --git a/front/src/app/embalse-cuenca/[cuenca]/page.tsx b/front/src/app/embalse-cuenca/[cuenca]/page.tsx new file mode 100644 index 0000000..1f1ebae --- /dev/null +++ b/front/src/app/embalse-cuenca/[cuenca]/page.tsx @@ -0,0 +1,46 @@ +import { EmbalsesCuencaPod, getEmbalsesPorCuenca } from "@/pods/embalse-cuenca"; +import { cuencas } from "@/core/constants/cuencas.constants"; +import { Metadata } from "next"; +import { mapRiverBasinListFromApiToView } from "@/pods/embalse-cuenca-list/embalse-cuenca.mapper"; + +interface Props { + params: Promise<{ cuenca: string }>; +} + +const getCuencaBySlug = (slug: string) => { + return Object.values(cuencas).find((cuenca) => cuenca.slug === slug); +}; + +export async function generateMetadata({ params }: Props): Promise { + const { cuenca } = await params; + const datosCuenca = getCuencaBySlug(cuenca.toString()); + + return { + title: `Embalses de ${datosCuenca.nombre}`, + }; +} + +export default async function EmbalseCuencaListadoPage({ + params, +}: Props): Promise { + const { cuenca } = await params; + const datosCuenca = getCuencaBySlug(cuenca.toString()); + const embalsesByRiverBasinFromApi = await getEmbalsesPorCuenca( + datosCuenca.nombre, + ); + const embalsesByRiverBasinLookup = mapRiverBasinListFromApiToView( + embalsesByRiverBasinFromApi, + ); + + if (!cuenca) { + return
Cuenca no encontrada
; + } + + return ( + + ); +} diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx b/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx new file mode 100644 index 0000000..1f2f1b6 --- /dev/null +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx @@ -0,0 +1,42 @@ +"use client"; +import { Card } from "@/common/components/card.component"; +import { CuencasModel } from "@/common/models"; +import { generateSlug } from "db-model"; +import Link from "next/link"; + +export interface Props { + nombreCuenca: string; + slug: string; + embalses: CuencasModel[]; +} + +export const EmbalseCuencaComponent: React.FC = (props) => { + const { nombreCuenca, slug, embalses } = props; + return ( + +
+ {embalses.length === 0 ? ( +

No se encontraron embalses para {nombreCuenca}

+ ) : ( +

Embalses de {nombreCuenca}

+ )} +
+ {embalses.map(({ id, name }) => ( + + {name} + + ))} +
+ {`Mapa +
+
+ ); +}; diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts b/front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts new file mode 100644 index 0000000..79f52c9 --- /dev/null +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts @@ -0,0 +1,14 @@ +import { + EmbalsesCuencaList, + EmbalsesCuencaListApi, +} from "@/common/models/cuencas.model"; + +export const mapRiverBasinListFromApiToView = ( + embalses: EmbalsesCuencaListApi[], +): EmbalsesCuencaList[] => + Array.isArray(embalses) + ? embalses.map((embalse) => ({ + id: embalse.embalse_id, + name: embalse.nombre, + })) + : []; diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx b/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx new file mode 100644 index 0000000..758932f --- /dev/null +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { EmbalseCuencaComponent } from "./embalse-cuenca.component"; +import { CuencasModel } from "@/common/models"; + +export interface Props { + nombreCuenca: string; + slug: string; + embalses: CuencasModel[]; +} +export const EmbalsesCuencaPod: React.FC = (props) => { + const { nombreCuenca, slug, embalses } = props; + return ( + + ); +}; diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts b/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts new file mode 100644 index 0000000..2e98146 --- /dev/null +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts @@ -0,0 +1,28 @@ +"use server"; + +import { getDb } from "@/lib/mongodb"; +import { CuencasModelApi } from "@/common/models/cuencas.model"; + +export async function getEmbalsesPorCuenca( + nombre: string, +): Promise { + try { + const db = await getDb(); + const docs = await db + .collection("embalses") + .find({ "cuenca.nombre": nombre }, { projection: { _id: 1, nombre: 1 } }) + .toArray(); + + return docs.map((doc) => ({ + _id: doc.slug ?? String(doc._id), + nombre: doc.nombre ?? "", + })); + } catch (error) { + console.warn( + "getEmbalsesByRiverBasin: MongoDB not available (build time?), returning empty array.", + "Error:", + error instanceof Error ? error.message : error, + ); + } + return []; +} diff --git a/front/src/pods/embalse-cuenca/index.ts b/front/src/pods/embalse-cuenca/index.ts new file mode 100644 index 0000000..25806f0 --- /dev/null +++ b/front/src/pods/embalse-cuenca/index.ts @@ -0,0 +1,2 @@ +export * from "./embalse-cuenca.pod"; +export * from "./embalse-cuenca.repository"; From 2b3248459c5a2c10f5aab7a9bf7acdca5cc19e39 Mon Sep 17 00:00:00 2001 From: josemi1189 Date: Mon, 2 Mar 2026 20:23:39 +0100 Subject: [PATCH 4/5] Refactor: rename function names to spanish --- .../src/app/embalse-cuenca/[cuenca]/page.tsx | 22 +++++++++++-------- .../embalse-cuenca-list.component.tsx | 4 ++-- .../embalse-cuenca.mapper.ts | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/front/src/app/embalse-cuenca/[cuenca]/page.tsx b/front/src/app/embalse-cuenca/[cuenca]/page.tsx index 1f1ebae..49690cc 100644 --- a/front/src/app/embalse-cuenca/[cuenca]/page.tsx +++ b/front/src/app/embalse-cuenca/[cuenca]/page.tsx @@ -1,7 +1,8 @@ import { EmbalsesCuencaPod, getEmbalsesPorCuenca } from "@/pods/embalse-cuenca"; import { cuencas } from "@/core/constants/cuencas.constants"; import { Metadata } from "next"; -import { mapRiverBasinListFromApiToView } from "@/pods/embalse-cuenca-list/embalse-cuenca.mapper"; +import { mapListaCuencasDesdeApiParaVista } from "@/pods/embalse-cuenca-list/embalse-cuenca.mapper"; +import { notFound } from "next/navigation"; interface Props { params: Promise<{ cuenca: string }>; @@ -15,6 +16,10 @@ export async function generateMetadata({ params }: Props): Promise { const { cuenca } = await params; const datosCuenca = getCuencaBySlug(cuenca.toString()); + if (!datosCuenca) { + return {}; + } + return { title: `Embalses de ${datosCuenca.nombre}`, }; @@ -25,22 +30,21 @@ export default async function EmbalseCuencaListadoPage({ }: Props): Promise { const { cuenca } = await params; const datosCuenca = getCuencaBySlug(cuenca.toString()); - const embalsesByRiverBasinFromApi = await getEmbalsesPorCuenca( + if (!datosCuenca) { + notFound(); + } + const embalsesPorCuencaDesdeApi = await getEmbalsesPorCuenca( datosCuenca.nombre, ); - const embalsesByRiverBasinLookup = mapRiverBasinListFromApiToView( - embalsesByRiverBasinFromApi, + const embalsesPorCuenca = mapListaCuencasDesdeApiParaVista( + embalsesPorCuencaDesdeApi, ); - if (!cuenca) { - return
Cuenca no encontrada
; - } - return ( ); } diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx index fed72d9..3cbd08c 100644 --- a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx @@ -1,12 +1,12 @@ import { Card } from "@/common/components/card.component"; -import { mapRiverBasinListFromApiToView } from "./embalse-cuenca.mapper"; +import { mapListaCuencasDesdeApiParaVista } from "./embalse-cuenca.mapper"; import { getRiverBasins } from "./embalse-cuenca-list.repository"; import Link from "next/link"; import { generateSlug } from "db-model"; export const EmbalsesCuencaList: React.FC = async () => { const cuencasAPI = await getRiverBasins(); - const cuencasList = mapRiverBasinListFromApiToView(cuencasAPI); + const cuencasList = mapListaCuencasDesdeApiParaVista(cuencasAPI); return ( diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts b/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts index c6aec44..787a4c6 100644 --- a/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts @@ -1,6 +1,6 @@ import { CuencasModel, CuencasModelApi } from "@/common/models/cuencas.model"; -export const mapRiverBasinListFromApiToView = ( +export const mapListaCuencasDesdeApiParaVista = ( cuencas: CuencasModelApi[], ): CuencasModel[] => Array.isArray(cuencas) From f3c7de61ff41ce000215f4a5750589fdbaebf685 Mon Sep 17 00:00:00 2001 From: manudous Date: Wed, 4 Mar 2026 16:38:45 +0100 Subject: [PATCH 5/5] Feat: Refactor reservoir and river basin components to use new lookup mapping and API structure --- front/next-env.d.ts | 2 +- .../src/app/embalse-cuenca/[cuenca]/page.tsx | 16 +++----- front/src/app/embalse-cuenca/page.tsx | 9 ++++- front/src/common/mappers/index.ts | 1 + front/src/common/mappers/lookup.mappers.ts | 12 ++++++ front/src/common/models/cuencas.model.ts | 14 +------ front/src/common/models/lookup.model.ts | 5 +++ front/src/core/constants/index.ts | 1 + front/src/lib/mongodb.ts | 37 ++++++++++--------- .../embalse-cuenca-list.component.tsx | 13 ++++--- .../embalse-cuenca-list.pod.tsx | 10 ++++- .../embalse-cuenca-list.repository.ts | 14 ++----- .../embalse-cuenca.mapper.ts | 11 ------ front/src/pods/embalse-cuenca-list/index.ts | 1 + .../embalse-cuenca.component.tsx | 7 ++-- .../embalse-cuenca/embalse-cuenca.mapper.ts | 14 ------- .../embalse-cuenca/embalse-cuenca.pod.tsx | 13 ++----- .../embalse-cuenca.repository.ts | 19 ++++------ 18 files changed, 89 insertions(+), 110 deletions(-) create mode 100644 front/src/common/mappers/index.ts create mode 100644 front/src/common/mappers/lookup.mappers.ts delete mode 100644 front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts delete mode 100644 front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts diff --git a/front/next-env.d.ts b/front/next-env.d.ts index 9edff1c..c4b7818 100644 --- a/front/next-env.d.ts +++ b/front/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/front/src/app/embalse-cuenca/[cuenca]/page.tsx b/front/src/app/embalse-cuenca/[cuenca]/page.tsx index 49690cc..42c6c08 100644 --- a/front/src/app/embalse-cuenca/[cuenca]/page.tsx +++ b/front/src/app/embalse-cuenca/[cuenca]/page.tsx @@ -1,8 +1,7 @@ import { EmbalsesCuencaPod, getEmbalsesPorCuenca } from "@/pods/embalse-cuenca"; -import { cuencas } from "@/core/constants/cuencas.constants"; +import { cuencas } from "@/core/constants"; import { Metadata } from "next"; -import { mapListaCuencasDesdeApiParaVista } from "@/pods/embalse-cuenca-list/embalse-cuenca.mapper"; -import { notFound } from "next/navigation"; +import { mapLookupListFromApiToViewModel } from "@/common/mappers"; interface Props { params: Promise<{ cuenca: string }>; @@ -14,7 +13,7 @@ const getCuencaBySlug = (slug: string) => { export async function generateMetadata({ params }: Props): Promise { const { cuenca } = await params; - const datosCuenca = getCuencaBySlug(cuenca.toString()); + const datosCuenca = getCuencaBySlug(cuenca); if (!datosCuenca) { return {}; @@ -29,21 +28,18 @@ export default async function EmbalseCuencaListadoPage({ params, }: Props): Promise { const { cuenca } = await params; - const datosCuenca = getCuencaBySlug(cuenca.toString()); - if (!datosCuenca) { - notFound(); - } + const datosCuenca = getCuencaBySlug(cuenca); + const embalsesPorCuencaDesdeApi = await getEmbalsesPorCuenca( datosCuenca.nombre, ); - const embalsesPorCuenca = mapListaCuencasDesdeApiParaVista( + const embalsesPorCuenca = mapLookupListFromApiToViewModel( embalsesPorCuencaDesdeApi, ); return ( ); diff --git a/front/src/app/embalse-cuenca/page.tsx b/front/src/app/embalse-cuenca/page.tsx index 92728e6..ea7ff72 100644 --- a/front/src/app/embalse-cuenca/page.tsx +++ b/front/src/app/embalse-cuenca/page.tsx @@ -1,9 +1,14 @@ +import { mapLookupListFromApiToViewModel } from "@/common/mappers"; import { EmbalseCuencaListPod } from "@/pods/embalse-cuenca-list"; +import { getRiverBasins } from "@/pods/embalse-cuenca-list/embalse-cuenca-list.repository"; import { Metadata } from "next"; export const metadata: Metadata = { title: "Embalses por cuencas", }; -export default function EmbalsesCuencasPage() { - return ; +export default async function EmbalsesCuencasPage() { + const cuencasAPI = await getRiverBasins(); + const cuencaList = mapLookupListFromApiToViewModel(cuencasAPI); + + return ; } diff --git a/front/src/common/mappers/index.ts b/front/src/common/mappers/index.ts new file mode 100644 index 0000000..cfbbb94 --- /dev/null +++ b/front/src/common/mappers/index.ts @@ -0,0 +1 @@ +export * from "./lookup.mappers"; diff --git a/front/src/common/mappers/lookup.mappers.ts b/front/src/common/mappers/lookup.mappers.ts new file mode 100644 index 0000000..2957cc2 --- /dev/null +++ b/front/src/common/mappers/lookup.mappers.ts @@ -0,0 +1,12 @@ +import { LookupApi } from "@/common/models"; +import { Lookup } from "@content-island/api-client"; + +export const mapLookupListFromApiToViewModel = ( + lookupList: LookupApi[], +): Lookup[] => + Array.isArray(lookupList) ? lookupList.map(mapLookupFromApiToViewModel) : []; + +const mapLookupFromApiToViewModel = (lookup: LookupApi): Lookup => ({ + id: lookup._id, + name: lookup.nombre, +}); diff --git a/front/src/common/models/cuencas.model.ts b/front/src/common/models/cuencas.model.ts index 1466836..ec82594 100644 --- a/front/src/common/models/cuencas.model.ts +++ b/front/src/common/models/cuencas.model.ts @@ -1,20 +1,10 @@ -import { Lookup } from "./lookup.model"; - -export interface CuencasModel { - id: string; - name: string; -} - -export interface CuencasModelApi { - _id: string; - nombre: string; -} +import { LookupApi } from "./lookup.model"; export interface EmbalsesCuencaListApi { embalse_id: string; nombre: string; slug: string; - cuenca: CuencasModelApi; + cuenca: LookupApi; } export interface EmbalsesCuencaList { diff --git a/front/src/common/models/lookup.model.ts b/front/src/common/models/lookup.model.ts index cd43ce3..f5cf627 100644 --- a/front/src/common/models/lookup.model.ts +++ b/front/src/common/models/lookup.model.ts @@ -2,3 +2,8 @@ export interface Lookup { id: string; name: string; } + +export interface LookupApi { + _id: string; + nombre: string; +} diff --git a/front/src/core/constants/index.ts b/front/src/core/constants/index.ts index d333a56..768ed5b 100644 --- a/front/src/core/constants/index.ts +++ b/front/src/core/constants/index.ts @@ -1 +1,2 @@ export * from "./provincias.constants"; +export * from "./cuencas.constants"; diff --git a/front/src/lib/mongodb.ts b/front/src/lib/mongodb.ts index 297c41c..3fc9708 100644 --- a/front/src/lib/mongodb.ts +++ b/front/src/lib/mongodb.ts @@ -2,29 +2,32 @@ import { MongoClient, type Db } from "mongodb"; //hack de TypeScript para tipar globalThis con nuestra propiedad custom _mongoClient const globalForMongo = globalThis as typeof globalThis & { - _mongoClient?: MongoClient; + _mongoClient?: MongoClient; }; //crea el cliente solo si no existe ya (singleton) -async function getClient(): Promise { - const connectionString = process.env.MONGODB_CONNECTION_STRING; - if (!connectionString) { - throw new Error( - "Please define the MONGODB_CONNECTION_STRING environment variable in .env.local" - ); - } +async function getClient(): Promise { + const connectionString = process.env.MONGODB_CONNECTION_STRING; + if (!connectionString) { + throw new Error( + "Please define the MONGODB_CONNECTION_STRING environment variable in .env.local", + ); + } - if (!globalForMongo._mongoClient) { - console.log("[mongodb] Connecting to MongoDB...", connectionString.replace(/\/\/.*@/, "//***@")); - globalForMongo._mongoClient = new MongoClient(connectionString); - await globalForMongo._mongoClient.connect(); - console.log("[mongodb] Connected successfully"); - } + if (!globalForMongo._mongoClient) { + console.log( + "[mongodb] Connecting to MongoDB...", + connectionString.replace(/\/\/.*@/, "//***@"), + ); + globalForMongo._mongoClient = new MongoClient(connectionString); + await globalForMongo._mongoClient.connect(); + console.log("[mongodb] Connected successfully"); + } - return globalForMongo._mongoClient; + return globalForMongo._mongoClient; } //lo que exportamo devuelve la instancia de Db lista para hacer queries export async function getDb(): Promise { - const client = await getClient(); - return client.db(); + const client = await getClient(); + return client.db(); } diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx index 3cbd08c..7a10e9e 100644 --- a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.component.tsx @@ -1,19 +1,20 @@ import { Card } from "@/common/components/card.component"; -import { mapListaCuencasDesdeApiParaVista } from "./embalse-cuenca.mapper"; -import { getRiverBasins } from "./embalse-cuenca-list.repository"; import Link from "next/link"; import { generateSlug } from "db-model"; +import { Lookup } from "@/common/models"; -export const EmbalsesCuencaList: React.FC = async () => { - const cuencasAPI = await getRiverBasins(); - const cuencasList = mapListaCuencasDesdeApiParaVista(cuencasAPI); +interface Props { + cuencaList: Lookup[]; +} +export const EmbalsesCuencaList: React.FC = (props) => { + const { cuencaList } = props; return (

Embalses por cuencas

- {cuencasList.map(({ id, name }) => ( + {cuencaList.map(({ id, name }) => ( { - return ; +interface Props { + cuencaList: Lookup[]; +} + +export const EmbalseCuencaListPod: React.FC = async (props) => { + const { cuencaList } = props; + return ; }; diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts index 527ab6e..335ef57 100644 --- a/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts +++ b/front/src/pods/embalse-cuenca-list/embalse-cuenca-list.repository.ts @@ -1,20 +1,15 @@ "use server"; +import { LookupApi } from "@/common/models"; import { getDb } from "@/lib/mongodb"; -import type { CuencasModelApi } from "@/common/models/cuencas.model"; -export async function getRiverBasins(): Promise { +export async function getRiverBasins(): Promise { try { const db = await getDb(); - const docs = await db - .collection("cuencas") + return await db + .collection("cuencas") .find({}, { projection: { _id: 1, nombre: 1 } }) .toArray(); - - return docs.map((doc) => ({ - _id: doc.slug ?? String(doc._id), - nombre: doc.nombre ?? "", - })); } catch (error) { console.warn( "getEmbalsesByRiverBasin: MongoDB not available (build time?), returning empty array.", @@ -22,5 +17,4 @@ export async function getRiverBasins(): Promise { error instanceof Error ? error.message : error, ); } - return []; } diff --git a/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts b/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts deleted file mode 100644 index 787a4c6..0000000 --- a/front/src/pods/embalse-cuenca-list/embalse-cuenca.mapper.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CuencasModel, CuencasModelApi } from "@/common/models/cuencas.model"; - -export const mapListaCuencasDesdeApiParaVista = ( - cuencas: CuencasModelApi[], -): CuencasModel[] => - Array.isArray(cuencas) - ? cuencas.map((cuenca) => ({ - id: cuenca._id, - name: cuenca.nombre, - })) - : []; diff --git a/front/src/pods/embalse-cuenca-list/index.ts b/front/src/pods/embalse-cuenca-list/index.ts index 7ee1112..54c55e3 100644 --- a/front/src/pods/embalse-cuenca-list/index.ts +++ b/front/src/pods/embalse-cuenca-list/index.ts @@ -1 +1,2 @@ export * from "./embalse-cuenca-list.pod"; +export * from "./embalse-cuenca-list.repository"; diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx b/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx index 1f2f1b6..2e5879e 100644 --- a/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.component.tsx @@ -1,17 +1,16 @@ "use client"; import { Card } from "@/common/components/card.component"; -import { CuencasModel } from "@/common/models"; +import { Lookup } from "@/common/models"; import { generateSlug } from "db-model"; import Link from "next/link"; export interface Props { nombreCuenca: string; - slug: string; - embalses: CuencasModel[]; + embalses: Lookup[]; } export const EmbalseCuencaComponent: React.FC = (props) => { - const { nombreCuenca, slug, embalses } = props; + const { nombreCuenca, embalses } = props; return (
diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts b/front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts deleted file mode 100644 index 79f52c9..0000000 --- a/front/src/pods/embalse-cuenca/embalse-cuenca.mapper.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { - EmbalsesCuencaList, - EmbalsesCuencaListApi, -} from "@/common/models/cuencas.model"; - -export const mapRiverBasinListFromApiToView = ( - embalses: EmbalsesCuencaListApi[], -): EmbalsesCuencaList[] => - Array.isArray(embalses) - ? embalses.map((embalse) => ({ - id: embalse.embalse_id, - name: embalse.nombre, - })) - : []; diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx b/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx index 758932f..80894e3 100644 --- a/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.pod.tsx @@ -1,19 +1,14 @@ import React from "react"; import { EmbalseCuencaComponent } from "./embalse-cuenca.component"; -import { CuencasModel } from "@/common/models"; +import { Lookup } from "@/common/models"; export interface Props { nombreCuenca: string; - slug: string; - embalses: CuencasModel[]; + embalses: Lookup[]; } export const EmbalsesCuencaPod: React.FC = (props) => { - const { nombreCuenca, slug, embalses } = props; + const { nombreCuenca, embalses } = props; return ( - + ); }; diff --git a/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts b/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts index 2e98146..cf2c531 100644 --- a/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts +++ b/front/src/pods/embalse-cuenca/embalse-cuenca.repository.ts @@ -1,22 +1,18 @@ "use server"; +import { LookupApi } from "@/common/models"; import { getDb } from "@/lib/mongodb"; -import { CuencasModelApi } from "@/common/models/cuencas.model"; +import { Embalse } from "db-model"; -export async function getEmbalsesPorCuenca( +export const getEmbalsesPorCuenca = async ( nombre: string, -): Promise { +): Promise => { try { const db = await getDb(); - const docs = await db - .collection("embalses") + return await db + .collection("embalses") .find({ "cuenca.nombre": nombre }, { projection: { _id: 1, nombre: 1 } }) .toArray(); - - return docs.map((doc) => ({ - _id: doc.slug ?? String(doc._id), - nombre: doc.nombre ?? "", - })); } catch (error) { console.warn( "getEmbalsesByRiverBasin: MongoDB not available (build time?), returning empty array.", @@ -24,5 +20,4 @@ export async function getEmbalsesPorCuenca( error instanceof Error ? error.message : error, ); } - return []; -} +};