|
@@ -1,5 +1,5 @@
|
|
|
"use client";
|
|
"use client";
|
|
|
-import { ArrowPathIcon } from "@heroicons/react/24/outline";
|
|
|
|
|
|
|
+import { ArrowPathIcon, ServerIcon } from "@heroicons/react/24/outline";
|
|
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
import { useState } from "react";
|
|
import { useState } from "react";
|
|
|
import toast from "react-hot-toast";
|
|
import toast from "react-hot-toast";
|
|
@@ -38,88 +38,49 @@ export default function ApiHealth() {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const isHealthy = data?.status === "healthy";
|
|
const isHealthy = data?.status === "healthy";
|
|
|
- const lastChecked = data?.datetime
|
|
|
|
|
- ? new Date(data.datetime).toLocaleTimeString()
|
|
|
|
|
- : null;
|
|
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <div className="mb-6 p-4 border rounded bg-gray-50 dark:bg-gray-800">
|
|
|
|
|
- <div className="flex items-center justify-between mb-4">
|
|
|
|
|
- <h3 className="font-semibold">API Health</h3>
|
|
|
|
|
- <div className="flex items-center gap-2">
|
|
|
|
|
- {isLoading ? (
|
|
|
|
|
- <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-indigo-600 dark:border-indigo-400"></div>
|
|
|
|
|
- ) : (
|
|
|
|
|
- <span
|
|
|
|
|
- className={`px-2 py-1 rounded text-xs font-medium ${
|
|
|
|
|
- isHealthy && !error
|
|
|
|
|
- ? "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200"
|
|
|
|
|
- : "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"
|
|
|
|
|
- }`}
|
|
|
|
|
- >
|
|
|
|
|
- {isHealthy && !error ? "Healthy" : "Unhealthy"}
|
|
|
|
|
- </span>
|
|
|
|
|
- )}
|
|
|
|
|
- <button
|
|
|
|
|
- onClick={() => setShowRestartConfirm(true)}
|
|
|
|
|
- disabled={restartMutation.isPending}
|
|
|
|
|
- className="ml-2 p-1.5 rounded hover:bg-gray-200 dark:hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
|
|
|
- title="Restart API service"
|
|
|
|
|
- >
|
|
|
|
|
- <ArrowPathIcon
|
|
|
|
|
- className={`w-4 h-4 ${
|
|
|
|
|
- restartMutation.isPending ? "animate-spin" : ""
|
|
|
|
|
- }`}
|
|
|
|
|
- />
|
|
|
|
|
- </button>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- <div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-sm">
|
|
|
|
|
- <div>
|
|
|
|
|
- <span className="font-medium text-gray-700 dark:text-gray-300">
|
|
|
|
|
- Status:
|
|
|
|
|
- </span>
|
|
|
|
|
- <span
|
|
|
|
|
- className={`ml-2 ${isHealthy && !error ? "text-green-600" : "text-red-600"}`}
|
|
|
|
|
- >
|
|
|
|
|
- {isLoading
|
|
|
|
|
- ? "Checking..."
|
|
|
|
|
- : isHealthy && !error
|
|
|
|
|
- ? "Operational"
|
|
|
|
|
- : "Issues Detected"}
|
|
|
|
|
- </span>
|
|
|
|
|
- </div>
|
|
|
|
|
- {responseTime !== null && (
|
|
|
|
|
- <div>
|
|
|
|
|
- <span className="font-medium text-gray-700 dark:text-gray-300">
|
|
|
|
|
- Response Time:
|
|
|
|
|
- </span>
|
|
|
|
|
- <span className="ml-2 text-gray-900 dark:text-gray-100">
|
|
|
|
|
- {responseTime}ms
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <div className="group relative overflow-hidden rounded-2xl bg-white/5 p-8 ring-1 ring-white/10 transition-all duration-300 hover:bg-white/10 hover:ring-white/20">
|
|
|
|
|
+ <div className="flex items-center justify-between">
|
|
|
|
|
+ <div className="flex items-center gap-x-3">
|
|
|
|
|
+ <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-500/20 ring-1 ring-blue-500/30">
|
|
|
|
|
+ <ServerIcon className="h-6 w-6 text-blue-400" />
|
|
|
</div>
|
|
</div>
|
|
|
- )}
|
|
|
|
|
- {lastChecked && (
|
|
|
|
|
<div>
|
|
<div>
|
|
|
- <span className="font-medium text-gray-700 dark:text-gray-300">
|
|
|
|
|
- Last Checked:
|
|
|
|
|
- </span>
|
|
|
|
|
- <span className="ml-2 text-gray-900 dark:text-gray-100">
|
|
|
|
|
- {lastChecked}
|
|
|
|
|
- </span>
|
|
|
|
|
- </div>
|
|
|
|
|
- )}
|
|
|
|
|
- {error && (
|
|
|
|
|
- <div className="md:col-span-2">
|
|
|
|
|
- <span className="font-medium text-gray-700 dark:text-gray-300">
|
|
|
|
|
- Error:
|
|
|
|
|
- </span>
|
|
|
|
|
- <span className="ml-2 text-red-600 text-xs">
|
|
|
|
|
- {error.message || "Connection failed"}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <div className="text-2xl font-bold text-white">
|
|
|
|
|
+ {isLoading ? (
|
|
|
|
|
+ <div className="flex justify-center">
|
|
|
|
|
+ <div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <span
|
|
|
|
|
+ className={
|
|
|
|
|
+ isHealthy && !error ? "text-green-400" : "text-red-400"
|
|
|
|
|
+ }
|
|
|
|
|
+ >
|
|
|
|
|
+ {isHealthy && !error ? "Healthy" : "Issues"}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="text-sm font-medium text-gray-400">API Health</div>
|
|
|
|
|
+ {responseTime !== null && (
|
|
|
|
|
+ <div className="text-xs text-gray-500 mt-1">
|
|
|
|
|
+ {responseTime}ms response
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
</div>
|
|
</div>
|
|
|
- )}
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <button
|
|
|
|
|
+ onClick={() => setShowRestartConfirm(true)}
|
|
|
|
|
+ disabled={restartMutation.isPending}
|
|
|
|
|
+ className="px-3 py-1 rounded text-xs font-medium transition-colors bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-1"
|
|
|
|
|
+ title="Restart API service"
|
|
|
|
|
+ >
|
|
|
|
|
+ <ArrowPathIcon
|
|
|
|
|
+ className={`h-3 w-3 ${restartMutation.isPending ? "animate-spin" : ""}`}
|
|
|
|
|
+ />
|
|
|
|
|
+ Restart
|
|
|
|
|
+ </button>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
{/* Restart Confirmation Dialog */}
|
|
{/* Restart Confirmation Dialog */}
|