diff --git a/app/(main)/ClientComponents/ServerListClient.tsx b/app/(main)/ClientComponents/ServerListClient.tsx index d899f4e..81f8e8e 100644 --- a/app/(main)/ClientComponents/ServerListClient.tsx +++ b/app/(main)/ClientComponents/ServerListClient.tsx @@ -10,24 +10,13 @@ export default function ServerListClient() { refreshInterval: 3000, }); if (!data) return null; - const sortedResult = data.result.sort((a: any, b: any) => a.id - b.id); + const sortedResult = data.result.sort((a, b) => a.id - b.id); const timestamp = Date.now() / 1000; return (
- {sortedResult.map((server: any) => ( - 300 ? "offline" : "online"} - uptime={server.status.Uptime / 86400} - mem={(server.status.MemUsed / server.host.MemTotal) * 100} - stg={(server.status.DiskUsed / server.host.DiskTotal) * 100} - /> + {sortedResult.map((serverInfo) => ( + ))}
); diff --git a/bun.lockb b/bun.lockb index 113abeb..d1e5845 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/ServerCard.tsx b/components/ServerCard.tsx index 6120137..3a93215 100644 --- a/components/ServerCard.tsx +++ b/components/ServerCard.tsx @@ -1,62 +1,43 @@ -import React from "react"; - +import { NezhaAPISafe } from "@/app/types/nezha-api"; import ServerUsageBar from "@/components/ServerUsageBar"; import { Card } from "@/components/ui/card"; import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@/components/ui/tooltip"; - -type ServerCardProps = { - id: number; - status: string; - name: string; - uptime: number; - cpu: number; - mem: number; - stg: number; - up: number; - down: number; -}; + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { formatNezhaInfo } from "@/lib/utils"; +import ServerCardPopover from "./ServerCardPopover"; export default function ServerCard({ - status, - name, - uptime, - cpu, - mem, - stg, - up, - down, -}: ServerCardProps) { - return status === "online" ? ( + timestamp, + serverInfo, +}: { + timestamp: number; + serverInfo: NezhaAPISafe; +}) { + const { name, online, cpu, up, down, mem, stg, ...props } = formatNezhaInfo( + timestamp, + serverInfo, + ); + + return online === "online" ? ( - - - -
- -

- {name} -

-
-
- -
-
Hostname: {name}
-
Online: {uptime.toFixed(0)} Days
-
-
-
-
+ + +
+ +

{name}

+
+
+ + + +

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" } > - - - -
- -

{name}

-
-
- Offline -
-
+ + +
+ +

{name}

+
+
+ 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",