finished meteorologia and main dashboard
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import type { WeatherForecastResponse } from "../../../types/weather";
|
||||
|
||||
const BACKEND_URL = "http://localhost:18450";
|
||||
|
||||
type LocationState = {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
|
||||
export function useWeatherForecast() {
|
||||
const [forecast, setForecast] = useState<WeatherForecastResponse | null>(null);
|
||||
const [location, setLocation] = useState<LocationState | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!navigator.geolocation) {
|
||||
setError("Geolocalização não suportada.");
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(position) => {
|
||||
setLocation({
|
||||
latitude: position.coords.latitude,
|
||||
longitude: position.coords.longitude,
|
||||
});
|
||||
},
|
||||
() => {
|
||||
// Fallback Leiria
|
||||
setLocation({
|
||||
latitude: 39.75,
|
||||
longitude: -8.8,
|
||||
});
|
||||
},
|
||||
{
|
||||
enableHighAccuracy: false,
|
||||
timeout: 8000,
|
||||
maximumAge: 1000 * 60 * 60 * 12,
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!location) return;
|
||||
|
||||
const latitude = location.latitude;
|
||||
const longitude = location.longitude;
|
||||
|
||||
const controller = new AbortController();
|
||||
|
||||
async function loadForecast() {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const params = new URLSearchParams({
|
||||
lat: String(latitude),
|
||||
lon: String(longitude),
|
||||
days: "7",
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
`${BACKEND_URL}/api/weather/forecast?${params.toString()}`,
|
||||
{ signal: controller.signal },
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to load weather forecast");
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as WeatherForecastResponse;
|
||||
setForecast(payload);
|
||||
} catch (error) {
|
||||
if (controller.signal.aborted) return;
|
||||
|
||||
console.error("Failed to load weather forecast", error);
|
||||
setError("Não foi possível carregar a previsão meteorológica.");
|
||||
setForecast(null);
|
||||
} finally {
|
||||
if (!controller.signal.aborted) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadForecast();
|
||||
|
||||
return () => controller.abort();
|
||||
}, [location]);
|
||||
|
||||
return {
|
||||
forecast,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user