182 lines
5.5 KiB
TypeScript
182 lines
5.5 KiB
TypeScript
"use client"; // KVZChartView.tsx
|
||
|
||
import React, { useEffect } from "react";
|
||
import DateRangePicker from "@/components/common/DateRangePicker";
|
||
import { getMessagesThunk } from "@/redux/thunks/getMessagesThunk";
|
||
import { setLoading } from "@/redux/slices/kabelueberwachungChartSlice";
|
||
import ReactModal from "react-modal";
|
||
import { useDispatch, useSelector } from "react-redux";
|
||
import { AppDispatch, RootState } from "@/redux/store";
|
||
import {
|
||
setChartOpen,
|
||
setFullScreen,
|
||
setSlotNumber,
|
||
setVonDatum,
|
||
setBisDatum,
|
||
setSelectedMode,
|
||
setSelectedSlotType,
|
||
} from "@/redux/slices/kabelueberwachungChartSlice";
|
||
import { resetBrushRange } from "@/redux/slices/brushSlice";
|
||
import FallSensors from "../../../../fall-detection-sensors/FallSensors";
|
||
import Report from "../IsoMeasurementChart/Report";
|
||
|
||
interface KVZChartViewProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
slotIndex: number;
|
||
}
|
||
|
||
// Modal zur Anzeige der KVz Zustände (Sturzsensoren / Fall Detection LEDs)
|
||
// Stil und Verhalten analog zu ISO / RSL / TDR Modals
|
||
const KVZChartView: React.FC<KVZChartViewProps> = ({
|
||
isOpen,
|
||
onClose,
|
||
slotIndex,
|
||
}) => {
|
||
const dispatch = useDispatch<AppDispatch>();
|
||
const { isFullScreen, slotNumber, vonDatum, bisDatum } = useSelector(
|
||
(state: RootState) => state.kabelueberwachungChartSlice
|
||
);
|
||
const { vonDatum: pickerVonDatum, bisDatum: pickerBisDatum } = useSelector(
|
||
(state: RootState) => state.dateRangePicker
|
||
);
|
||
|
||
// Beim Öffnen Slot setzen (damit konsistent zu anderen Modals)
|
||
useEffect(() => {
|
||
if (isOpen) {
|
||
dispatch(setSlotNumber(slotIndex));
|
||
}
|
||
}, [isOpen, slotIndex, dispatch]);
|
||
|
||
const handleClose = () => {
|
||
const today = new Date();
|
||
const thirtyDaysAgo = new Date();
|
||
thirtyDaysAgo.setDate(today.getDate() - 30);
|
||
const toISO = (d: Date) => d.toLocaleDateString("sv-SE");
|
||
|
||
// Zurücksetzen – entspricht Verhalten der anderen Modals
|
||
dispatch(setVonDatum(toISO(thirtyDaysAgo)));
|
||
dispatch(setBisDatum(toISO(today)));
|
||
dispatch(setSelectedMode("DIA1"));
|
||
dispatch(setSelectedSlotType("isolationswiderstand"));
|
||
dispatch(setChartOpen(false));
|
||
dispatch(setFullScreen(false));
|
||
dispatch(resetBrushRange());
|
||
|
||
onClose();
|
||
};
|
||
|
||
const toggleFullScreen = () => dispatch(setFullScreen(!isFullScreen));
|
||
|
||
const handleFetchMessages = async () => {
|
||
const fromDate = pickerVonDatum ?? vonDatum;
|
||
const toDate = pickerBisDatum ?? bisDatum;
|
||
try {
|
||
dispatch(setLoading(true));
|
||
await dispatch(getMessagesThunk({ fromDate, toDate })).unwrap();
|
||
} catch (err) {
|
||
console.error("❌ Fehler beim Laden der Meldungen (KVZ)", err);
|
||
} finally {
|
||
dispatch(setLoading(false));
|
||
}
|
||
};
|
||
|
||
return (
|
||
<ReactModal
|
||
isOpen={isOpen}
|
||
onRequestClose={handleClose}
|
||
ariaHideApp={false}
|
||
style={{
|
||
overlay: { backgroundColor: "rgba(0, 0, 0, 0.5)" },
|
||
content: {
|
||
top: "50%",
|
||
left: "50%",
|
||
bottom: "auto",
|
||
marginRight: "-50%",
|
||
transform: "translate(-50%, -50%)",
|
||
width: isFullScreen ? "90vw" : "60rem",
|
||
height: isFullScreen ? "90vh" : "32rem",
|
||
padding: "1rem",
|
||
transition: "all 0.3s ease-in-out",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
overflowX: "hidden",
|
||
},
|
||
}}
|
||
>
|
||
{/* Action Buttons */}
|
||
<div
|
||
style={{
|
||
position: "absolute",
|
||
top: "0.625rem",
|
||
right: "0.625rem",
|
||
display: "flex",
|
||
gap: "0.75rem",
|
||
}}
|
||
>
|
||
<button
|
||
onClick={toggleFullScreen}
|
||
style={{
|
||
background: "transparent",
|
||
border: "none",
|
||
fontSize: "1.5rem",
|
||
cursor: "pointer",
|
||
}}
|
||
>
|
||
<i
|
||
className={
|
||
isFullScreen ? "bi bi-fullscreen-exit" : "bi bi-arrows-fullscreen"
|
||
}
|
||
></i>
|
||
</button>
|
||
<button
|
||
onClick={handleClose}
|
||
style={{
|
||
background: "transparent",
|
||
border: "none",
|
||
fontSize: "1.5rem",
|
||
cursor: "pointer",
|
||
}}
|
||
>
|
||
<i className="bi bi-x-circle-fill"></i>
|
||
</button>
|
||
</div>
|
||
|
||
{/* Content */}
|
||
<div className="flex flex-col h-full">
|
||
<h3 className="text-lg font-semibold mb-1">KVz Zustände & Meldungen</h3>
|
||
|
||
{/* Toolbar mit KÜ + DateRangePicker + Sensoren (analog zu anderen Modalen) */}
|
||
<div className="w-full flex flex-wrap items-center gap-4 mb-4">
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-xs font-semibold opacity-80 select-none">
|
||
KÜ {slotNumber !== null ? slotNumber + 1 : "-"}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center gap-3 flex-1 min-w-[20rem]">
|
||
<div className="relative z-[1500]">
|
||
<DateRangePicker />
|
||
</div>
|
||
<button
|
||
type="button"
|
||
onClick={handleFetchMessages}
|
||
className="btn-primary h-8 font-medium px-4"
|
||
>
|
||
Anzeigen
|
||
</button>
|
||
</div>
|
||
<div className="flex items-center justify-end" style={{ width: "12rem" }}>
|
||
<FallSensors slotIndex={slotIndex} />
|
||
</div>
|
||
</div>
|
||
{/* Meldungen Bereich */}
|
||
<div className="flex-1 border rounded bg-white overflow-hidden">
|
||
<Report moduleType="KVZ" />
|
||
</div>
|
||
</div>
|
||
</ReactModal>
|
||
);
|
||
};
|
||
|
||
export default KVZChartView;
|