253 lines
7.9 KiB
TypeScript
253 lines
7.9 KiB
TypeScript
"use client";
|
||
declare global {
|
||
interface Window {
|
||
__tdrCache?: Record<string, { data: any; tdrActive: boolean }>;
|
||
}
|
||
}
|
||
|
||
import React, { useState, useEffect } from "react";
|
||
import { useSelector } from "react-redux";
|
||
import { RootState } from "../../../../../redux/store";
|
||
|
||
interface Props {
|
||
slot: number;
|
||
onClose?: () => void; // ← NEU
|
||
}
|
||
|
||
export default function TdrEinstellung({ slot, onClose }: Props) {
|
||
const tdrSlice = useSelector((state: RootState) => state.kueDataSlice);
|
||
|
||
const cacheKey = `slot_${slot}`;
|
||
if (typeof window !== "undefined") {
|
||
window.__tdrCache = window.__tdrCache || {};
|
||
}
|
||
const cachedTdr =
|
||
typeof window !== "undefined"
|
||
? window.__tdrCache?.[cacheKey] ?? null
|
||
: null;
|
||
|
||
const [tdrData, setTdrData] = useState(
|
||
() =>
|
||
cachedTdr?.data || {
|
||
daempfung: tdrSlice.tdrAtten?.[slot]?.toString() ?? "",
|
||
geschwindigkeit: tdrSlice.tdrSpeed?.[slot]?.toString() ?? "",
|
||
trigger: tdrSlice.tdrTrigger?.[slot]?.toString() ?? "",
|
||
}
|
||
);
|
||
|
||
const [tdrActive, setTdrActive] = useState(
|
||
() => cachedTdr?.tdrActive ?? tdrSlice.tdrActive?.[slot] === 1
|
||
);
|
||
|
||
// Updates in Redux nicht mehr automatisch übernehmen, solange Fenster offen
|
||
|
||
const updateCache = (data: typeof tdrData, active = tdrActive) => {
|
||
if (typeof window !== "undefined") {
|
||
(window.__tdrCache ??= {})[cacheKey] = {
|
||
data,
|
||
tdrActive: active,
|
||
};
|
||
}
|
||
};
|
||
|
||
const handleSave = () => {
|
||
const { daempfung, geschwindigkeit, trigger } = tdrData;
|
||
|
||
if (!daempfung.trim() || !geschwindigkeit.trim() || !trigger.trim()) {
|
||
alert("Bitte alle Felder ausfüllen.");
|
||
return;
|
||
}
|
||
|
||
const isDev = window.location.hostname === "localhost";
|
||
|
||
if (isDev) {
|
||
const updates = [
|
||
{ key: "win_tdrAtten", slot, value: daempfung.trim() },
|
||
{ key: "win_tdrSpeed", slot, value: geschwindigkeit.trim() },
|
||
{ key: "win_tdrTrigger", slot, value: trigger.trim() },
|
||
];
|
||
|
||
fetch("/api/cpl/updateTdrSettingsDataAPIHandler", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ updates }),
|
||
})
|
||
.then((res) => res.json())
|
||
.then(() => {
|
||
alert("TDR-Werte erfolgreich gespeichert.");
|
||
if (typeof onClose === "function") onClose(); // ← MODAL SCHLIESSEN
|
||
})
|
||
.catch((err) => {
|
||
console.error("Fehler beim Speichern:", err);
|
||
alert("Speichern fehlgeschlagen.");
|
||
});
|
||
} else {
|
||
// Originaler Webservice-Teil...
|
||
const base = `${window.location.origin}/CPL?/kabelueberwachung.html`;
|
||
|
||
const urls = [
|
||
`${base}&KTD${slot}=${daempfung.trim()}`,
|
||
`${base}&KTS${slot}=${geschwindigkeit.trim()}`,
|
||
`${base}&KTE${slot}=${trigger.trim()}`,
|
||
];
|
||
|
||
Promise.all(
|
||
urls.map((url) =>
|
||
fetch(url).then((res) => {
|
||
if (!res.ok) throw new Error(`Fehler bei ${url}`);
|
||
return res.text();
|
||
})
|
||
)
|
||
)
|
||
.then(() => {
|
||
alert("TDR-Einstellungen erfolgreich gesendet.");
|
||
if (typeof onClose === "function") onClose(); // ← MODAL SCHLIESSEN
|
||
})
|
||
.catch((err) => {
|
||
console.error("Fehler beim Senden:", err);
|
||
alert("Fehler beim Senden der TDR-Einstellungen.");
|
||
});
|
||
}
|
||
|
||
updateCache(tdrData, tdrActive);
|
||
};
|
||
|
||
const handleTdrToggle = () => {
|
||
const newState = !tdrActive;
|
||
setTdrActive(newState);
|
||
updateCache(tdrData, newState);
|
||
|
||
const isDev = window.location.hostname === "localhost";
|
||
const slotParam = `KTX${slot}=${newState ? 1 : 0}`;
|
||
|
||
const reloadAfterConfirm = () => {
|
||
const msg = newState
|
||
? "✅ TDR wurde aktiviert."
|
||
: "⚠️ TDR wurde deaktiviert.";
|
||
alert(msg);
|
||
location.reload();
|
||
};
|
||
|
||
if (isDev) {
|
||
const updates = [{ key: "win_tdrActive", slot, value: newState ? 1 : 0 }];
|
||
|
||
fetch("/api/cpl/updateTdrSettingsDataAPIHandler", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ updates }),
|
||
})
|
||
.then((res) => res.json())
|
||
.then(() => {
|
||
console.log("TDR-Aktiv-Status gespeichert.");
|
||
reloadAfterConfirm();
|
||
})
|
||
.catch((err) => {
|
||
console.error("Fehler beim Speichern von TDR aktiv:", err);
|
||
});
|
||
} else {
|
||
const url = `${window.location.origin}/CPL?/kabelueberwachung.html&${slotParam}`;
|
||
fetch(url)
|
||
.then((res) => {
|
||
if (!res.ok) throw new Error("TDR-Befehl fehlgeschlagen");
|
||
console.log("TDR aktiviert/deaktiviert:", res.status);
|
||
reloadAfterConfirm();
|
||
})
|
||
.catch((err) => {
|
||
console.error("Fehler beim TDR-Befehl:", err);
|
||
alert("Fehler beim Umschalten der TDR-Funktion.");
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="space-y-4 text-sm laptop:text-base">
|
||
<h2 className="text-base laptop:text-lg font-semibold">
|
||
TDR-Einstellung – Steckplatz {slot + 1}
|
||
</h2>
|
||
|
||
<div className="flex items-center gap-3">
|
||
<span className="text-sm font-medium">TDR-Funktion:</span>
|
||
<button
|
||
type="button"
|
||
role="switch"
|
||
aria-checked={tdrActive}
|
||
onClick={handleTdrToggle}
|
||
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ${
|
||
tdrActive ? "bg-littwin-blue" : "bg-gray-300"
|
||
}`}
|
||
>
|
||
<span
|
||
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform duration-200 ${
|
||
tdrActive ? "translate-x-6" : "translate-x-1"
|
||
}`}
|
||
/>
|
||
</button>
|
||
<span className="text-sm text-gray-600">
|
||
{tdrActive ? "aktiviert" : "deaktiviert"}
|
||
</span>
|
||
</div>
|
||
|
||
<div className="mt-6 mb-4">
|
||
<h3 className="font-bold mb-2">TDR Einstellungen</h3>
|
||
|
||
<div className="mb-4 grid grid-cols-2 items-center gap-2 w-full">
|
||
<label className="font-semibold">TDR Dämpfung</label>
|
||
<div className="flex items-center gap-2">
|
||
<input
|
||
type="number"
|
||
className="w-24 border rounded p-1"
|
||
value={tdrData.daempfung}
|
||
onChange={(e) => {
|
||
const updated = { ...tdrData, daempfung: e.target.value };
|
||
setTdrData(updated);
|
||
updateCache(updated);
|
||
}}
|
||
/>
|
||
<span>dB</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mb-4 grid grid-cols-2 items-center gap-2 w-full">
|
||
<label className="font-semibold">Geschwindigkeit</label>
|
||
<div className="flex items-center gap-2">
|
||
<input
|
||
type="number"
|
||
className="w-24 border rounded p-1"
|
||
value={tdrData.geschwindigkeit}
|
||
onChange={(e) => {
|
||
const updated = { ...tdrData, geschwindigkeit: e.target.value };
|
||
setTdrData(updated);
|
||
updateCache(updated);
|
||
}}
|
||
/>
|
||
<span>m/µs</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mb-4 grid grid-cols-2 items-center gap-2 w-full">
|
||
<label className="font-semibold">Trigger</label>
|
||
<input
|
||
type="number"
|
||
className="w-full border rounded p-1"
|
||
value={tdrData.trigger}
|
||
onChange={(e) => {
|
||
const updated = { ...tdrData, trigger: e.target.value };
|
||
setTdrData(updated);
|
||
updateCache(updated);
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="qhd:pt-48 2xl:pt-16 xl:pt-8 laptop:pt-2 flex justify-end">
|
||
<button
|
||
onClick={handleSave}
|
||
className="bg-littwin-blue text-white px-4 py-2 rounded shadow hover:bg-blue-500"
|
||
>
|
||
Einstellungen senden
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|