diff --git a/src/src/components/stationCard/StationCard.css b/src/src/components/stationCard/StationCard.css new file mode 100644 index 0000000..20199ab --- /dev/null +++ b/src/src/components/stationCard/StationCard.css @@ -0,0 +1,16 @@ +.wave1 { + position: absolute; + top: 0px; + right: -16px; + rotate: 0grad; + width: 100%; + height: 100px; /* Ajusta el tamaño del área de la onda */ + z-index: 0; + overflow: hidden; +} + +.wave1 > svg { + position: absolute; + top: -20px; /* Ajusta la posición vertical de la onda */ + right: 0; +} \ No newline at end of file diff --git a/src/src/components/stationCard/StationCard.js b/src/src/components/stationCard/StationCard.js new file mode 100644 index 0000000..adccb94 --- /dev/null +++ b/src/src/components/stationCard/StationCard.js @@ -0,0 +1,141 @@ +import React, { useEffect, useState } from "react"; +import "./StationCard.css"; +import { Card, Col, Spinner } from "react-bootstrap"; +import { IconDroplet, IconMapPin, IconSun } from "@tabler/icons-react"; +import Services from "../../services/Services"; + +function StationCard({ loading, msgError, station }) { + const [lastDataStation, setLastDataStation] = useState(); + + console.log(station); + + useEffect(() => { + if (!station) return; + + const fetchLastDailyWeather = async () => { + try { + const idStations = station.id; + const response = await Services.getLastDailyWeather(idStations); + setLastDataStation(response); + console.log(response); + } catch (error) { + console.error( + "Error al cargar la última información de las estaciones:", + error + ); + } finally { + } + }; + fetchLastDailyWeather(); + }, [station]); + + const getDayOfWeek = (dateString) => { + const date = new Date(dateString); + return date.toLocaleDateString("es-ES", { weekday: "long" }); + }; + + return ( + + + {/* Onda SVG */} +
+ + + + + +
+ {loading ? ( +
+ +

Cargando datos...

+
+ ) : msgError ? ( +
+

{msgError}

+
+ ) : station ? ( + +
+
+
+

{station.name}

+ + {lastDataStation?.climaticData + ? lastDataStation.climaticData + .find((item) => item.measure === "t_min") + ?.value.toFixed(1) ?? "N/A" + : "N/A"}{" "} + -{" "} + {lastDataStation?.climaticData + ? lastDataStation.climaticData + .find((item) => item.measure === "t_max") + ?.value.toFixed(1) ?? "N/A" + : "N/A"} + +
+
+ + + {lastDataStation?.climaticData + ? lastDataStation.climaticData + .find((item) => item.measure === "prec") + ?.value.toFixed(1) ?? "N/A" + : "N/A"}{" "} + mm + + + + {lastDataStation?.climaticData + ? lastDataStation.climaticData + .find((item) => item.measure === "sol_rad") + ?.value.toFixed(1) ?? "N/A" + : "N/A"}{" "} + M/J + +
+
+
+
+ + {lastDataStation?.date + ? getDayOfWeek(lastDataStation.date) + : "N/A"} + + {lastDataStation?.date ?? "N/A"} +
+
+ + + {station.municipality}, {station.state} + +
+
+
+
+ ) : ( +
+

No se ha seleccionado ninguna estación

+
+ )} +
+ + ); +} + +export default StationCard; diff --git a/src/src/pages/dashboard/Dashboard.js b/src/src/pages/dashboard/Dashboard.js index 95b89c0..9c2c529 100644 --- a/src/src/pages/dashboard/Dashboard.js +++ b/src/src/pages/dashboard/Dashboard.js @@ -41,7 +41,7 @@ const Dashboard = () => { try { const response = await Services.getAllWeatherStations(); const filteredStations = response.filter( - (item) => item.origin === "CHIRPS y ERA-5" + (item) => item.origin === "WEATHERLINK" ); const station = filteredStations.find((item) => item.id === idWS); setStations(filteredStations); diff --git a/src/src/pages/home/Home.css b/src/src/pages/home/Home.css index db43419..39d7033 100644 --- a/src/src/pages/home/Home.css +++ b/src/src/pages/home/Home.css @@ -7,10 +7,10 @@ url("../../assets/img/bg-home.jpg"); background-size: cover; background-position: center; - min-height: 80vh; + min-height: 90vh; } -.container-header { +/* .container-header { position: relative; top: 150px; -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/src/src/pages/home/Home.js b/src/src/pages/home/Home.js index 5e32815..abba0ac 100644 --- a/src/src/pages/home/Home.js +++ b/src/src/pages/home/Home.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import "./Home.css"; import { Col, Container, Row } from "react-bootstrap"; import Feature from "../../components/feature/Feature"; @@ -8,17 +8,107 @@ import { IconMapSearch, IconCloudRain, } from "@tabler/icons-react"; +import StationCard from "../../components/stationCard/StationCard"; +import Services from "../../services/Services"; function Home() { // Definir colores en una variable para facilitar ajustes globales const green = "green"; const white = "white"; + const [stations, setStations] = useState([]); + const [nearestStation, setNearestStation] = useState([]); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchStations = async () => { + try { + const response = await Services.getAllWeatherStations(); + const filteredStations = response.filter( + (item) => item.origin === "WEATHERLINK" + ); + setStations(filteredStations); + } catch (error) { + console.error("Error al cargar las estaciones:", error); + setError("Error al cargar las estaciones"); + } finally { + setLoading(false); + } + }; + + fetchStations(); + }, []); + + useEffect(() => { + const getUserLocation = () => { + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition( + (position) => { + const userLat = position.coords.latitude; + const userLon = position.coords.longitude; + findNearestStation(userLat, userLon); + }, + (error) => { + console.error("Error al obtener la ubicación del usuario:", error); + setError("Error al obtener la ubicación del usuario"); + setLoading(false); + } + ); + } else { + console.error("Geolocalización no es soportada por este navegador."); + setError("Geolocalización no es soportada por este navegador."); + setLoading(false); + } + }; + + const findNearestStation = (userLat, userLon) => { + let minDistance = Infinity; + let nearest = null; + + stations.forEach((station) => { + const distance = getDistanceFromLatLonInKm( + userLat, + userLon, + station.latitude, + station.longitude + ); + if (distance < minDistance) { + minDistance = distance; + nearest = station; + } + }); + + setNearestStation(nearest); + setLoading(false); + }; + + const getDistanceFromLatLonInKm = (lat1, lon1, lat2, lon2) => { + const R = 6371; // Radio de la Tierra en km + const dLat = deg2rad(lat2 - lat1); + const dLon = deg2rad(lon2 - lon1); + const a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(deg2rad(lat1)) * + Math.cos(deg2rad(lat2)) * + Math.sin(dLon / 2) * + Math.sin(dLon / 2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + const distance = R * c; // Distancia en km + return distance; + }; + + const deg2rad = (deg) => { + return deg * (Math.PI / 180); + }; + getUserLocation(); + }, [stations]); + return (
{/* Sección de bienvenida */} -
- +
+

Bienvenido a AClimate monitoring

@@ -37,6 +127,9 @@ function Home() {
+ + +
@@ -44,7 +137,7 @@ function Home() { @@ -56,7 +149,7 @@ function Home() { /> diff --git a/src/src/pages/station/Station.js b/src/src/pages/station/Station.js index d006b12..ae09b26 100644 --- a/src/src/pages/station/Station.js +++ b/src/src/pages/station/Station.js @@ -34,7 +34,7 @@ function Station() { try { const response = await Services.getAllWeatherStations(); const filteredStations = response.filter( - (item) => item.origin === "CHIRPS y ERA-5" + (item) => item.origin === "WEATHERLINK" ); setStations(filteredStations); } catch (error) { diff --git a/src/src/services/Services.js b/src/src/services/Services.js index 1ca7121..901e50e 100644 --- a/src/src/services/Services.js +++ b/src/src/services/Services.js @@ -15,10 +15,32 @@ class Services { * @throws Will throw an error if the request fails. */ async getAllWeatherStations() { - const url = `/geographic/${COUNTRY_ID}/WeatherStations/json`; + const url = `/geographic/${COUNTRY_ID}/json`; try { const response = await apiClient.get(url); - return response.data; + const data = response.data; + + // Flatten the response to extract the weather stations + const weatherStations = []; + + data.forEach((state) => { + const stateName = state.name; + + state.municipalities.forEach((municipality) => { + const municipalityName = municipality.name; + + municipality.weather_stations.forEach((station) => { + // Add municipality and state to each weather station + weatherStations.push({ + ...station, + municipality: municipalityName, + state: stateName, + }); + }); + }); + }); + + return weatherStations; } catch (error) { console.error("Error fetching weather stations:", error); throw new Error(