166 lines
5.1 KiB
JavaScript
166 lines
5.1 KiB
JavaScript
import { useState, useEffect } from 'react'
|
|
import WeatherDashboard from './components/WeatherDashboard'
|
|
import './App.css'
|
|
|
|
function App() {
|
|
const [weatherData, setWeatherData] = useState([])
|
|
const [currentWeatherData, setCurrentWeatherData] = useState([]) // Immer die aktuellen 24h-Werte
|
|
const [rainData, setRainData] = useState([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState(null)
|
|
const [lastUpdate, setLastUpdate] = useState(null)
|
|
const [timeRange, setTimeRange] = useState('24h') // '24h', '7d', '30d', '365d'
|
|
|
|
useEffect(() => {
|
|
const fetchData = async () => {
|
|
try {
|
|
setLoading(true)
|
|
|
|
// Prüfe ob eingebettete Daten vorhanden sind (statischer Build)
|
|
if (window.__WEATHER_DATA__ && timeRange === '24h') {
|
|
setWeatherData(window.__WEATHER_DATA__)
|
|
setCurrentWeatherData(window.__WEATHER_DATA__)
|
|
setRainData([])
|
|
setLastUpdate(new Date())
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
// API-URLs basierend auf Zeitraum
|
|
let weatherUrl, rainUrl
|
|
const baseUrl = import.meta.env.DEV ? 'http://localhost:8000' : '/api'
|
|
|
|
switch (timeRange) {
|
|
case '24h':
|
|
weatherUrl = `${baseUrl}/weather/history?hours=24`
|
|
rainUrl = null
|
|
break
|
|
case '7d':
|
|
weatherUrl = `${baseUrl}/weather/hourly-aggregated?days=7`
|
|
rainUrl = `${baseUrl}/weather/rain-daily?days=7`
|
|
break
|
|
case '30d':
|
|
weatherUrl = `${baseUrl}/weather/daily-with-minmax?days=30`
|
|
rainUrl = `${baseUrl}/weather/rain-daily?days=30`
|
|
break
|
|
case '365d':
|
|
weatherUrl = `${baseUrl}/weather/daily-aggregated?days=365`
|
|
rainUrl = `${baseUrl}/weather/rain-weekly?days=365`
|
|
break
|
|
default:
|
|
weatherUrl = `${baseUrl}/weather/history?hours=24`
|
|
rainUrl = null
|
|
}
|
|
|
|
// Wetterdaten laden
|
|
const weatherResponse = await fetch(weatherUrl)
|
|
if (!weatherResponse.ok) {
|
|
throw new Error('API-Fehler: ' + weatherResponse.status)
|
|
}
|
|
const weatherDataResult = await weatherResponse.json()
|
|
setWeatherData(weatherDataResult)
|
|
|
|
// Immer die aktuellen 24h-Daten für "Aktuell"-Anzeige laden
|
|
if (timeRange !== '24h') {
|
|
const currentUrl = `${baseUrl}/weather/history?hours=24`
|
|
const currentResponse = await fetch(currentUrl)
|
|
if (currentResponse.ok) {
|
|
const currentDataResult = await currentResponse.json()
|
|
setCurrentWeatherData(currentDataResult)
|
|
}
|
|
} else {
|
|
setCurrentWeatherData(weatherDataResult)
|
|
}
|
|
|
|
// Regendaten laden (falls separater Endpunkt)
|
|
if (rainUrl) {
|
|
const rainResponse = await fetch(rainUrl)
|
|
if (rainResponse.ok) {
|
|
const rainDataResult = await rainResponse.json()
|
|
setRainData(rainDataResult)
|
|
}
|
|
} else {
|
|
setRainData([])
|
|
}
|
|
|
|
setLastUpdate(new Date())
|
|
setLoading(false)
|
|
} catch (err) {
|
|
setError(err.message)
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
fetchData()
|
|
|
|
// Automatisches Update alle 5 Minuten (nur für 24h und ohne statische Daten)
|
|
if (!window.__WEATHER_DATA__ && timeRange === '24h') {
|
|
const interval = setInterval(fetchData, 5 * 60 * 1000)
|
|
return () => clearInterval(interval)
|
|
}
|
|
}, [timeRange])
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="loading-container">
|
|
<div className="loading-spinner"></div>
|
|
<p>Lade Wetterdaten...</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="error-container">
|
|
<h2>Fehler beim Laden der Daten</h2>
|
|
<p>{error}</p>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
// Aktuelle Zeit formatieren
|
|
const now = new Date()
|
|
const dateStr = now.toLocaleDateString('de-DE', {
|
|
weekday: 'long',
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric'
|
|
})
|
|
const timeStr = now.toLocaleTimeString('de-DE', {
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
})
|
|
|
|
// TODO: Sonnenauf-/untergang und Mondphase berechnen
|
|
// Aktuell Platzhalter - benötigt Bibliothek wie 'suncalc'
|
|
const sunrise = "06:45"
|
|
const sunset = "18:30"
|
|
const moonPhase = "abnehmend 50%"
|
|
|
|
return (
|
|
<div className="app">
|
|
<header className="app-header">
|
|
<h1>Aktuelle Wetterdaten</h1>
|
|
<div className="header-datetime">{dateStr} - {timeStr} Uhr</div>
|
|
<div className="header-spacer"></div>
|
|
<div className="header-coordinates">48.6 N - 9.6 E - 574 m NN</div>
|
|
<div className="header-astro">
|
|
Sonnen-Aufgang: {sunrise} - Untergang: {sunset} Mond-Phase: {moonPhase}
|
|
</div>
|
|
</header>
|
|
|
|
<main className="app-main">
|
|
<WeatherDashboard
|
|
data={weatherData}
|
|
currentData={currentWeatherData}
|
|
rainData={rainData}
|
|
timeRange={timeRange}
|
|
onTimeRangeChange={setTimeRange}
|
|
/>
|
|
</main>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default App
|