mirror of
https://github.com/hamster1963/nezha-dash.git
synced 2025-04-24 21:10:45 +08:00
feat: ip info
This commit is contained in:
parent
d72cd29446
commit
33d22fa8b3
@ -15,3 +15,4 @@ NEXT_PUBLIC_CustomDescription=NezhaDash is a dashboard for Nezha.
|
|||||||
NEXT_PUBLIC_Links='[{"link":"https://github.com/hamster1963/nezha-dash","name":"GitHub"},{"link":"https://buycoffee.top/coffee","name":"Buycoffee☕️"}]'
|
NEXT_PUBLIC_Links='[{"link":"https://github.com/hamster1963/nezha-dash","name":"GitHub"},{"link":"https://buycoffee.top/coffee","name":"Buycoffee☕️"}]'
|
||||||
NEXT_PUBLIC_DisableIndex=false
|
NEXT_PUBLIC_DisableIndex=false
|
||||||
NEXT_PUBLIC_ShowTagCount=false
|
NEXT_PUBLIC_ShowTagCount=false
|
||||||
|
NEXT_PUBLIC_ShowIpInfo=false
|
||||||
|
@ -1,24 +1,111 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { IPInfo } from "@/app/api/server-ip/route";
|
import { IPInfo } from "@/app/api/server-ip/route";
|
||||||
|
import { Loader } from "@/components/loading/Loader";
|
||||||
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import { nezhaFetcher } from "@/lib/utils";
|
import { nezhaFetcher } from "@/lib/utils";
|
||||||
import useSWR from "swr";
|
import useSWRImmutable from "swr/immutable";
|
||||||
|
|
||||||
export default function ServerIPInfo({ server_id }: { server_id: number }) {
|
export default function ServerIPInfo({ server_id }: { server_id: number }) {
|
||||||
const { data } = useSWR<IPInfo>(
|
const { data } = useSWRImmutable<IPInfo>(
|
||||||
`/api/server-ip?server_id=${server_id}`,
|
`/api/server-ip?server_id=${server_id}`,
|
||||||
nezhaFetcher,
|
nezhaFetcher,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return <div>Loading...</div>;
|
return (
|
||||||
|
<div className="mb-11">
|
||||||
|
<Loader visible />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<h1>Server IP Info</h1>
|
<section className="flex flex-wrap gap-2 mb-4">
|
||||||
</div>
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"ASN"}</p>
|
||||||
|
<div className="text-xs">
|
||||||
|
{data.asn.autonomous_system_organization}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"Origin ASN"}</p>
|
||||||
|
<div className="text-xs">
|
||||||
|
AS{data.asn.autonomous_system_number}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
{"Registered Country"}
|
||||||
|
</p>
|
||||||
|
<div className="text-xs">
|
||||||
|
{data.city.registered_country?.names.en}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"Time Zone"}</p>
|
||||||
|
<div className="text-xs">{data.city.location?.time_zone}</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
{data.city.postal && (
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"Postal"}</p>
|
||||||
|
<div className="text-xs">{data.city.postal?.code}</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"ISO"}</p>
|
||||||
|
<div className="text-xs">{data.city.country?.iso_code}</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"City"}</p>
|
||||||
|
<div className="text-xs">{data.city.city?.names.en}</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"Longitude"}</p>
|
||||||
|
<div className="text-xs">{data.city.location?.longitude}</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="rounded-[10px] bg-transparent border-none shadow-none">
|
||||||
|
<CardContent className="px-1.5 py-1">
|
||||||
|
<section className="flex flex-col items-start gap-0.5">
|
||||||
|
<p className="text-xs text-muted-foreground">{"Latitude"}</p>
|
||||||
|
<div className="text-xs">{data.city.location?.latitude}</div>
|
||||||
|
</section>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</section>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import ServerDetailChartClient from "@/app/(main)/ClientComponents/ServerDetailC
|
|||||||
import ServerDetailClient from "@/app/(main)/ClientComponents/ServerDetailClient";
|
import ServerDetailClient from "@/app/(main)/ClientComponents/ServerDetailClient";
|
||||||
import TabSwitch from "@/components/TabSwitch";
|
import TabSwitch from "@/components/TabSwitch";
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import getEnv from "@/lib/env-entry";
|
||||||
import { use, useState } from "react";
|
import { use, useState } from "react";
|
||||||
|
|
||||||
import ServerIPInfo from "../../ClientComponents/ServerIPInfo";
|
import ServerIPInfo from "../../ClientComponents/ServerIPInfo";
|
||||||
@ -16,7 +17,6 @@ export default function Page(props: { params: Promise<{ id: string }> }) {
|
|||||||
return (
|
return (
|
||||||
<div className="mx-auto grid w-full max-w-5xl gap-2">
|
<div className="mx-auto grid w-full max-w-5xl gap-2">
|
||||||
<ServerDetailClient server_id={Number(params.id)} />
|
<ServerDetailClient server_id={Number(params.id)} />
|
||||||
<ServerIPInfo server_id={Number(params.id)} />
|
|
||||||
<section className="flex items-center my-2 w-full">
|
<section className="flex items-center my-2 w-full">
|
||||||
<Separator className="flex-1" />
|
<Separator className="flex-1" />
|
||||||
<div className="flex justify-center w-full max-w-[200px]">
|
<div className="flex justify-center w-full max-w-[200px]">
|
||||||
@ -35,6 +35,9 @@ export default function Page(props: { params: Promise<{ id: string }> }) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: currentTab === tabs[1] ? "block" : "none" }}>
|
<div style={{ display: currentTab === tabs[1] ? "block" : "none" }}>
|
||||||
|
{getEnv("NEXT_PUBLIC_ShowIpInfo") && (
|
||||||
|
<ServerIPInfo server_id={Number(params.id)} />
|
||||||
|
)}
|
||||||
<NetworkChartClient
|
<NetworkChartClient
|
||||||
server_id={Number(params.id)}
|
server_id={Number(params.id)}
|
||||||
show={currentTab === tabs[1]}
|
show={currentTab === tabs[1]}
|
||||||
|
@ -27,6 +27,13 @@ export async function GET(req: NextRequest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!getEnv("NEXT_PUBLIC_ShowIpInfo")) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "NEXT_PUBLIC_ShowIpInfo is disable" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const { searchParams } = new URL(req.url);
|
const { searchParams } = new URL(req.url);
|
||||||
const server_id = searchParams.get("server_id");
|
const server_id = searchParams.get("server_id");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user