Merge branch 'hamster1963:main' into main

This commit is contained in:
kattocloud 2024-11-07 14:41:06 +08:00 committed by GitHub
commit 161a57f560
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 206 additions and 52 deletions

View File

@ -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;

View File

@ -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");

View File

@ -1,7 +1,6 @@
import ServerList from "@/components/ServerList"; import ServerList from "@/components/ServerList";
import ServerOverview from "@/components/ServerOverview"; import ServerOverview from "@/components/ServerOverview";
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">

View File

@ -53,6 +53,10 @@ export default async function LocaleLayout({
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(

BIN
bun.lockb

Binary file not shown.

View File

@ -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

View File

@ -1,8 +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 (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
View 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>
);
}

View File

@ -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,
}; };
} }

View File

@ -12,6 +12,7 @@
"defaultTag": "All" "defaultTag": "All"
}, },
"ServerCard": { "ServerCard": {
"System": "System",
"CPU": "CPU", "CPU": "CPU",
"Mem": "Mem", "Mem": "Mem",
"STG": "STG", "STG": "STG",

View File

@ -12,6 +12,7 @@
"defaultTag": "すべて" "defaultTag": "すべて"
}, },
"ServerCard": { "ServerCard": {
"System": "システム",
"CPU": "CPU", "CPU": "CPU",
"Mem": "Mem", "Mem": "Mem",
"STG": "STG", "STG": "STG",

View File

@ -12,6 +12,7 @@
"defaultTag": "全部" "defaultTag": "全部"
}, },
"ServerCard": { "ServerCard": {
"System": "系統",
"CPU": "CPU", "CPU": "CPU",
"Mem": "記憶體", "Mem": "記憶體",
"STG": "儲存", "STG": "儲存",

View File

@ -12,6 +12,7 @@
"defaultTag": "全部" "defaultTag": "全部"
}, },
"ServerCard": { "ServerCard": {
"System": "系统",
"CPU": "CPU", "CPU": "CPU",
"Mem": "内存", "Mem": "内存",
"STG": "存储", "STG": "存储",

View File

@ -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,

View File

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