Files
CPLv4.0/components/main/einausgaenge/modals/OutputModal.tsx
2025-05-01 18:49:19 +02:00

122 lines
3.7 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.

This file contains Unicode characters that might be confused with other characters. 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/OutputModal.tsx
import React, { useState } from "react";
import { useSelector } from "react-redux";
import { RootState } from "../../../../redux/store";
export default function OutputModal({
selectedOutput,
closeOutputModal,
isOpen,
}: {
selectedOutput: any;
closeOutputModal: () => void;
isOpen: boolean;
}) {
const allOutputs = useSelector(
(state: RootState) => state.digitalOutputsSlice.outputs
);
const [label, setLabel] = useState(selectedOutput.label || "");
const [status, setStatus] = useState(selectedOutput.status || false);
const [timer, setTimer] = useState(0);
const [isSaving, setIsSaving] = useState(false);
const [errorMsg, setErrorMsg] = useState("");
if (!isOpen || !selectedOutput) return null;
const handleSave = async () => {
setIsSaving(true);
setErrorMsg("");
const updatedOutputs = allOutputs.map((output) =>
output.id === selectedOutput.id ? { ...output, label, status } : output
);
try {
const res = await fetch("/api/cpl/updateDigitalOutputs", {
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("✅ Änderungen gespeichert");
closeOutputModal();
}
} catch (err) {
setErrorMsg("❌ Netzwerkfehler beim Speichern.");
} finally {
setIsSaving(false);
}
};
return (
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
<div className="bg-white rounded-lg shadow-lg p-6 w-full max-w-md">
<h2 className="text-xl font-bold mb-4 text-littwin-blue">
Ausgang {selectedOutput.id} Konfiguration
</h2>
<div className="mb-4">
<label className="block font-semibold mb-1">Bezeichnung</label>
<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>
<div className="mb-4 flex items-center justify-between">
<label className="font-semibold">Status</label>
<button
onClick={() => setStatus(!status)}
className={`px-3 py-1 rounded text-white font-medium ${
status ? "bg-green-600" : "bg-gray-400"
}`}
>
{status ? "EIN" : "AUS"}
</button>
</div>
<div className="mb-4">
<label className="block font-semibold mb-1">
Timer (Sekunden, optional)
</label>
<input
type="number"
min={0}
value={timer}
onChange={(e) => setTimer(parseInt(e.target.value))}
className="w-full border border-gray-300 rounded px-3 py-2"
placeholder="z.B. 5 für 5 Sekunden"
/>
</div>
{errorMsg && <p className="text-red-600 text-sm mb-2">{errorMsg}</p>}
<div className="flex justify-end gap-2 mt-6">
<button
onClick={closeOutputModal}
disabled={isSaving}
className="px-4 py-2 rounded bg-gray-300 hover:bg-gray-400"
>
Abbrechen
</button>
<button
onClick={handleSave}
disabled={isSaving}
className="px-4 py-2 rounded bg-blue-600 hover:bg-blue-700 text-white"
>
{isSaving ? "Speichern..." : "Speichern"}
</button>
</div>
</div>
</div>
);
}