Skip to content

Commit 0d0b738

Browse files
committed
remove unused and refactor components
Signed-off-by: wambui-pixel <kiokowambui015@gmail.com>
1 parent f6b0100 commit 0d0b738

File tree

12 files changed

+996
-1086
lines changed

12 files changed

+996
-1086
lines changed

ui/app/api/broker/overview/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ export async function GET() {
6464
});
6565
if (!res.ok) {
6666
return NextResponse.json(
67-
{ error: `Backend returned ${res.status}` },
68-
{ status: res.status },
67+
{ error: "Broker request failed" },
68+
{ status: 502 },
6969
);
7070
}
7171
const data = await res.json();
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"use client";
2+
3+
import { Badge } from "@/components/ui/badge";
4+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
5+
import {
6+
Table,
7+
TableBody,
8+
TableCell,
9+
TableHead,
10+
TableHeader,
11+
TableRow,
12+
} from "@/components/ui/table";
13+
import { formatBytes, formatCount, formatUptime } from "@/lib/format";
14+
import type { NodeInfo } from "@/lib/types";
15+
16+
interface ClusterNodesTableProps {
17+
nodes: NodeInfo[];
18+
selectedNodeId: string | null;
19+
onSelectNode: (id: string | null) => void;
20+
}
21+
22+
export function ClusterNodesTable({
23+
nodes,
24+
selectedNodeId,
25+
onSelectNode,
26+
}: ClusterNodesTableProps) {
27+
if (nodes.length === 0) return null;
28+
29+
return (
30+
<Card className="border-flux-card-border bg-flux-card">
31+
<CardHeader className="pb-3">
32+
<div className="flex items-center justify-between">
33+
<div>
34+
<CardTitle className="text-base text-flux-text">
35+
Cluster Nodes
36+
</CardTitle>
37+
<p className="text-xs text-flux-text-muted mt-0.5">
38+
{nodes.length} node{nodes.length !== 1 ? "s" : ""}
39+
</p>
40+
</div>
41+
</div>
42+
</CardHeader>
43+
<CardContent className="p-0">
44+
<div className="overflow-x-auto">
45+
<Table>
46+
<TableHeader>
47+
<TableRow className="border-flux-card-border hover:bg-transparent">
48+
<TableHead className="pl-6">Node</TableHead>
49+
<TableHead>Address</TableHead>
50+
<TableHead className="text-right">Sessions</TableHead>
51+
<TableHead className="text-right">Subscriptions</TableHead>
52+
<TableHead className="text-right">Msgs In</TableHead>
53+
<TableHead className="text-right">Msgs Out</TableHead>
54+
<TableHead className="text-right">Bytes In</TableHead>
55+
<TableHead className="text-right pr-6">Uptime</TableHead>
56+
</TableRow>
57+
</TableHeader>
58+
<TableBody>
59+
{nodes.map((node) => {
60+
const isSelected = selectedNodeId === node.node_id;
61+
return (
62+
<TableRow
63+
key={node.node_id}
64+
className={`border-flux-card-border transition-colors ${
65+
isSelected
66+
? "bg-flux-blue/10 hover:bg-flux-blue/15"
67+
: "hover:bg-flux-hover"
68+
}`}
69+
>
70+
<TableCell className="pl-6 py-4">
71+
<button
72+
type="button"
73+
aria-pressed={isSelected}
74+
aria-label={`Inspect node ${node.node_id}`}
75+
onClick={() =>
76+
onSelectNode(isSelected ? null : node.node_id)
77+
}
78+
className="flex w-full items-center gap-2 rounded text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-flux-blue"
79+
>
80+
<span className="inline-block w-2 h-2 rounded-full bg-flux-green shrink-0" />
81+
<span className="text-flux-text font-medium text-sm">
82+
{node.node_id}
83+
</span>
84+
{node.is_leader && (
85+
<Badge
86+
variant="outline"
87+
className="text-xs bg-flux-blue/10 text-flux-blue border-flux-blue/20"
88+
>
89+
Leader
90+
</Badge>
91+
)}
92+
</button>
93+
</TableCell>
94+
<TableCell className="text-flux-text-muted font-mono text-xs py-4">
95+
{node.addr}
96+
</TableCell>
97+
<TableCell className="text-flux-text text-sm text-right py-4">
98+
{node.sessions !== undefined ? (
99+
formatCount(node.sessions)
100+
) : (
101+
<span className="text-flux-text-muted"></span>
102+
)}
103+
</TableCell>
104+
<TableCell className="text-flux-text text-sm text-right py-4">
105+
{node.subscriptions !== undefined ? (
106+
formatCount(node.subscriptions)
107+
) : (
108+
<span className="text-flux-text-muted"></span>
109+
)}
110+
</TableCell>
111+
<TableCell className="text-flux-text text-sm text-right py-4">
112+
{node.messages_received !== undefined ? (
113+
formatCount(node.messages_received)
114+
) : (
115+
<span className="text-flux-text-muted"></span>
116+
)}
117+
</TableCell>
118+
<TableCell className="text-flux-text text-sm text-right py-4">
119+
{node.messages_sent !== undefined ? (
120+
formatCount(node.messages_sent)
121+
) : (
122+
<span className="text-flux-text-muted"></span>
123+
)}
124+
</TableCell>
125+
<TableCell className="text-flux-text text-sm text-right py-4">
126+
{node.bytes_received !== undefined ? (
127+
formatBytes(node.bytes_received)
128+
) : (
129+
<span className="text-flux-text-muted"></span>
130+
)}
131+
</TableCell>
132+
<TableCell className="text-flux-text-muted text-sm text-right pr-6 py-4">
133+
{formatUptime(node.uptime_seconds)}
134+
</TableCell>
135+
</TableRow>
136+
);
137+
})}
138+
</TableBody>
139+
</Table>
140+
</div>
141+
</CardContent>
142+
</Card>
143+
);
144+
}

0 commit comments

Comments
 (0)