66 lines
1.4 KiB
TypeScript
66 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { RefreshCw } from "lucide-react";
|
|
import { useEffect, useState } from "react";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
export function HealthCheckClient() {
|
|
const [status, setStatus] = useState<"checking" | "online" | "offline">(
|
|
"checking",
|
|
);
|
|
const [checking, setChecking] = useState(false);
|
|
|
|
async function checkEmulator() {
|
|
setChecking(true);
|
|
setStatus("checking");
|
|
try {
|
|
const res = await fetch("/api/admin/devops/health");
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
setStatus(data.emulator ? "online" : "offline");
|
|
} else {
|
|
setStatus("offline");
|
|
}
|
|
} catch {
|
|
setStatus("offline");
|
|
} finally {
|
|
setChecking(false);
|
|
}
|
|
}
|
|
|
|
// biome-ignore lint/correctness/useExhaustiveDependencies: explicitly chosen here, see surrounding code
|
|
useEffect(() => {
|
|
checkEmulator();
|
|
}, []);
|
|
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
<Badge
|
|
variant={
|
|
status === "online"
|
|
? "default"
|
|
: status === "offline"
|
|
? "destructive"
|
|
: "secondary"
|
|
}
|
|
>
|
|
{status === "checking"
|
|
? "Checking..."
|
|
: status === "online"
|
|
? "Online"
|
|
: "Offline"}
|
|
</Badge>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="h-6 w-6"
|
|
onClick={checkEmulator}
|
|
disabled={checking}
|
|
>
|
|
<RefreshCw className={`h-3 w-3 ${checking ? "animate-spin" : ""}`} />
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|