"use client"; // /components/main/system/DetailModal.tsx import React, { useEffect, useRef, useState } from "react"; import { Line } from "react-chartjs-2"; import { useSelector } from "react-redux"; import { RootState, useAppDispatch } from "@/redux/store"; import { Listbox } from "@headlessui/react"; import { setFullScreen } from "@/redux/slices/kabelueberwachungChartSlice"; import DateRangePicker from "@/components/common/DateRangePicker"; import { setVonDatum, setBisDatum, } from "@/redux/slices/kabelueberwachungChartSlice"; // Import Thunks import { getSystemspannung5VplusThunk } from "@/redux/thunks/getSystemspannung5VplusThunk"; import { getSystemspannung15VplusThunk } from "@/redux/thunks/getSystemspannung15VplusThunk"; import { getSystemspannung15VminusThunk } from "@/redux/thunks/getSystemspannung15VminusThunk"; import { getSystemspannung98VminusThunk } from "@/redux/thunks/getSystemspannung98VminusThunk"; import { getTemperaturAdWandlerThunk } from "@/redux/thunks/getTemperaturAdWandlerThunk"; import { getTemperaturProzessorThunk } from "@/redux/thunks/getTemperaturProzessorThunk"; import { Chart as ChartJS, LineElement, PointElement, CategoryScale, LinearScale, Title, Tooltip, Legend, Filler, TimeScale, } from "chart.js"; import "chartjs-adapter-date-fns"; import { de } from "date-fns/locale"; ChartJS.register( LineElement, PointElement, CategoryScale, LinearScale, Title, Tooltip, Legend, Filler, TimeScale ); type ReduxDataEntry = { //Alle DIA0 t,m,i,a , DIA1 und DIA2 t,i,a,g t: string; // Zeitstempel i: number; // Minimum a: number; // Maximum g?: number; // Durchschnitt (optional, falls vorhanden) m?: number; // aktueller Messwert (optional, falls vorhanden) }; const chartOptions = { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: "top" as const }, title: { display: true, text: "Verlauf", }, tooltip: { mode: "index" as const, intersect: false, callbacks: { label: function (ctx: any) { return `Messwert: ${ctx.parsed.y}`; }, title: function (items: any[]) { const date = items[0].parsed.x; return `Zeitpunkt: ${new Date(date).toLocaleString("de-DE")}`; }, }, }, zoom: { pan: { enabled: true, mode: "x" as const }, zoom: { wheel: { enabled: true }, pinch: { enabled: true }, mode: "x" as const, }, }, }, scales: { x: { type: "time" as const, time: { unit: "day" as const, tooltipFormat: "dd.MM.yyyy HH:mm", displayFormats: { day: "dd.MM.yyyy", }, }, adapters: { date: { locale: de }, }, title: { display: true, text: "Zeit", }, }, y: { title: { display: true, text: "Messwert", }, }, }, }; type Props = { isOpen: boolean; selectedKey: string | null; onClose: () => void; zeitraum: "DIA0" | "DIA1" | "DIA2"; setZeitraum: (typ: "DIA0" | "DIA1" | "DIA2") => void; }; export const DetailModal = ({ isOpen, selectedKey, onClose, zeitraum, setZeitraum, }: Props) => { const chartRef = useRef(null); const [chartData, setChartData] = useState({ datasets: [], }); const [isLoading, setIsLoading] = useState(false); const [shouldUpdateChart, setShouldUpdateChart] = useState(false); const vonDatum = useSelector( (state: RootState) => state.kabelueberwachungChartSlice.vonDatum ); const bisDatum = useSelector( (state: RootState) => state.kabelueberwachungChartSlice.bisDatum ); const [filteredData, setFilteredData] = useState([]); const reduxData = useSelector((state: RootState) => { switch (selectedKey) { case "+5V": return state.systemspannung5Vplus[zeitraum]; case "+15V": return state.systemspannung15Vplus[zeitraum]; case "-15V": return state.systemspannung15Vminus[zeitraum]; case "-98V": return state.systemspannung98Vminus[zeitraum]; case "ADC Temp": return state.temperaturAdWandler[zeitraum]; case "CPU Temp": return state.temperaturProzessor[zeitraum]; default: return []; } }) as ReduxDataEntry[]; const isFullScreen = useSelector( (state: RootState) => state.kabelueberwachungChartSlice.isFullScreen ); const dispatch = useAppDispatch(); const toggleFullScreen = () => { dispatch(setFullScreen(!isFullScreen)); setTimeout(() => { chartRef.current?.resize(); }, 50); }; const handleClose = () => { dispatch(setFullScreen(false)); dispatch(setVonDatum("")); dispatch(setBisDatum("")); onClose(); }; useEffect(() => { const loadZoomPlugin = async () => { if (typeof window !== "undefined") { const zoomPlugin = (await import("chartjs-plugin-zoom")).default; if (!ChartJS.registry.plugins.get("zoom")) { ChartJS.register(zoomPlugin); } } }; loadZoomPlugin(); }, []); // API-Request beim Klick auf "Daten laden" const handleFetchData = () => { setIsLoading(true); // Clear previous chart data setChartData({ datasets: [] }); // Flag setzen, dass Chart nach Datenempfang aktualisiert werden soll setShouldUpdateChart(true); switch (selectedKey) { case "+5V": dispatch(getSystemspannung5VplusThunk(zeitraum)); break; case "+15V": dispatch(getSystemspannung15VplusThunk(zeitraum)); break; case "-15V": dispatch(getSystemspannung15VminusThunk(zeitraum)); break; case "-98V": dispatch(getSystemspannung98VminusThunk(zeitraum)); break; case "ADC Temp": dispatch(getTemperaturAdWandlerThunk(zeitraum)); break; case "CPU Temp": dispatch(getTemperaturProzessorThunk(zeitraum)); break; default: break; } }; useEffect(() => { if (chartRef.current && selectedKey) { chartRef.current.options.plugins.title.text = `Verlauf ${selectedKey}`; chartRef.current.update("none"); } }, [selectedKey]); useEffect(() => { if (chartRef.current) { chartRef.current.resetZoom(); } }, [zeitraum]); // Chart.js animation complete callback to set isLoading false useEffect(() => { if (chartRef.current && isLoading) { const chartInstance = chartRef.current; // Save previous callback to restore later const prevCallback = chartInstance.options.animation?.onComplete; chartInstance.options.animation = { ...chartInstance.options.animation, onComplete: () => { setIsLoading(false); if (typeof prevCallback === "function") prevCallback(); }, }; chartInstance.update(); } }, [chartData, isLoading]); // Update chart data when Redux data changes (only after button click) useEffect(() => { if (shouldUpdateChart && reduxData && reduxData.length > 0) { console.log("Redux data for chart:", reduxData); // Convert Redux data to Chart.js format const chartDataPoints = reduxData.map((entry) => ({ x: new Date(entry.t).getTime(), y: entry.m || entry.a || entry.i || 0, // Use current value, max, min, or 0 })); const newChartData = { datasets: [ { label: selectedKey || "Messwerte", data: chartDataPoints, borderColor: "#00AEEF", // littwin-blue backgroundColor: "rgba(0, 174, 239, 0.2)", // littwin-blue mit Transparenz tension: 0.1, fill: false, }, ], }; console.log("Chart data points:", chartDataPoints); setChartData(newChartData); setShouldUpdateChart(false); // Reset flag } else if (shouldUpdateChart && (!reduxData || reduxData.length === 0)) { console.log("No Redux data available"); setChartData({ datasets: [] }); setShouldUpdateChart(false); // Reset flag } }, [reduxData, selectedKey, shouldUpdateChart]); if (!isOpen || !selectedKey) return null; return (

Detailansicht: {selectedKey}

{ { DIA0: "Alle Messwerte", DIA1: "Stündlich", DIA2: "Täglich", }[zeitraum] } {["DIA0", "DIA1", "DIA2"].map((option) => ( `px-4 py-1 cursor-pointer ${ selected ? "bg-littwin-blue text-white" : active ? "bg-gray-200" : "" }` } > { { DIA0: "Alle Messwerte", DIA1: "Stündlich", DIA2: "Täglich", }[option] } ))}
); };