Files
CPLv4.0/components/main/einausgaenge/modals/DigitalOutputsModal.tsx
Ismail Ali b9651a53a9 esLint
2025-06-26 22:56:20 +02:00

139 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"; // /components/main/einausgaenge/modals/DigitalOutputsModal.tsx
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { RootState } from "../../../../redux/store";
import type { DigitalOutput } from "@/types/digitalOutput";
export default function DigitalOutputsModal({
selectedOutput,
closeOutputModal,
isOpen,
}: {
selectedOutput: DigitalOutput | null;
closeOutputModal: () => void;
isOpen: boolean;
}) {
const allOutputs = useSelector(
(state: RootState) => state.digitalOutputsSlice.outputs
);
const [label, setLabel] = useState("");
const [status, setStatus] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const [errorMsg, setErrorMsg] = useState("");
// ✅ Zustand neu setzen, wenn Modal geöffnet oder anderer Ausgang ausgewählt wird
useEffect(() => {
if (isOpen && selectedOutput) {
setLabel(selectedOutput.label || "");
setStatus(selectedOutput.status || false);
setErrorMsg("");
}
}, [isOpen, selectedOutput]);
if (!isOpen || !selectedOutput) return null;
const handleSave = async () => {
setIsSaving(true);
setErrorMsg("");
const updatedOutputs = allOutputs.map((output) =>
output.id === selectedOutput.id
? { ...output, label: label.trim(), status }
: output
);
const isCPL = process.env.NEXT_PUBLIC_NODE_ENV === "production";
try {
if (isCPL) {
// ✅ Name speichern (DANx=...)
const nameEncoded = encodeURIComponent(label.trim());
const nameUrl = `/CPL?digitalOutputs.html&DAN0${selectedOutput.id}=${nameEncoded}`;
// ✅ Status speichern (DASx=...)
const statusUrl = `/CPL?digitalOutputs.html&DAS0${selectedOutput.id}=${
status ? 1 : 0
}`;
// 🟢 Beide nacheinander senden (wichtig bei älteren CPL-Versionen)
window.location.href = nameUrl; // Name zuerst (ggf. durch Refresh überschrieben)
setTimeout(() => {
window.location.href = statusUrl;
}, 300); // kleine Verzögerung (optional)
// 💡 Modal wird nicht automatisch geschlossen — da Seite neu lädt.
} else {
// 🧪 Lokaler Entwicklungsmodus
const res = await fetch("/api/cpl/updateDigitalOutputsHandler", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ outputs: updatedOutputs }),
});
if (!res.ok) {
const err = await res.json();
setErrorMsg(err?.error || "Fehler beim Speichern.");
} else {
console.log(
"✅ Status & Label gespeichert für Ausgang",
selectedOutput.id
);
closeOutputModal();
}
}
} catch (err) {
console.error("Fehler beim Speichern:", err);
setErrorMsg("❌ Fehler beim Speichern.");
} finally {
setIsSaving(false);
}
};
return (
<div className="fixed top-0 left-0 w-full h-full bg-black bg-opacity-50 flex justify-center items-center z-50">
<div className="bg-white rounded-lg shadow-lg p-6 w-1/2 max-w-lg">
<div className="mb-4 border-b pb-2 flex justify-between items-center">
<h2 className="text-base font-bold">
Einstellungen Schaltausgang {selectedOutput.id}
</h2>
<button
onClick={closeOutputModal}
className="text-2xl hover:text-gray-400"
aria-label="Modal schließen"
>
<i className="bi bi-x-circle-fill"></i>
</button>
</div>
<div className="grid grid-cols-2 gap-x-4 gap-y-3">
<div>
<span className="font-normal">Bezeichnung:</span>
</div>
<input
type="text"
value={label}
onChange={(e) => setLabel(e.target.value)}
className="w-full border border-gray-300 rounded px-3 py-2"
placeholder="z.B. Licht Relais 1"
/>
</div>
{errorMsg && <p className="text-red-600 text-sm mb-2">{errorMsg}</p>}
<div className="flex justify-end gap-2 mt-6">
<button
onClick={handleSave}
disabled={isSaving}
className="bg-littwin-blue text-white px-4 py-2 rounded flex items-center"
>
{isSaving ? "Speichern..." : "Speichern"}
</button>
</div>
</div>
</div>
);
}