mirror of
https://github.com/hamster1963/nezha-dash.git
synced 2025-04-24 21:10:45 +08:00
Merge branch 'main' into cloudflare
This commit is contained in:
commit
c21e635ce0
@ -102,7 +102,15 @@ function CpuChart({ data }: { data: NezhaAPISafe }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
const newData = [...cpuChartData, { timeStamp: timestamp, cpu: cpu }];
|
let newData = [] as cpuChartData[];
|
||||||
|
if (cpuChartData.length === 0) {
|
||||||
|
newData = [
|
||||||
|
{ timeStamp: timestamp, cpu: cpu },
|
||||||
|
{ timeStamp: timestamp, cpu: cpu },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newData = [...cpuChartData, { timeStamp: timestamp, cpu: cpu }];
|
||||||
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > 30) {
|
||||||
newData.shift();
|
newData.shift();
|
||||||
}
|
}
|
||||||
@ -194,10 +202,18 @@ function ProcessChart({ data }: { data: NezhaAPISafe }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
const newData = [
|
let newData = [] as processChartData[];
|
||||||
|
if (processChartData.length === 0) {
|
||||||
|
newData = [
|
||||||
|
{ timeStamp: timestamp, process: process },
|
||||||
|
{ timeStamp: timestamp, process: process },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newData = [
|
||||||
...processChartData,
|
...processChartData,
|
||||||
{ timeStamp: timestamp, process: process },
|
{ timeStamp: timestamp, process: process },
|
||||||
];
|
];
|
||||||
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > 30) {
|
||||||
newData.shift();
|
newData.shift();
|
||||||
}
|
}
|
||||||
@ -276,10 +292,18 @@ function MemChart({ data }: { data: NezhaAPISafe }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
const newData = [
|
let newData = [] as memChartData[];
|
||||||
|
if (memChartData.length === 0) {
|
||||||
|
newData = [
|
||||||
|
{ timeStamp: timestamp, mem: mem, swap: swap },
|
||||||
|
{ timeStamp: timestamp, mem: mem, swap: swap },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newData = [
|
||||||
...memChartData,
|
...memChartData,
|
||||||
{ timeStamp: timestamp, mem: mem, swap: swap },
|
{ timeStamp: timestamp, mem: mem, swap: swap },
|
||||||
];
|
];
|
||||||
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > 30) {
|
||||||
newData.shift();
|
newData.shift();
|
||||||
}
|
}
|
||||||
@ -395,7 +419,15 @@ function DiskChart({ data }: { data: NezhaAPISafe }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
const newData = [...diskChartData, { timeStamp: timestamp, disk: disk }];
|
let newData = [] as diskChartData[];
|
||||||
|
if (diskChartData.length === 0) {
|
||||||
|
newData = [
|
||||||
|
{ timeStamp: timestamp, disk: disk },
|
||||||
|
{ timeStamp: timestamp, disk: disk },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newData = [...diskChartData, { timeStamp: timestamp, disk: disk }];
|
||||||
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > 30) {
|
||||||
newData.shift();
|
newData.shift();
|
||||||
}
|
}
|
||||||
@ -487,10 +519,18 @@ function NetworkChart({ data }: { data: NezhaAPISafe }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
const newData = [
|
let newData = [] as networkChartData[];
|
||||||
|
if (networkChartData.length === 0) {
|
||||||
|
newData = [
|
||||||
|
{ timeStamp: timestamp, upload: up, download: down },
|
||||||
|
{ timeStamp: timestamp, upload: up, download: down },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newData = [
|
||||||
...networkChartData,
|
...networkChartData,
|
||||||
{ timeStamp: timestamp, upload: up, download: down },
|
{ timeStamp: timestamp, upload: up, download: down },
|
||||||
];
|
];
|
||||||
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > 30) {
|
||||||
newData.shift();
|
newData.shift();
|
||||||
}
|
}
|
||||||
@ -605,10 +645,18 @@ function ConnectChart({ data }: { data: NezhaAPISafe }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const timestamp = Date.now().toString();
|
const timestamp = Date.now().toString();
|
||||||
const newData = [
|
let newData = [] as connectChartData[];
|
||||||
|
if (connectChartData.length === 0) {
|
||||||
|
newData = [
|
||||||
|
{ timeStamp: timestamp, tcp: tcp, udp: udp },
|
||||||
|
{ timeStamp: timestamp, tcp: tcp, udp: udp },
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newData = [
|
||||||
...connectChartData,
|
...connectChartData,
|
||||||
{ timeStamp: timestamp, tcp: tcp, udp: udp },
|
{ timeStamp: timestamp, tcp: tcp, udp: udp },
|
||||||
];
|
];
|
||||||
|
}
|
||||||
if (newData.length > 30) {
|
if (newData.length > 30) {
|
||||||
newData.shift();
|
newData.shift();
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ export default function ServerListClient() {
|
|||||||
<p className="text-sm font-medium opacity-40">{t("error_message")}</p>
|
<p className="text-sm font-medium opacity-40">{t("error_message")}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
if (!data) return null;
|
if (!data?.result) return null;
|
||||||
|
|
||||||
const { result } = data;
|
const { result } = data;
|
||||||
|
|
||||||
|
@ -12,7 +12,10 @@ import useSWR from "swr";
|
|||||||
|
|
||||||
export default function ServerOverviewClient() {
|
export default function ServerOverviewClient() {
|
||||||
const t = useTranslations("ServerOverviewClient");
|
const t = useTranslations("ServerOverviewClient");
|
||||||
const { data, error } = useSWR<ServerApi>("/api/server", nezhaFetcher);
|
const { data, error, isLoading } = useSWR<ServerApi>(
|
||||||
|
"/api/server",
|
||||||
|
nezhaFetcher,
|
||||||
|
);
|
||||||
const disableCartoon = getEnv("NEXT_PUBLIC_DisableCartoon") === "true";
|
const disableCartoon = getEnv("NEXT_PUBLIC_DisableCartoon") === "true";
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
@ -23,14 +26,8 @@ export default function ServerOverviewClient() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!data?.result)
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<p className="text-sm font-medium opacity-40">{t("no_data_message")}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<section className="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
<section className="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="px-6 py-3">
|
<CardContent className="px-6 py-3">
|
||||||
@ -42,7 +39,7 @@ export default function ServerOverviewClient() {
|
|||||||
<span className="relative flex h-2 w-2">
|
<span className="relative flex h-2 w-2">
|
||||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-blue-500"></span>
|
<span className="relative inline-flex h-2 w-2 rounded-full bg-blue-500"></span>
|
||||||
</span>
|
</span>
|
||||||
{data ? (
|
{data?.result ? (
|
||||||
<div className="text-lg font-semibold">
|
<div className="text-lg font-semibold">
|
||||||
{data?.result.length}
|
{data?.result.length}
|
||||||
</div>
|
</div>
|
||||||
@ -66,7 +63,7 @@ export default function ServerOverviewClient() {
|
|||||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-500 opacity-75"></span>
|
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-500 opacity-75"></span>
|
||||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-green-500"></span>
|
<span className="relative inline-flex h-2 w-2 rounded-full bg-green-500"></span>
|
||||||
</span>
|
</span>
|
||||||
{data ? (
|
{data?.result ? (
|
||||||
<div className="text-lg font-semibold">
|
<div className="text-lg font-semibold">
|
||||||
{data?.live_servers}
|
{data?.live_servers}
|
||||||
</div>
|
</div>
|
||||||
@ -90,7 +87,7 @@ export default function ServerOverviewClient() {
|
|||||||
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75"></span>
|
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75"></span>
|
||||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-red-500"></span>
|
<span className="relative inline-flex h-2 w-2 rounded-full bg-red-500"></span>
|
||||||
</span>
|
</span>
|
||||||
{data ? (
|
{data?.result ? (
|
||||||
<div className="text-lg font-semibold">
|
<div className="text-lg font-semibold">
|
||||||
{data?.offline_servers}
|
{data?.offline_servers}
|
||||||
</div>
|
</div>
|
||||||
@ -109,7 +106,7 @@ export default function ServerOverviewClient() {
|
|||||||
<p className="text-sm font-medium md:text-base">
|
<p className="text-sm font-medium md:text-base">
|
||||||
{t("p_3463-3530_Totalbandwidth")}
|
{t("p_3463-3530_Totalbandwidth")}
|
||||||
</p>
|
</p>
|
||||||
{data ? (
|
{data?.result ? (
|
||||||
<section className="flex pt-[4px] items-center gap-2">
|
<section className="flex pt-[4px] items-center gap-2">
|
||||||
<p className="text-[14px] font-semibold">
|
<p className="text-[14px] font-semibold">
|
||||||
↑{formatBytes(data?.total_out_bandwidth)}
|
↑{formatBytes(data?.total_out_bandwidth)}
|
||||||
@ -136,5 +133,11 @@ export default function ServerOverviewClient() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</section>
|
</section>
|
||||||
|
{data?.result === undefined && !isLoading && (
|
||||||
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<p className="text-sm font-medium opacity-40">{t("error_message")}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -90,17 +90,19 @@ export function formatRelativeTime(timestamp: number): string {
|
|||||||
const diff = now - timestamp;
|
const diff = now - timestamp;
|
||||||
const hours = Math.floor(diff / (1000 * 60 * 60));
|
const hours = Math.floor(diff / (1000 * 60 * 60));
|
||||||
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
|
||||||
|
|
||||||
if (hours > 24) {
|
if (hours > 24) {
|
||||||
const days = Math.floor(hours / 24);
|
const days = Math.floor(hours / 24);
|
||||||
return `${days}d`;
|
return `${days}d`;
|
||||||
} else if (hours > 0) {
|
} else if (hours > 0) {
|
||||||
return `${hours}h`;
|
return `${hours}h`;
|
||||||
} else if (minutes >= 0) {
|
} else if (minutes > 0) {
|
||||||
return `${minutes}m`;
|
return `${minutes}m`;
|
||||||
} else {
|
} else if (seconds >= 0) {
|
||||||
return "just now";
|
return `${seconds}s`;
|
||||||
}
|
}
|
||||||
|
return "0s";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatTime(timestamp: number): string {
|
export function formatTime(timestamp: number): string {
|
||||||
|
Loading…
Reference in New Issue
Block a user