Files
bodenfeuchte/app/page.tsx
T
2026-05-15 19:05:10 +02:00

107 lines
3.1 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
} from 'recharts';
type Measurement = {
timestamp: number;
soil_moisture: number;
};
function formatTime(ts: number): string {
return new Date(ts).toLocaleTimeString('de-DE', {
hour: '2-digit',
minute: '2-digit',
});
}
export default function Home() {
const [data, setData] = useState<Measurement[]>([]);
const [lastUpdate, setLastUpdate] = useState<string>('');
const fetchData = async () => {
const res = await fetch('/bodenfeuchte/api/data');
const json: Measurement[] = await res.json();
setData(json);
setLastUpdate(new Date().toLocaleTimeString('de-DE'));
};
useEffect(() => {
fetchData();
const interval = setInterval(fetchData, 60_000);
return () => clearInterval(interval);
}, []);
const latest = data.at(-1);
return (
<main className="min-h-screen bg-gray-950 text-gray-100 p-8">
<h1 className="text-2xl font-semibold mb-1">Bodenfeuchte</h1>
<p className="text-sm text-gray-400 mb-6">
Letzte 6 Stunden · Aktualisierung: {lastUpdate || '…'}
</p>
{latest && (
<div className="mb-8 inline-block bg-gray-800 rounded-xl px-6 py-4">
<span className="text-5xl font-bold text-green-400">
{latest.soil_moisture.toFixed(1)}
</span>
<span className="text-2xl text-gray-400 ml-2">%</span>
<p className="text-xs text-gray-500 mt-1">
{formatTime(latest.timestamp)} Uhr
</p>
</div>
)}
<div className="bg-gray-900 rounded-2xl p-4" style={{ height: 360 }}>
{data.length === 0 ? (
<div className="flex items-center justify-center h-full text-gray-500">
Noch keine Daten vorhanden
</div>
) : (
<ResponsiveContainer width="100%" height="100%">
<LineChart data={data} margin={{ top: 8, right: 16, bottom: 8, left: 0 }}>
<CartesianGrid strokeDasharray="3 3" stroke="#374151" />
<XAxis
dataKey="timestamp"
tickFormatter={formatTime}
stroke="#6b7280"
tick={{ fontSize: 12 }}
minTickGap={40}
/>
<YAxis
domain={[0, 100]}
unit="%"
stroke="#6b7280"
tick={{ fontSize: 12 }}
width={45}
/>
<Tooltip
formatter={(v) => [`${Number(v).toFixed(1)} %`, 'Bodenfeuchte']}
labelFormatter={(ts) => formatTime(Number(ts))}
contentStyle={{ background: '#1f2937', border: 'none', borderRadius: 8 }}
/>
<Line
type="monotone"
dataKey="soil_moisture"
stroke="#4ade80"
strokeWidth={2}
dot={false}
activeDot={{ r: 4 }}
/>
</LineChart>
</ResponsiveContainer>
)}
</div>
</main>
);
}