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
f9b798c406
@ -1,8 +1,6 @@
|
|||||||
import pack from "@/package.json";
|
import pack from "@/package.json";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
export const experimental_ppr = true;
|
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
const t = useTranslations("Footer");
|
const t = useTranslations("Footer");
|
||||||
const version = pack.version;
|
const version = pack.version;
|
||||||
|
@ -11,8 +11,6 @@ import Image from "next/image";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
export const experimental_ppr = true;
|
|
||||||
|
|
||||||
function Header() {
|
function Header() {
|
||||||
const t = useTranslations("Header");
|
const t = useTranslations("Header");
|
||||||
const customLogo = getEnv("NEXT_PUBLIC_CustomLogo");
|
const customLogo = getEnv("NEXT_PUBLIC_CustomLogo");
|
||||||
|
@ -3,7 +3,6 @@ import ServerOverview from "@/components/ServerOverview";
|
|||||||
|
|
||||||
export const runtime = "edge";
|
export const runtime = "edge";
|
||||||
|
|
||||||
export const experimental_ppr = true;;
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto grid w-full max-w-5xl gap-4 md:gap-6">
|
<div className="mx-auto grid w-full max-w-5xl gap-4 md:gap-6">
|
||||||
|
@ -48,11 +48,15 @@ export default async function LocaleLayout({
|
|||||||
return (
|
return (
|
||||||
<html lang={locale} suppressHydrationWarning>
|
<html lang={locale} suppressHydrationWarning>
|
||||||
<head>
|
<head>
|
||||||
{!process.env.VERCEL && <PublicEnvScript />}
|
<PublicEnvScript />
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/gh/lipis/flag-icons@7.0.0/css/flag-icons.min.css"
|
href="https://cdn.jsdelivr.net/gh/lipis/flag-icons@7.0.0/css/flag-icons.min.css"
|
||||||
/>
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/font-logos@1/assets/font-logos.css"
|
||||||
|
/>
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
className={cn(
|
className={cn(
|
||||||
|
@ -4,6 +4,11 @@ import ServerUsageBar from "@/components/ServerUsageBar";
|
|||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
import getEnv from "@/lib/env-entry";
|
import getEnv from "@/lib/env-entry";
|
||||||
|
import {
|
||||||
|
GetFontLogoClass,
|
||||||
|
GetOsName,
|
||||||
|
MageMicrosoftWindows,
|
||||||
|
} from "@/lib/logo-class";
|
||||||
import { cn, formatBytes, formatNezhaInfo } from "@/lib/utils";
|
import { cn, formatBytes, formatNezhaInfo } from "@/lib/utils";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@ -16,7 +21,7 @@ export default function ServerCard({
|
|||||||
}) {
|
}) {
|
||||||
const t = useTranslations("ServerCard");
|
const t = useTranslations("ServerCard");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { id, name, country_code, online, cpu, up, down, mem, stg, tcp, udp } =
|
const { id, name, country_code, online, cpu, up, down, mem, stg, host } =
|
||||||
formatNezhaInfo(serverInfo);
|
formatNezhaInfo(serverInfo);
|
||||||
|
|
||||||
const showFlag = getEnv("NEXT_PUBLIC_ShowFlag") === "true";
|
const showFlag = getEnv("NEXT_PUBLIC_ShowFlag") === "true";
|
||||||
@ -64,9 +69,32 @@ export default function ServerCard({
|
|||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<section
|
<section
|
||||||
className={cn("grid grid-cols-5 items-center gap-3", {
|
className={cn("grid grid-cols-5 items-center gap-3", {
|
||||||
"lg:grid-cols-7": fixedTopServerName,
|
"lg:grid-cols-6 lg:gap-4": fixedTopServerName,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
{fixedTopServerName && (
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
"hidden col-span-1 items-center lg:flex lg:flex-row gap-2"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div className="text-xs font-semibold">
|
||||||
|
{host.Platform.includes("Windows") ? (
|
||||||
|
<MageMicrosoftWindows className="size-[10px]" />
|
||||||
|
) : (
|
||||||
|
<p className={`fl-${GetFontLogoClass(host.Platform)}`} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className={"flex w-14 flex-col"}>
|
||||||
|
<p className="text-xs text-muted-foreground">{t("System")}</p>
|
||||||
|
<div className="flex items-center text-[10.5px] font-semibold">
|
||||||
|
{host.Platform.includes("Windows")
|
||||||
|
? "Windows"
|
||||||
|
: GetOsName(host.Platform)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className={"flex w-14 flex-col"}>
|
<div className={"flex w-14 flex-col"}>
|
||||||
<p className="text-xs text-muted-foreground">{t("CPU")}</p>
|
<p className="text-xs text-muted-foreground">{t("CPU")}</p>
|
||||||
<div className="flex items-center text-xs font-semibold">
|
<div className="flex items-center text-xs font-semibold">
|
||||||
@ -104,28 +132,6 @@ export default function ServerCard({
|
|||||||
: `${down.toFixed(2)}M/s`}
|
: `${down.toFixed(2)}M/s`}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{fixedTopServerName && (
|
|
||||||
<div className={" w-14 flex-col hidden lg:flex"}>
|
|
||||||
<p className="text-xs text-muted-foreground">TCP</p>
|
|
||||||
<div className="flex items-center text-xs font-semibold gap-1">
|
|
||||||
<span className="relative inline-flex size-1.5 rounded-full bg-[hsl(var(--chart-1))]"></span>
|
|
||||||
<div className="flex items-center text-xs font-semibold">
|
|
||||||
{tcp}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{fixedTopServerName && (
|
|
||||||
<div className={"w-14 flex-col hidden lg:flex"}>
|
|
||||||
<p className="text-xs text-muted-foreground">UDP</p>
|
|
||||||
<div className="flex items-center text-xs font-semibold gap-1">
|
|
||||||
<span className="relative inline-flex size-1.5 rounded-full bg-[hsl(var(--chart-4))]"></span>
|
|
||||||
<div className="flex items-center text-xs font-semibold">
|
|
||||||
{udp}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</section>
|
</section>
|
||||||
{showNetTransfer && (
|
{showNetTransfer && (
|
||||||
<section
|
<section
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import { env } from "next-runtime-env";
|
import { env } from "next-runtime-env";
|
||||||
|
|
||||||
export default function getEnv(key: string) {
|
export default function getEnv(key: string) {
|
||||||
if (process.env.VERCEL) {
|
|
||||||
return process.env[key];
|
|
||||||
} else {
|
|
||||||
if (key.startsWith("NEXT_PUBLIC_")) {
|
if (key.startsWith("NEXT_PUBLIC_")) {
|
||||||
return env(key);
|
return env(key);
|
||||||
}
|
}
|
||||||
return process.env[key];
|
return process.env[key];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
149
lib/logo-class.tsx
Normal file
149
lib/logo-class.tsx
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import React from "react";
|
||||||
|
import type { SVGProps } from "react";
|
||||||
|
|
||||||
|
export function GetFontLogoClass(platform: string): string {
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
"almalinux",
|
||||||
|
"alpine",
|
||||||
|
"aosc",
|
||||||
|
"apple",
|
||||||
|
"archlinux",
|
||||||
|
"archlabs",
|
||||||
|
"artix",
|
||||||
|
"budgie",
|
||||||
|
"centos",
|
||||||
|
"coreos",
|
||||||
|
"debian",
|
||||||
|
"deepin",
|
||||||
|
"devuan",
|
||||||
|
"docker",
|
||||||
|
"elementary",
|
||||||
|
"fedora",
|
||||||
|
"ferris",
|
||||||
|
"flathub",
|
||||||
|
"freebsd",
|
||||||
|
"gentoo",
|
||||||
|
"gnu-guix",
|
||||||
|
"illumos",
|
||||||
|
"kali-linux",
|
||||||
|
"linuxmint",
|
||||||
|
"mageia",
|
||||||
|
"mandriva",
|
||||||
|
"manjaro",
|
||||||
|
"nixos",
|
||||||
|
"openbsd",
|
||||||
|
"opensuse",
|
||||||
|
"pop-os",
|
||||||
|
"raspberry-pi",
|
||||||
|
"redhat",
|
||||||
|
"rocky-linux",
|
||||||
|
"sabayon",
|
||||||
|
"slackware",
|
||||||
|
"snappy",
|
||||||
|
"solus",
|
||||||
|
"tux",
|
||||||
|
"ubuntu",
|
||||||
|
"void",
|
||||||
|
"zorin",
|
||||||
|
].indexOf(platform) > -1
|
||||||
|
) {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
if (platform == "darwin") {
|
||||||
|
return "apple";
|
||||||
|
}
|
||||||
|
if (["openwrt", "linux", "immortalwrt"].indexOf(platform) > -1) {
|
||||||
|
return "tux";
|
||||||
|
}
|
||||||
|
if (platform == "amazon") {
|
||||||
|
return "redhat";
|
||||||
|
}
|
||||||
|
if (platform == "arch") {
|
||||||
|
return "archlinux";
|
||||||
|
}
|
||||||
|
if (platform.toLowerCase().includes("opensuse")) {
|
||||||
|
return "opensuse";
|
||||||
|
}
|
||||||
|
return "tux";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetOsName(platform: string): string {
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
"almalinux",
|
||||||
|
"alpine",
|
||||||
|
"aosc",
|
||||||
|
"apple",
|
||||||
|
"archlinux",
|
||||||
|
"archlabs",
|
||||||
|
"artix",
|
||||||
|
"budgie",
|
||||||
|
"centos",
|
||||||
|
"coreos",
|
||||||
|
"debian",
|
||||||
|
"deepin",
|
||||||
|
"devuan",
|
||||||
|
"docker",
|
||||||
|
"fedora",
|
||||||
|
"ferris",
|
||||||
|
"flathub",
|
||||||
|
"freebsd",
|
||||||
|
"gentoo",
|
||||||
|
"gnu-guix",
|
||||||
|
"illumos",
|
||||||
|
"linuxmint",
|
||||||
|
"mageia",
|
||||||
|
"mandriva",
|
||||||
|
"manjaro",
|
||||||
|
"nixos",
|
||||||
|
"openbsd",
|
||||||
|
"opensuse",
|
||||||
|
"pop-os",
|
||||||
|
"redhat",
|
||||||
|
"sabayon",
|
||||||
|
"slackware",
|
||||||
|
"snappy",
|
||||||
|
"solus",
|
||||||
|
"tux",
|
||||||
|
"ubuntu",
|
||||||
|
"void",
|
||||||
|
"zorin",
|
||||||
|
].indexOf(platform) > -1
|
||||||
|
) {
|
||||||
|
return platform.charAt(0).toUpperCase() + platform.slice(1);
|
||||||
|
}
|
||||||
|
if (platform == "darwin") {
|
||||||
|
return "macOS";
|
||||||
|
}
|
||||||
|
if (["openwrt", "linux", "immortalwrt"].indexOf(platform) > -1) {
|
||||||
|
return "Linux";
|
||||||
|
}
|
||||||
|
if (platform == "amazon") {
|
||||||
|
return "Redhat";
|
||||||
|
}
|
||||||
|
if (platform == "arch") {
|
||||||
|
return "Archlinux";
|
||||||
|
}
|
||||||
|
if (platform.toLowerCase().includes("opensuse")) {
|
||||||
|
return "Opensuse";
|
||||||
|
}
|
||||||
|
return "Linux";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MageMicrosoftWindows(props: SVGProps<SVGSVGElement>) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M2.75 7.189V2.865c0-.102 0-.115.115-.115h8.622c.128 0 .14 0 .14.128V11.5c0 .128 0 .128-.14.128H2.865c-.102 0-.115 0-.115-.116zM7.189 21.25H2.865c-.102 0-.115 0-.115-.116V12.59c0-.128 0-.128.128-.128h8.635c.102 0 .115 0 .115.115v8.57c0 .09 0 .103-.116.103zM21.25 7.189v4.31c0 .116 0 .116-.116.116h-8.557c-.102 0-.128 0-.128-.115V2.865c0-.09 0-.102.115-.102h8.48c.206 0 .206 0 .206.205zm-8.763 9.661v-4.273c0-.09 0-.115.103-.09h8.621c.026 0 0 .09 0 .142v8.518a.06.06 0 0 1-.017.06a.06.06 0 0 1-.06.017H12.54s-.09 0-.077-.09V16.85z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
18
lib/utils.ts
18
lib/utils.ts
@ -10,16 +10,16 @@ export function formatNezhaInfo(serverInfo: NezhaAPISafe) {
|
|||||||
return {
|
return {
|
||||||
...serverInfo,
|
...serverInfo,
|
||||||
cpu: serverInfo.status.CPU,
|
cpu: serverInfo.status.CPU,
|
||||||
process: serverInfo.status.ProcessCount,
|
process: serverInfo.status.ProcessCount || 0,
|
||||||
up: serverInfo.status.NetOutSpeed / 1024 / 1024,
|
up: serverInfo.status.NetOutSpeed / 1024 / 1024 || 0,
|
||||||
down: serverInfo.status.NetInSpeed / 1024 / 1024,
|
down: serverInfo.status.NetInSpeed / 1024 / 1024 || 0,
|
||||||
online: serverInfo.online_status,
|
online: serverInfo.online_status,
|
||||||
tcp: serverInfo.status.TcpConnCount,
|
tcp: serverInfo.status.TcpConnCount || 0,
|
||||||
udp: serverInfo.status.UdpConnCount,
|
udp: serverInfo.status.UdpConnCount || 0,
|
||||||
mem: (serverInfo.status.MemUsed / serverInfo.host.MemTotal) * 100,
|
mem: (serverInfo.status.MemUsed / serverInfo.host.MemTotal) * 100 || 0,
|
||||||
swap: (serverInfo.status.SwapUsed / serverInfo.host.SwapTotal) * 100,
|
swap: (serverInfo.status.SwapUsed / serverInfo.host.SwapTotal) * 100 || 0,
|
||||||
disk: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100,
|
disk: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100 || 0,
|
||||||
stg: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100,
|
stg: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100 || 0,
|
||||||
country_code: serverInfo.host.CountryCode,
|
country_code: serverInfo.host.CountryCode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"defaultTag": "All"
|
"defaultTag": "All"
|
||||||
},
|
},
|
||||||
"ServerCard": {
|
"ServerCard": {
|
||||||
|
"System": "System",
|
||||||
"CPU": "CPU",
|
"CPU": "CPU",
|
||||||
"Mem": "Mem",
|
"Mem": "Mem",
|
||||||
"STG": "STG",
|
"STG": "STG",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"defaultTag": "すべて"
|
"defaultTag": "すべて"
|
||||||
},
|
},
|
||||||
"ServerCard": {
|
"ServerCard": {
|
||||||
|
"System": "システム",
|
||||||
"CPU": "CPU",
|
"CPU": "CPU",
|
||||||
"Mem": "Mem",
|
"Mem": "Mem",
|
||||||
"STG": "STG",
|
"STG": "STG",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"defaultTag": "全部"
|
"defaultTag": "全部"
|
||||||
},
|
},
|
||||||
"ServerCard": {
|
"ServerCard": {
|
||||||
|
"System": "系統",
|
||||||
"CPU": "CPU",
|
"CPU": "CPU",
|
||||||
"Mem": "記憶體",
|
"Mem": "記憶體",
|
||||||
"STG": "儲存",
|
"STG": "儲存",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"defaultTag": "全部"
|
"defaultTag": "全部"
|
||||||
},
|
},
|
||||||
"ServerCard": {
|
"ServerCard": {
|
||||||
|
"System": "系统",
|
||||||
"CPU": "CPU",
|
"CPU": "CPU",
|
||||||
"Mem": "内存",
|
"Mem": "内存",
|
||||||
"STG": "存储",
|
"STG": "存储",
|
||||||
|
@ -22,10 +22,6 @@ const withPWA = withPWAInit({
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
experimental: {
|
|
||||||
ppr: "incremental",
|
|
||||||
},
|
|
||||||
reactStrictMode: true,
|
|
||||||
logging: {
|
logging: {
|
||||||
fetches: {
|
fetches: {
|
||||||
fullUrl: true,
|
fullUrl: true,
|
||||||
|
12
package.json
12
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nezha-dash",
|
"name": "nezha-dash",
|
||||||
"version": "1.2.5",
|
"version": "1.2.6",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev -p 3020",
|
"dev": "next dev -p 3020",
|
||||||
@ -22,8 +22,8 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.1.3",
|
"@radix-ui/react-tooltip": "^1.1.3",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.12.2",
|
"@typescript-eslint/eslint-plugin": "^8.13.0",
|
||||||
"caniuse-lite": "^1.0.30001677",
|
"caniuse-lite": "^1.0.30001678",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"country-flag-icons": "^1.5.13",
|
"country-flag-icons": "^1.5.13",
|
||||||
@ -32,7 +32,7 @@
|
|||||||
"framer-motion": "^12.0.0-alpha.1",
|
"framer-motion": "^12.0.0-alpha.1",
|
||||||
"lucide-react": "^0.454.0",
|
"lucide-react": "^0.454.0",
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"next": "^15.0.3-canary.5",
|
"next": "^15.0.2",
|
||||||
"next-auth": "^5.0.0-beta.25",
|
"next-auth": "^5.0.0-beta.25",
|
||||||
"next-intl": "^3.24.0",
|
"next-intl": "^3.24.0",
|
||||||
"next-runtime-env": "^3.2.2",
|
"next-runtime-env": "^3.2.2",
|
||||||
@ -47,13 +47,13 @@
|
|||||||
"swr": "^2.2.6-beta.4",
|
"swr": "^2.2.6-beta.4",
|
||||||
"tailwind-merge": "^2.5.4",
|
"tailwind-merge": "^2.5.4",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"typescript-eslint": "^8.12.2"
|
"typescript-eslint": "^8.13.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint-plugin-turbo": "^2.2.3",
|
"eslint-plugin-turbo": "^2.2.3",
|
||||||
"eslint-plugin-unused-imports": "^4.1.4",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"@next/bundle-analyzer": "15.0.2",
|
"@next/bundle-analyzer": "15.0.2",
|
||||||
"@types/node": "^22.8.7",
|
"@types/node": "^22.9.0",
|
||||||
"@types/react": "npm:types-react@19.0.0-rc.1",
|
"@types/react": "npm:types-react@19.0.0-rc.1",
|
||||||
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
|
Loading…
Reference in New Issue
Block a user