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..49690cc --- /dev/null +++ b/front/src/app/embalse-cuenca/[cuenca]/page.tsx @@ -0,0 +1,50 @@ +import { EmbalsesCuencaPod, getEmbalsesPorCuenca } from "@/pods/embalse-cuenca"; +import { cuencas } from "@/core/constants/cuencas.constants"; +import { Metadata } from "next"; +import { mapListaCuencasDesdeApiParaVista } from "@/pods/embalse-cuenca-list/embalse-cuenca.mapper"; +import { notFound } from "next/navigation"; + +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()); + + if (!datosCuenca) { + return {}; + } + + return { + title: `Embalses de ${datosCuenca.nombre}`, + }; +} + +export default async function EmbalseCuencaListadoPage({ + params, +}: Props): Promise { + const { cuenca } = await params; + const datosCuenca = getCuencaBySlug(cuenca.toString()); + if (!datosCuenca) { + notFound(); + } + const embalsesPorCuencaDesdeApi = await getEmbalsesPorCuenca( + datosCuenca.nombre, + ); + const embalsesPorCuenca = mapListaCuencasDesdeApiParaVista( + embalsesPorCuencaDesdeApi, + ); + + return ( + + ); +} diff --git a/front/src/app/embalse-cuenca/page.tsx b/front/src/app/embalse-cuenca/page.tsx new file mode 100644 index 0000000..92728e6 --- /dev/null +++ b/front/src/app/embalse-cuenca/page.tsx @@ -0,0 +1,9 @@ +import { EmbalseCuencaListPod } from "@/pods/embalse-cuenca-list"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Embalses por cuencas", +}; +export default function 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/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 + { + const cuencasAPI = await getRiverBasins(); + const cuencasList = mapListaCuencasDesdeApiParaVista(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..787a4c6 --- /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 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 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"; 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";