Skip to content

Commit fb676ae

Browse files
authored
Merge pull request #56 from cybermax4200/feat/network-status-indicator
feat: add network status indicator to footer
2 parents 697e351 + 8bd43af commit fb676ae

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

src/components/NetworkStatus.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"use client";
2+
3+
import { useEffect, useState } from "react";
4+
5+
const RPC_URL = process.env.NEXT_PUBLIC_RPC_URL ?? "";
6+
const NETWORK = process.env.NEXT_PUBLIC_STELLAR_NETWORK ?? "testnet";
7+
const POLL_MS = 30_000;
8+
9+
type Status = "online" | "offline" | "checking";
10+
11+
export default function NetworkStatus() {
12+
const [status, setStatus] = useState<Status>("checking");
13+
const [lastPing, setLastPing] = useState<Date | null>(null);
14+
15+
async function ping() {
16+
if (!RPC_URL) {
17+
setStatus("offline");
18+
return;
19+
}
20+
try {
21+
const res = await fetch(RPC_URL, {
22+
method: "POST",
23+
headers: { "Content-Type": "application/json" },
24+
body: JSON.stringify({
25+
jsonrpc: "2.0",
26+
id: 1,
27+
method: "getLatestLedger",
28+
params: {},
29+
}),
30+
});
31+
if (res.ok) {
32+
setStatus("online");
33+
setLastPing(new Date());
34+
} else {
35+
setStatus("offline");
36+
}
37+
} catch {
38+
setStatus("offline");
39+
}
40+
}
41+
42+
useEffect(() => {
43+
ping();
44+
const id = setInterval(ping, POLL_MS);
45+
return () => clearInterval(id);
46+
}, []);
47+
48+
const dotColor =
49+
status === "online"
50+
? "bg-green-400"
51+
: status === "offline"
52+
? "bg-red-500"
53+
: "bg-yellow-400 animate-pulse";
54+
55+
const label = NETWORK.charAt(0).toUpperCase() + NETWORK.slice(1);
56+
57+
return (
58+
<div className="flex items-center gap-2 text-xs text-gray-500">
59+
<span
60+
className={`inline-block w-2 h-2 rounded-full ${dotColor}`}
61+
aria-label={`RPC ${status}`}
62+
/>
63+
<span>{label}</span>
64+
{lastPing && (
65+
<span title={lastPing.toLocaleTimeString()}>
66+
· {lastPing.toLocaleTimeString()}
67+
</span>
68+
)}
69+
</div>
70+
);
71+
}

0 commit comments

Comments
 (0)