mirror of
https://github.com/hamster1963/nezha-dash.git
synced 2025-04-24 21:10:45 +08:00
perf: fully optimize
This commit is contained in:
parent
646354e515
commit
f9f57e4d19
@ -40,7 +40,7 @@ export default function ServerDetailClient({
|
||||
if (hasHistory) {
|
||||
router.back()
|
||||
} else {
|
||||
router.push(`/`)
|
||||
router.push("/")
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,8 +120,8 @@ export default function ServerDetailClient({
|
||||
<div className="text-xs">
|
||||
{" "}
|
||||
{uptime / 86400 >= 1
|
||||
? (uptime / 86400).toFixed(0) + " " + t("Days")
|
||||
: (uptime / 3600).toFixed(0) + " " + t("Hours")}{" "}
|
||||
? `${(uptime / 86400).toFixed(0)} ${t("Days")}`
|
||||
: `${(uptime / 3600).toFixed(0)} ${t("Hours")}`}
|
||||
</div>
|
||||
</section>
|
||||
</CardContent>
|
||||
|
@ -24,7 +24,7 @@ export default function ServerGlobal() {
|
||||
const countryList: string[] = []
|
||||
const serverCounts: { [key: string]: number } = {}
|
||||
|
||||
nezhaServerList.result.forEach((server) => {
|
||||
for (const server of nezhaServerList.result) {
|
||||
if (server.host.CountryCode) {
|
||||
const countryCode = server.host.CountryCode.toUpperCase()
|
||||
if (!countryList.includes(countryCode)) {
|
||||
@ -32,7 +32,7 @@ export default function ServerGlobal() {
|
||||
}
|
||||
serverCounts[countryCode] = (serverCounts[countryCode] || 0) + 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const width = 900
|
||||
const height = 500
|
||||
|
@ -40,6 +40,7 @@ export function InteractiveMap({
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="w-full h-auto"
|
||||
>
|
||||
<title>Interactive Map</title>
|
||||
<defs>
|
||||
<pattern id="dots" width="2" height="2" patternUnits="userSpaceOnUse">
|
||||
<circle cx="1" cy="1" r="0.5" fill="currentColor" />
|
||||
@ -55,14 +56,14 @@ export function InteractiveMap({
|
||||
fill="transparent"
|
||||
onMouseEnter={() => setTooltipData(null)}
|
||||
/>
|
||||
{filteredFeatures.map((feature, index) => {
|
||||
{filteredFeatures.map((feature) => {
|
||||
const isHighlighted = countries.includes(feature.properties.iso_a2_eh)
|
||||
|
||||
const serverCount = serverCounts[feature.properties.iso_a2_eh] || 0
|
||||
|
||||
return (
|
||||
<path
|
||||
key={index}
|
||||
key={feature.properties.iso_a2_eh}
|
||||
d={path(feature) || ""}
|
||||
className={
|
||||
isHighlighted
|
||||
|
@ -42,13 +42,13 @@ const MapTooltip = memo(function MapTooltip() {
|
||||
overflowY: "auto",
|
||||
}}
|
||||
>
|
||||
{sortedServers.map((server, index) => (
|
||||
<div key={index} className="flex items-center gap-1.5 py-0.5">
|
||||
{sortedServers.map((server) => (
|
||||
<div key={server.name} className="flex items-center gap-1.5 py-0.5">
|
||||
<span
|
||||
className={`w-1.5 h-1.5 shrink-0 rounded-full ${
|
||||
server.status ? "bg-green-500" : "bg-red-500"
|
||||
}`}
|
||||
></span>
|
||||
/>
|
||||
<span className="text-xs">{server.name}</span>
|
||||
</div>
|
||||
))}
|
||||
|
@ -124,16 +124,17 @@ export default function ServerListClient() {
|
||||
}
|
||||
|
||||
const tagCountMap: Record<string, number> = {}
|
||||
filteredServersByStatus.forEach((server) => {
|
||||
for (const server of filteredServersByStatus) {
|
||||
if (server.tag) {
|
||||
tagCountMap[server.tag] = (tagCountMap[server.tag] || 0) + 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="flex items-center gap-2 w-full overflow-hidden">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setShowMap(!showMap)
|
||||
}}
|
||||
@ -147,6 +148,7 @@ export default function ServerListClient() {
|
||||
<MapIcon className="size-[13px]" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setInline(inline === "0" ? "1" : "0")
|
||||
localStorage.setItem("inline", inline === "0" ? "1" : "0")
|
||||
|
@ -46,7 +46,7 @@ export default function ServerOverviewClient() {
|
||||
<p className="text-sm font-medium md:text-base">{t("p_816-881_Totalservers")}</p>
|
||||
<div className="flex items-center gap-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>
|
||||
{data?.result ? (
|
||||
<div className="text-lg font-semibold">{data?.result.length}</div>
|
||||
@ -76,8 +76,8 @@ export default function ServerOverviewClient() {
|
||||
<p className="text-sm font-medium md:text-base">{t("p_1610-1676_Onlineservers")}</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<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="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-500 opacity-75" />
|
||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-green-500" />
|
||||
</span>
|
||||
{data?.result ? (
|
||||
<div className="text-lg font-semibold">{data?.live_servers}</div>
|
||||
@ -107,8 +107,8 @@ export default function ServerOverviewClient() {
|
||||
<p className="text-sm font-medium md:text-base">{t("p_2532-2599_Offlineservers")}</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<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="absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75" />
|
||||
<span className="relative inline-flex h-2 w-2 rounded-full bg-red-500" />
|
||||
</span>
|
||||
{data?.result ? (
|
||||
<div className="text-lg font-semibold">{data?.offline_servers}</div>
|
||||
|
@ -28,7 +28,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
try {
|
||||
const serverIdNum = Number.parseInt(server_id, 10)
|
||||
if (isNaN(serverIdNum)) {
|
||||
if (Number.isNaN(serverIdNum)) {
|
||||
return NextResponse.json({ error: "server_id must be a valid number" }, { status: 400 })
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
try {
|
||||
const serverIdNum = Number.parseInt(server_id, 10)
|
||||
if (isNaN(serverIdNum)) {
|
||||
if (Number.isNaN(serverIdNum)) {
|
||||
return NextResponse.json({ error: "server_id must be a number" }, { status: 400 })
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false },
|
||||
"files": { "ignoreUnknown": false, "ignore": [".next", "public"] },
|
||||
"files": { "ignoreUnknown": false, "ignore": [".next", "public", "styles/globals.css"] },
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"useEditorconfig": true,
|
||||
@ -20,6 +20,9 @@
|
||||
"a11y": {
|
||||
"useKeyWithClickEvents": "off"
|
||||
},
|
||||
"security": {
|
||||
"noDangerouslySetInnerHtml": "off"
|
||||
},
|
||||
"complexity": { "noUselessTypeConstraint": "error" },
|
||||
"correctness": {
|
||||
"noUnusedVariables": "error",
|
||||
|
@ -38,6 +38,7 @@ export default function AnimatedCircularProgressBar({
|
||||
}
|
||||
>
|
||||
<svg fill="none" className="size-full" strokeWidth="2" viewBox="0 0 100 100">
|
||||
<title>Circular Progress Bar</title>
|
||||
{currentPercent <= 90 && currentPercent >= 0 && (
|
||||
<circle
|
||||
cx="50"
|
||||
|
@ -49,16 +49,16 @@ export function GetFontLogoClass(platform: string): string {
|
||||
) {
|
||||
return platform
|
||||
}
|
||||
if (platform == "darwin") {
|
||||
if (platform === "darwin") {
|
||||
return "apple"
|
||||
}
|
||||
if (["openwrt", "linux", "immortalwrt"].indexOf(platform) > -1) {
|
||||
return "tux"
|
||||
}
|
||||
if (platform == "amazon") {
|
||||
if (platform === "amazon") {
|
||||
return "redhat"
|
||||
}
|
||||
if (platform == "arch") {
|
||||
if (platform === "arch") {
|
||||
return "archlinux"
|
||||
}
|
||||
if (platform.toLowerCase().includes("opensuse")) {
|
||||
@ -112,16 +112,16 @@ export function GetOsName(platform: string): string {
|
||||
) {
|
||||
return platform.charAt(0).toUpperCase() + platform.slice(1)
|
||||
}
|
||||
if (platform == "darwin") {
|
||||
if (platform === "darwin") {
|
||||
return "macOS"
|
||||
}
|
||||
if (["openwrt", "linux", "immortalwrt"].indexOf(platform) > -1) {
|
||||
return "Linux"
|
||||
}
|
||||
if (platform == "amazon") {
|
||||
if (platform === "amazon") {
|
||||
return "Redhat"
|
||||
}
|
||||
if (platform == "arch") {
|
||||
if (platform === "arch") {
|
||||
return "Archlinux"
|
||||
}
|
||||
if (platform.toLowerCase().includes("opensuse")) {
|
||||
@ -133,10 +133,11 @@ export function GetOsName(platform: string): string {
|
||||
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}>
|
||||
<title>Mage Microsoft Windows</title>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
@variant dark (&:is(.dark *));
|
||||
|
||||
@theme {
|
||||
--font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
||||
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--font-sans: var(--font-sans), ui-sans-serif, system-ui, sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
|
||||
--color-border: hsl(var(--border));
|
||||
--color-input: hsl(var(--input));
|
||||
|
Loading…
Reference in New Issue
Block a user