52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { ServerStats } from "@/components/server_stats";
|
|
import { Card } from "@/components/ui/card";
|
|
import type { Metrics } from "@/models/metrics";
|
|
import type { MinimalServers } from "@/models/minimal_servers";
|
|
import { useQueries, useQuery } from "@tanstack/react-query";
|
|
import { createFileRoute } from "@tanstack/react-router";
|
|
import { useEffect, useState } from "react";
|
|
|
|
export const Route = createFileRoute("/")({
|
|
component: App,
|
|
});
|
|
|
|
function App() {
|
|
const { data: servers = [] } = useQuery<MinimalServers>({
|
|
queryKey: ["servers"],
|
|
queryFn: async () => {
|
|
const res = await fetch("/api/servers");
|
|
if (!res.ok) throw new Error("Failed to fetch servers");
|
|
return (await res.json()) as MinimalServers;
|
|
},
|
|
refetchInterval: 40000,
|
|
});
|
|
|
|
const { data: metrics = [] } = useQuery<Metrics[]>({
|
|
queryKey: ["serversMetrics", servers.map((s) => s.id).join("-")],
|
|
enabled: servers.length > 0,
|
|
queryFn: async () => {
|
|
const results = await Promise.all(
|
|
servers.map(async (server) => {
|
|
const res = await fetch(`/api/servers/${server.id}/metrics`);
|
|
if (!res.ok) throw new Error(`Failed metrics for ${server.id}`);
|
|
return (await res.json()) as Metrics;
|
|
}),
|
|
);
|
|
return results;
|
|
},
|
|
refetchInterval: 30000,
|
|
});
|
|
|
|
return (
|
|
<div className="p-4 flex flex-col gap-2">
|
|
{metrics.map((metric, index) => (
|
|
<div key={index}>
|
|
<Card className="p-2">
|
|
{metric && <ServerStats server={servers[index]} metrics={metric} />}
|
|
</Card>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|