54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { useEffect, useMemo } from "preact/hooks";
|
|
import { useSignal } from "@preact/signals";
|
|
|
|
const latencySamples = [18, 21, 24, 19, 22, 27, 20, 23, 25];
|
|
|
|
function getLatency() {
|
|
const jitter = Math.floor(Math.random() * 4) - 2; // -2..1
|
|
const base =
|
|
latencySamples[Math.floor(Math.random() * latencySamples.length)];
|
|
return Math.max(12, base + jitter);
|
|
}
|
|
|
|
export default function ServerStatus() {
|
|
const latency = useSignal(getLatency());
|
|
const status = useSignal<"online" | "warning">("online");
|
|
|
|
useEffect(() => {
|
|
const interval = setInterval(() => {
|
|
const value = getLatency();
|
|
latency.value = value;
|
|
status.value = value > 28 ? "warning" : "online";
|
|
}, 1400);
|
|
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
const statusLabel = useMemo(
|
|
() => (status.value === "online" ? "Operacional" : "Oscilação"),
|
|
[status.value],
|
|
);
|
|
|
|
return (
|
|
<div class="flex items-center justify-between rounded-xl border border-white/10 bg-white/5 px-5 py-4 text-sm text-foreground/90 shadow-lg shadow-black/30">
|
|
<div class="flex flex-col gap-1">
|
|
<span class="text-xs uppercase tracking-[0.2em] text-foreground/60">
|
|
Ping em tempo real
|
|
</span>
|
|
<div class="flex items-center gap-2">
|
|
<span
|
|
class={`h-2 w-2 rounded-full ${
|
|
status.value === "online" ? "bg-accent" : "bg-amber-400"
|
|
}`}
|
|
/>
|
|
<span class="font-semibold">{statusLabel}</span>
|
|
<span class="text-foreground/60">cloudflare-edge-01</span>
|
|
</div>
|
|
</div>
|
|
<div class="text-right">
|
|
<p class="text-2xl font-bold text-foreground">{latency.value}ms</p>
|
|
<p class="text-xs text-foreground/60">latência média</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|