diff --git a/src/src/components/stationPopup/StationPopup.js b/src/src/components/stationPopup/StationPopup.js
new file mode 100644
index 0000000..f0250a8
--- /dev/null
+++ b/src/src/components/stationPopup/StationPopup.js
@@ -0,0 +1,66 @@
+import React, { useMemo } from "react";
+import { Marker, Popup, Tooltip } from "react-leaflet";
+import { IconChartDonut } from "@tabler/icons-react";
+import { Link } from "react-router-dom";
+import L from "leaflet";
+
+function StationPopup({ station, lastData }) {
+ const iconMarker = useMemo(
+ () =>
+ new L.Icon({
+ iconUrl: require("../../assets/img/marker.png"),
+ iconSize: [48, 48],
+ }),
+ []
+ );
+
+ const renderClimaticData = (label, measure, unit) => (
+
+ {label}: |
+
+ {lastData?.climaticData
+ .find((item) => item.measure === measure)
+ ?.value.toFixed(1) ?? "N/A"}{" "}
+ {unit}
+ |
+
+ );
+
+ return (
+
+
+
+
+
+ Estación {station.name}
+
+
+
Fecha: {lastData?.date ?? "N/A"}
+
+
+
+ {renderClimaticData("Temperatura máxima", "t_max", "°C")}
+ {renderClimaticData("Temperatura mínima", "t_min", "°C")}
+ {renderClimaticData("Precipitación", "prec", "mm")}
+ {renderClimaticData("Radiación solar", "sol_rad", "MJ")}
+
+
+
+
+
+ Data
+
+
+
+
+ {station.name}
+
+
+ );
+}
+
+export default StationPopup;
diff --git a/src/src/pages/station/Station.js b/src/src/pages/station/Station.js
index ca4c181..d006b12 100644
--- a/src/src/pages/station/Station.js
+++ b/src/src/pages/station/Station.js
@@ -1,63 +1,73 @@
import React, { useState, useEffect, useRef } from "react";
import "./Station.css";
import { Modal, Spinner } from "react-bootstrap";
-import {
- MapContainer,
- Marker,
- Popup,
- TileLayer,
- Tooltip,
- ZoomControl,
- useMap,
-} from "react-leaflet";
+import { MapContainer, TileLayer, ZoomControl, useMap } from "react-leaflet";
import Services from "../../services/Services";
import L from "leaflet";
-import { IconChartDonut } from "@tabler/icons-react";
import SearchBar from "../../components/searchBar/SearchBar";
-import { Link } from "react-router-dom";
+import StationPopup from "../../components/stationPopup/StationPopup";
+
+const MapCenter = ({ stations }) => {
+ const map = useMap();
+
+ useEffect(() => {
+ if (stations.length > 0) {
+ const bounds = L.latLngBounds(
+ stations.map((station) => [station.latitude, station.longitude])
+ );
+ map.fitBounds(bounds);
+ }
+ }, [stations, map]);
+
+ return null;
+};
function Station() {
const [stations, setStations] = useState([]);
- const [loading, setLoading] = useState(true); // Manejo de estado de carga
- const [error, setError] = useState(null); // Manejo de errores
+ const [lastDataStations, setLastDataStations] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
const mapRef = useRef(null);
- const iconMarker = new L.Icon({
- iconUrl: require("../../assets/img/marker.png"),
- iconSize: [48, 48],
- });
-
useEffect(() => {
- // Llamada a la API para obtener las estaciones
- Services.getAllWeatherStations()
- .then((response) => {
+ const fetchStations = async () => {
+ try {
+ const response = await Services.getAllWeatherStations();
const filteredStations = response.filter(
(item) => item.origin === "CHIRPS y ERA-5"
);
setStations(filteredStations);
- setLoading(false); // Marcar como cargado
- })
- .catch((error) => {
+ } catch (error) {
console.error("Error al cargar las estaciones:", error);
setError("Error al cargar las estaciones");
- setLoading(false); // Marcar como cargado aunque haya error
- });
+ } finally {
+ setLoading(false);
+ }
+ };
+ fetchStations();
}, []);
- const MapCenter = ({ stations }) => {
- const map = useMap();
+ useEffect(() => {
+ if (stations.length === 0) return;
- useEffect(() => {
- if (stations.length > 0) {
- const bounds = L.latLngBounds(
- stations.map((station) => [station.latitude, station.longitude])
+ const fetchLastDailyWeather = async () => {
+ try {
+ setLoading(true);
+ const idsStations = stations.map((station) => station.id).join(",");
+ const response = await Services.getLastDailyWeather(idsStations);
+ setLastDataStations(response);
+ } catch (error) {
+ console.error(
+ "Error al cargar la última información de las estaciones:",
+ error
);
- map.fitBounds(bounds); // Ajustar el mapa a los límites de las estaciones
+ setError("Error al cargar la última información de las estaciones");
+ } finally {
+ setLoading(false);
}
- }, [stations, map]);
-
- return null; // No es necesario renderizar nada
- };
+ };
+ fetchLastDailyWeather();
+ }, [stations]);
const handleStationClick = (station) => {
const map = mapRef.current;
@@ -66,71 +76,12 @@ function Station() {
}
};
- const renderPopupData = (station) => (
-
-
-
-
-
- Estación {station.name}
-
-
-
Fecha: 32
-
-
-
-
-
- Temperatura máxima:
- |
- 432 |
-
-
-
- Temperatura mínima:
- |
- 432 |
-
-
- Precipitación: |
- 432 |
-
-
-
- Radiación solar:
- |
- 432 |
-
-
-
-
-
-
- Data
-
-
-
-
- {station.name}
-
-
- );
-
if (error) {
- return {error}
; // Mostrar mensaje de error
+ return {error}
;
}
return (
<>
- {/* Modal de loading */}
-
+
Obteniendo estaciones...
@@ -154,7 +105,18 @@ function Station() {
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
- {stations.map((station) => renderPopupData(station))}
+ {stations.map((station) => {
+ const lastData = lastDataStations.find(
+ (item) => item.weather_station === station.id
+ );
+ return (
+
+ );
+ })}
} A promise that resolves to the daily weather data.
+ * @throws Will throw an error if the request fails.
+ */
+ async getLastDailyWeather(stationsIds) {
+ const url = `/DailyWeatherData/LastDailyData/${stationsIds}/json`;
+ try {
+ const response = await apiClient.get(url);
+ return response.data;
+ } catch (error) {
+ console.error(
+ `Error fetching last daily weather for station ${stationsIds}:`,
+ error
+ );
+ throw new Error(
+ `Failed to fetch last daily weather for station ${stationsIds}. Please try again later.`
+ );
+ }
+ }
}
export default new Services();