CPU
@@ -89,19 +70,15 @@ export default function ServerCard({
"flex flex-col items-center justify-start gap-3 p-3 md:px-5 lg:flex-row"
}
>
-
-
-
-
-
- Offline
-
-
+
+
+
+
+ Offline
+
);
}
diff --git a/components/ServerCardPopover.tsx b/components/ServerCardPopover.tsx
new file mode 100644
index 0000000..aab2299
--- /dev/null
+++ b/components/ServerCardPopover.tsx
@@ -0,0 +1,68 @@
+import { NezhaAPISafe } from "@/app/types/nezha-api";
+import { cn, formatBytes } from "@/lib/utils";
+
+export function ServerCardPopoverCard({
+ className,
+ title,
+ content,
+ children,
+}: {
+ className?: string;
+ title: string;
+ content?: string;
+ children?: React.ReactNode;
+}) {
+ return (
+
+
{title}
+ {children ? children :
{content}
}
+
+
+ );
+}
+
+export default function ServerCardPopover({
+ host,
+ status,
+}: {
+ host: NezhaAPISafe["host"];
+ status: NezhaAPISafe["status"];
+}) {
+ return (
+
+
+ item).join(", ")}`}
+ />
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/ui/popover.tsx b/components/ui/popover.tsx
new file mode 100644
index 0000000..a0ec48b
--- /dev/null
+++ b/components/ui/popover.tsx
@@ -0,0 +1,31 @@
+"use client"
+
+import * as React from "react"
+import * as PopoverPrimitive from "@radix-ui/react-popover"
+
+import { cn } from "@/lib/utils"
+
+const Popover = PopoverPrimitive.Root
+
+const PopoverTrigger = PopoverPrimitive.Trigger
+
+const PopoverContent = React.forwardRef<
+ React.ElementRef
,
+ React.ComponentPropsWithoutRef
+>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
+
+
+
+))
+PopoverContent.displayName = PopoverPrimitive.Content.displayName
+
+export { Popover, PopoverTrigger, PopoverContent }
diff --git a/lib/utils.ts b/lib/utils.ts
index 6dcf264..e3a7514 100644
--- a/lib/utils.ts
+++ b/lib/utils.ts
@@ -1,3 +1,4 @@
+import { NezhaAPISafe } from "@/app/types/nezha-api";
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
@@ -5,6 +6,18 @@ export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
+export function formatNezhaInfo(timestamp: number, serverInfo: NezhaAPISafe) {
+ return {
+ ...serverInfo,
+ cpu: serverInfo.status.CPU,
+ up: serverInfo.status.NetOutSpeed / 1024 / 1024,
+ down: serverInfo.status.NetInSpeed / 1024 / 1024,
+ online: timestamp - serverInfo.last_active > 300 ? "offline" : "online",
+ mem: (serverInfo.status.MemUsed / serverInfo.host.MemTotal) * 100,
+ stg: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100,
+ }
+}
+
export function formatBytes(bytes: number, decimals: number = 2) {
if (!+bytes) return "0 Bytes";
diff --git a/package.json b/package.json
index 9bcef28..17b36e6 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-navigation-menu": "^1.1.4",
+ "@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.0.2",