mirror of
https://github.com/hamster1963/nezha-dash.git
synced 2025-04-24 21:10:45 +08:00
refactor: data retrieval function
This commit is contained in:
parent
7cfc5a49cc
commit
a16dd290a7
@ -11,12 +11,11 @@ export default function ServerListClient() {
|
||||
});
|
||||
if (!data) return null;
|
||||
const sortedResult = data.result.sort((a, b) => a.id - b.id);
|
||||
const timestamp = Date.now() / 1000;
|
||||
|
||||
return (
|
||||
<section className={"grid grid-cols-1 gap-2 md:grid-cols-2"}>
|
||||
{sortedResult.map((serverInfo) => (
|
||||
<ServerCard key={serverInfo.id} timestamp={timestamp} serverInfo={serverInfo} />
|
||||
<ServerCard key={serverInfo.id} serverInfo={serverInfo} />
|
||||
))}
|
||||
</section>
|
||||
);
|
||||
|
@ -38,7 +38,7 @@ function Header() {
|
||||
|
||||
// https://github.com/streamich/react-use/blob/master/src/useInterval.ts
|
||||
const useInterval = (callback: Function, delay?: number | null) => {
|
||||
const savedCallback = useRef<Function>(() => { });
|
||||
const savedCallback = useRef<Function>(() => {});
|
||||
|
||||
useEffect(() => {
|
||||
savedCallback.current = callback;
|
||||
@ -61,7 +61,9 @@ function Overview() {
|
||||
}, []);
|
||||
const timeOption = DateTime.TIME_SIMPLE;
|
||||
timeOption.hour12 = true;
|
||||
const [timeString, setTimeString] = useState(DateTime.now().setLocale("en-US").toLocaleString(timeOption));
|
||||
const [timeString, setTimeString] = useState(
|
||||
DateTime.now().setLocale("en-US").toLocaleString(timeOption),
|
||||
);
|
||||
|
||||
useInterval(() => {
|
||||
setTimeString(DateTime.now().setLocale("en-US").toLocaleString(timeOption));
|
||||
@ -73,9 +75,7 @@ function Overview() {
|
||||
<div className="flex items-center gap-1.5">
|
||||
<p className="text-sm font-medium opacity-50">where the time is</p>
|
||||
{mouted && (
|
||||
<p className="opacity-1 text-sm font-medium">
|
||||
{timeString}
|
||||
</p>
|
||||
<p className="opacity-1 text-sm font-medium">{timeString}</p>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import ServerList from "@/components/ServerList";
|
||||
import ServerOverview from "@/components/ServerOverview";
|
||||
import { GetNezhaData } from "@/lib/prefetch";
|
||||
import { GetNezhaData } from "@/lib/serverFetch";
|
||||
|
||||
import { SWRConfig } from "swr";
|
||||
|
||||
export default function Home() {
|
||||
|
@ -1,57 +1,10 @@
|
||||
import { NezhaAPI, ServerApi } from "@/app/types/nezha-api";
|
||||
import { MakeOptional } from "@/app/types/utils";
|
||||
import { GetNezhaData } from "@/lib/serverFetch";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function GET(_: Request) {
|
||||
if (!process.env.NezhaBaseUrl) {
|
||||
return NextResponse.json(
|
||||
{ error: "NezhaBaseUrl is not set" },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
// Remove trailing slash
|
||||
var nezhaBaseUrl = process.env.NezhaBaseUrl;
|
||||
|
||||
if (process.env.NezhaBaseUrl[process.env.NezhaBaseUrl.length - 1] === "/") {
|
||||
nezhaBaseUrl = process.env.NezhaBaseUrl.slice(0, -1);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(nezhaBaseUrl + "/api/v1/server/details", {
|
||||
headers: {
|
||||
Authorization: process.env.NezhaAuth as string,
|
||||
},
|
||||
next: {
|
||||
revalidate: 0,
|
||||
},
|
||||
});
|
||||
const nezhaData = (await response.json()).result as NezhaAPI[];
|
||||
const data: ServerApi = {
|
||||
live_servers: 0,
|
||||
offline_servers: 0,
|
||||
total_bandwidth: 0,
|
||||
result: [],
|
||||
};
|
||||
const timestamp = Date.now() / 1000;
|
||||
data.result = nezhaData.map(
|
||||
(element: MakeOptional<NezhaAPI, "ipv4" | "ipv6" | "valid_ip">) => {
|
||||
if (timestamp - element.last_active > 300) {
|
||||
data.offline_servers += 1;
|
||||
} else {
|
||||
data.live_servers += 1;
|
||||
}
|
||||
data.total_bandwidth += element.status.NetOutTransfer;
|
||||
|
||||
delete element.ipv4;
|
||||
delete element.ipv6;
|
||||
delete element.valid_ip;
|
||||
|
||||
return element;
|
||||
},
|
||||
);
|
||||
|
||||
return NextResponse.json(data, { status: 200 });
|
||||
const response = await GetNezhaData();
|
||||
return NextResponse.json(response, { status: 200 });
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: error }, { status: 200 });
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ export interface NezhaAPI {
|
||||
name: string;
|
||||
tag: string;
|
||||
last_active: number;
|
||||
online_status: boolean;
|
||||
ipv4: string;
|
||||
ipv6: string;
|
||||
valid_ip: string;
|
||||
|
@ -10,18 +10,14 @@ import { formatNezhaInfo } from "@/lib/utils";
|
||||
import ServerCardPopover from "./ServerCardPopover";
|
||||
|
||||
export default function ServerCard({
|
||||
timestamp,
|
||||
serverInfo,
|
||||
}: {
|
||||
timestamp: number;
|
||||
serverInfo: NezhaAPISafe;
|
||||
}) {
|
||||
const { name, online, cpu, up, down, mem, stg, ...props } = formatNezhaInfo(
|
||||
timestamp,
|
||||
serverInfo,
|
||||
);
|
||||
const { name, online, cpu, up, down, mem, stg, ...props } =
|
||||
formatNezhaInfo(serverInfo);
|
||||
|
||||
return online === "online" ? (
|
||||
return online ? (
|
||||
<Card
|
||||
className={
|
||||
"flex flex-col items-center justify-start gap-3 p-3 md:px-5 lg:flex-row"
|
||||
|
@ -1,13 +1,13 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import * as React from "react"
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
||||
import * as React from "react";
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const Popover = PopoverPrimitive.Root
|
||||
const Popover = PopoverPrimitive.Root;
|
||||
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
|
||||
const PopoverContent = React.forwardRef<
|
||||
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||
@ -20,12 +20,12 @@ const PopoverContent = React.forwardRef<
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
))
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
||||
));
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
||||
|
||||
export { Popover, PopoverTrigger, PopoverContent }
|
||||
export { Popover, PopoverTrigger, PopoverContent };
|
||||
|
@ -1,54 +0,0 @@
|
||||
import { NezhaAPI, ServerApi } from "@/app/types/nezha-api";
|
||||
import { MakeOptional } from "@/app/types/utils";
|
||||
import { error } from "console";
|
||||
|
||||
export async function GetNezhaData() {
|
||||
if (!process.env.NezhaBaseUrl) {
|
||||
error("NezhaBaseUrl is not set");
|
||||
return;
|
||||
}
|
||||
// Remove trailing slash
|
||||
var nezhaBaseUrl = process.env.NezhaBaseUrl;
|
||||
|
||||
if (process.env.NezhaBaseUrl[process.env.NezhaBaseUrl.length - 1] === "/") {
|
||||
nezhaBaseUrl = process.env.NezhaBaseUrl.slice(0, -1);
|
||||
}
|
||||
try {
|
||||
const response = await fetch(nezhaBaseUrl + "/api/v1/server/details", {
|
||||
headers: {
|
||||
Authorization: process.env.NezhaAuth as string,
|
||||
},
|
||||
next: {
|
||||
revalidate: 1,
|
||||
},
|
||||
});
|
||||
const nezhaData = (await response.json()).result as NezhaAPI[];
|
||||
const data: ServerApi = {
|
||||
live_servers: 0,
|
||||
offline_servers: 0,
|
||||
total_bandwidth: 0,
|
||||
result: [],
|
||||
};
|
||||
const timestamp = Date.now() / 1000;
|
||||
data.result = nezhaData.map(
|
||||
(element: MakeOptional<NezhaAPI, "ipv4" | "ipv6" | "valid_ip">) => {
|
||||
if (timestamp - element.last_active > 300) {
|
||||
data.offline_servers += 1;
|
||||
} else {
|
||||
data.live_servers += 1;
|
||||
}
|
||||
data.total_bandwidth += element.status.NetOutTransfer;
|
||||
|
||||
delete element.ipv4;
|
||||
delete element.ipv6;
|
||||
delete element.valid_ip;
|
||||
|
||||
return element;
|
||||
},
|
||||
);
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
58
lib/serverFetch.tsx
Normal file
58
lib/serverFetch.tsx
Normal file
@ -0,0 +1,58 @@
|
||||
"use server";
|
||||
|
||||
import { NezhaAPI, ServerApi } from "@/app/types/nezha-api";
|
||||
import { MakeOptional } from "@/app/types/utils";
|
||||
import { error } from "console";
|
||||
|
||||
export async function GetNezhaData() {
|
||||
if (!process.env.NezhaBaseUrl) {
|
||||
error("NezhaBaseUrl is not set");
|
||||
return;
|
||||
}
|
||||
// Remove trailing slash
|
||||
var nezhaBaseUrl = process.env.NezhaBaseUrl;
|
||||
|
||||
if (process.env.NezhaBaseUrl[process.env.NezhaBaseUrl.length - 1] === "/") {
|
||||
nezhaBaseUrl = process.env.NezhaBaseUrl.slice(0, -1);
|
||||
}
|
||||
try {
|
||||
const response = await fetch(nezhaBaseUrl + "/api/v1/server/details", {
|
||||
headers: {
|
||||
Authorization: process.env.NezhaAuth as string,
|
||||
},
|
||||
next: {
|
||||
revalidate: 1,
|
||||
},
|
||||
});
|
||||
const nezhaData = (await response.json()).result as NezhaAPI[];
|
||||
const data: ServerApi = {
|
||||
live_servers: 0,
|
||||
offline_servers: 0,
|
||||
total_bandwidth: 0,
|
||||
result: [],
|
||||
};
|
||||
const timestamp = Date.now() / 1000;
|
||||
data.result = nezhaData.map(
|
||||
(element: MakeOptional<NezhaAPI, "ipv4" | "ipv6" | "valid_ip">) => {
|
||||
if (timestamp - element.last_active > 300) {
|
||||
data.offline_servers += 1;
|
||||
element.online_status = false;
|
||||
} else {
|
||||
data.live_servers += 1;
|
||||
element.online_status = true;
|
||||
}
|
||||
data.total_bandwidth += element.status.NetOutTransfer;
|
||||
|
||||
delete element.ipv4;
|
||||
delete element.ipv6;
|
||||
delete element.valid_ip;
|
||||
|
||||
return element;
|
||||
},
|
||||
);
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
@ -6,16 +6,16 @@ export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
export function formatNezhaInfo(timestamp: number, serverInfo: NezhaAPISafe) {
|
||||
export function formatNezhaInfo(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",
|
||||
online: serverInfo.online_status,
|
||||
mem: (serverInfo.status.MemUsed / serverInfo.host.MemTotal) * 100,
|
||||
stg: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function formatBytes(bytes: number, decimals: number = 2) {
|
||||
|
Loading…
Reference in New Issue
Block a user