'use client'; import { useState, useEffect, useCallback } from 'react'; import AppLayout from '@/components/AppLayout'; import BarChart from '@/components/BarChart'; import { VerbrauchPoint, Every, RangeKey } from '@/types/strom'; const COLOR_24H = '#2980b9'; const COLOR_7D = '#27ae60'; const COLOR_31D = '#e67e22'; const COLOR_365D = '#8e44ad'; type SelectorKind = 'date24' | 'date' | 'month' | 'year'; function todayStr(): string { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; } function thisMonthStr(): string { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`; } const CURRENT_YEAR = new Date().getFullYear(); const YEARS = Array.from({ length: 11 }, (_, i) => CURRENT_YEAR - i); interface ChartCardProps { range: RangeKey; every: Every; title: string; color: string; selector: SelectorKind; } function ChartCard({ range, every, title, color, selector }: ChartCardProps) { const [value, setValue] = useState(() => { switch (selector) { case 'date24': return ''; // leer = rollierend letzte 24h case 'date': return todayStr(); case 'month': return thisMonthStr(); case 'year': return String(CURRENT_YEAR); } }); const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const fetchData = useCallback( async (sel: string) => { setIsLoading(true); setError(null); try { const params = new URLSearchParams({ range }); if (selector === 'date24' && sel) params.set('date', sel); if (selector === 'date') params.set('date', sel); if (selector === 'month') params.set('month', sel); if (selector === 'year') params.set('year', sel); const res = await fetch(`/api/verbrauch?${params.toString()}`, { cache: 'no-store', headers: { 'Cache-Control': 'no-cache' }, }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const json = await res.json(); if (json.success) { setData(json.data); } else { setError(json.error || 'Fehler beim Laden der Daten.'); } } catch { setError('Netzwerkfehler.'); } finally { setIsLoading(false); } }, [range, selector] ); useEffect(() => { fetchData(value); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Jahres-Chart: Achse immer ueber das komplette Kalenderjahr -> alle 12 Monate // sichtbar, Restmonate bleiben ohne Balken. let xMin: number | undefined; let xMax: number | undefined; if (range === '365d') { const y = Number(value); if (Number.isFinite(y)) { xMin = new Date(y, 0, 1).getTime(); // bis Ende Dezember -> Januar des Folgejahres wird nicht mehr angezeigt xMax = new Date(y + 1, 0, 1).getTime() - 1; } } // Gesamtverbrauch des angezeigten Zeitraums const total = data.reduce((sum, [, v]) => sum + v, 0); const totalLabel = range === '365d' ? `Gesamtverbrauch ${value}` : 'Gesamtverbrauch'; return (
{/* Steuerung */}
{selector === 'year' ? ( ) : ( setValue(e.target.value)} className="border border-gray-400 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-gray-500" /> )}
{error && {error}} {!isLoading && !error && data.length === 0 && ( Keine Daten im gewählten Zeitraum. )}
{/* Diagramm */} {isLoading ? (
Lade Daten…
) : ( <> {data.length > 0 && (
{totalLabel}:{' '} {total.toLocaleString('de-DE', { minimumFractionDigits: 1, maximumFractionDigits: 1 })} kWh
)} )}
); } export default function VerbrauchCharts() { return ( ); }