Compare commits

...

3 Commits

Author SHA1 Message Date
hamster1963
b9e6cd750d update: v1.2.6 2024-11-07 14:28:50 +08:00
hamster1963
d6be65e321 fix(DetailChart): NaN on detail chart 2024-11-07 14:24:15 +08:00
hamster1963
adaea14bc9 feat(ServerCard): refactor card section when FixedTopServerName is enabled 2024-11-07 14:23:40 +08:00
15 changed files with 206 additions and 52 deletions

View File

@ -1,8 +1,6 @@
import pack from "@/package.json";
import { useTranslations } from "next-intl";
export const experimental_ppr = true;
export default function Footer() {
const t = useTranslations("Footer");
const version = pack.version;

View File

@ -11,8 +11,6 @@ import Image from "next/image";
import { useRouter } from "next/navigation";
import React, { useEffect, useRef, useState } from "react";
export const experimental_ppr = true;
function Header() {
const t = useTranslations("Header");
const customLogo = getEnv("NEXT_PUBLIC_CustomLogo");

View File

@ -1,7 +1,6 @@
import ServerList from "@/components/ServerList";
import ServerOverview from "@/components/ServerOverview";
export const experimental_ppr = true;
export default function Home() {
return (
<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"
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>
<body
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 { Card } from "@/components/ui/card";
import getEnv from "@/lib/env-entry";
import {
GetFontLogoClass,
GetOsName,
MageMicrosoftWindows,
} from "@/lib/logo-class";
import { cn, formatBytes, formatNezhaInfo } from "@/lib/utils";
import { useTranslations } from "next-intl";
import Link from "next/link";
@ -16,7 +21,7 @@ export default function ServerCard({
}) {
const t = useTranslations("ServerCard");
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);
const showFlag = getEnv("NEXT_PUBLIC_ShowFlag") === "true";
@ -64,9 +69,32 @@ export default function ServerCard({
<div className="flex flex-col gap-2">
<section
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"}>
<p className="text-xs text-muted-foreground">{t("CPU")}</p>
<div className="flex items-center text-xs font-semibold">
@ -104,28 +132,6 @@ export default function ServerCard({
: `${down.toFixed(2)}M/s`}
</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>
{showNetTransfer && (
<section

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 {
...serverInfo,
cpu: serverInfo.status.CPU,
process: serverInfo.status.ProcessCount,
up: serverInfo.status.NetOutSpeed / 1024 / 1024,
down: serverInfo.status.NetInSpeed / 1024 / 1024,
process: serverInfo.status.ProcessCount || 0,
up: serverInfo.status.NetOutSpeed / 1024 / 1024 || 0,
down: serverInfo.status.NetInSpeed / 1024 / 1024 || 0,
online: serverInfo.online_status,
tcp: serverInfo.status.TcpConnCount,
udp: serverInfo.status.UdpConnCount,
mem: (serverInfo.status.MemUsed / serverInfo.host.MemTotal) * 100,
swap: (serverInfo.status.SwapUsed / serverInfo.host.SwapTotal) * 100,
disk: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100,
stg: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100,
tcp: serverInfo.status.TcpConnCount || 0,
udp: serverInfo.status.UdpConnCount || 0,
mem: (serverInfo.status.MemUsed / serverInfo.host.MemTotal) * 100 || 0,
swap: (serverInfo.status.SwapUsed / serverInfo.host.SwapTotal) * 100 || 0,
disk: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100 || 0,
stg: (serverInfo.status.DiskUsed / serverInfo.host.DiskTotal) * 100 || 0,
country_code: serverInfo.host.CountryCode,
};
}

View File

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

View File

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

View File

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

View File

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

View File

@ -22,10 +22,6 @@ const withPWA = withPWAInit({
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
experimental: {
ppr: "incremental",
},
reactStrictMode: true,
logging: {
fetches: {
fullUrl: true,

View File

@ -1,6 +1,6 @@
{
"name": "nezha-dash",
"version": "1.2.5",
"version": "1.2.6",
"private": true,
"scripts": {
"dev": "next dev -p 3020",
@ -22,8 +22,8 @@
"@radix-ui/react-tooltip": "^1.1.3",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/luxon": "^3.4.2",
"@typescript-eslint/eslint-plugin": "^8.12.2",
"caniuse-lite": "^1.0.30001677",
"@typescript-eslint/eslint-plugin": "^8.13.0",
"caniuse-lite": "^1.0.30001678",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"country-flag-icons": "^1.5.13",
@ -32,7 +32,7 @@
"framer-motion": "^12.0.0-alpha.1",
"lucide-react": "^0.454.0",
"luxon": "^3.5.0",
"next": "^15.0.3-canary.5",
"next": "^15.0.2",
"next-auth": "^5.0.0-beta.25",
"next-intl": "^3.24.0",
"next-runtime-env": "^3.2.2",
@ -47,13 +47,13 @@
"swr": "^2.2.6-beta.4",
"tailwind-merge": "^2.5.4",
"tailwindcss-animate": "^1.0.7",
"typescript-eslint": "^8.12.2"
"typescript-eslint": "^8.13.0"
},
"devDependencies": {
"eslint-plugin-turbo": "^2.2.3",
"eslint-plugin-unused-imports": "^4.1.4",
"@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-dom": "npm:types-react-dom@19.0.0-rc.1",
"autoprefixer": "^10.4.20",