feat: Overlay nicht über die Seite sondern nur über den KÜ Slot wenn ein Event kommt
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
"use client";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useAppSelector } from "@/redux/store";
|
||||
|
||||
export default function SlotActivityOverlay({
|
||||
slotIndex,
|
||||
}: {
|
||||
slotIndex: number;
|
||||
}) {
|
||||
const ksx = useAppSelector((s) => s.deviceEvents.ksx);
|
||||
const ksy = useAppSelector((s) => s.deviceEvents.ksy);
|
||||
const ksz = useAppSelector((s) => s.deviceEvents.ksz);
|
||||
const loopStartedAt = useAppSelector((s) => s.deviceEvents.loopStartedAt);
|
||||
const tdrStartedAt = useAppSelector((s) => s.deviceEvents.tdrStartedAt);
|
||||
const alignmentStartedAt = useAppSelector(
|
||||
(s) => s.deviceEvents.alignmentStartedAt
|
||||
);
|
||||
|
||||
const loopActive = Array.isArray(ksx) && ksx[slotIndex] === 1;
|
||||
const tdrActive = Array.isArray(ksy) && ksy[slotIndex] === 1;
|
||||
const alignActive = Array.isArray(ksz) && ksz[slotIndex] === 1;
|
||||
|
||||
// Progress ticker
|
||||
const [now, setNow] = useState<number>(Date.now());
|
||||
useEffect(() => {
|
||||
const any = loopActive || tdrActive || alignActive;
|
||||
if (!any) return;
|
||||
const id = setInterval(() => setNow(Date.now()), 1000);
|
||||
return () => clearInterval(id);
|
||||
}, [loopActive, tdrActive, alignActive]);
|
||||
|
||||
const clamp = (v: number, min = 0, max = 1) =>
|
||||
Math.max(min, Math.min(max, v));
|
||||
const compute = (startedAt: number | null, durationMs: number) => {
|
||||
if (!startedAt) return { pct: 0 };
|
||||
const elapsed = now - startedAt;
|
||||
const pct = clamp(elapsed / durationMs) * 100;
|
||||
return { pct };
|
||||
};
|
||||
|
||||
// Durations
|
||||
const LOOP_MS = 2 * 60 * 1000; // ~2 min
|
||||
const TDR_MS = 30 * 1000; // ~30 s
|
||||
const ALIGN_MS = 10 * 60 * 1000; // ~10 min
|
||||
|
||||
if (!loopActive && !tdrActive && !alignActive) return null;
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 z-20 flex items-center justify-center bg-white/70 backdrop-blur-sm">
|
||||
<div className="p-2 rounded-md shadow bg-white/90 border border-gray-200 w-[min(90%,12rem)]">
|
||||
<div className="text-[0.75rem] font-semibold mb-2 text-gray-800">
|
||||
Bitte warten…
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{loopActive && (
|
||||
<div>
|
||||
<div className="text-[0.7rem] text-gray-800 mb-1">Schleife</div>
|
||||
{(() => {
|
||||
const { pct } = compute(loopStartedAt, LOOP_MS);
|
||||
return (
|
||||
<div>
|
||||
<div className="h-2 w-full bg-gray-200 rounded overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-littwin-blue transition-all"
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-[0.65rem] text-gray-700 mt-1">
|
||||
{Math.round(pct)}%
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
)}
|
||||
{tdrActive && (
|
||||
<div>
|
||||
<div className="text-[0.7rem] text-gray-800 mb-1">TDR</div>
|
||||
{(() => {
|
||||
const { pct } = compute(tdrStartedAt, TDR_MS);
|
||||
return (
|
||||
<div>
|
||||
<div className="h-2 w-full bg-gray-200 rounded overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-littwin-blue transition-all"
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-[0.65rem] text-gray-700 mt-1">
|
||||
{Math.round(pct)}%
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
)}
|
||||
{alignActive && (
|
||||
<div>
|
||||
<div className="text-[0.7rem] text-gray-800 mb-1">Abgleich</div>
|
||||
{(() => {
|
||||
const { pct } = compute(alignmentStartedAt, ALIGN_MS);
|
||||
return (
|
||||
<div>
|
||||
<div className="h-2 w-full bg-gray-200 rounded overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-littwin-blue transition-all"
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-[0.65rem] text-gray-700 mt-1">
|
||||
{Math.round(pct)}%
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user