mirror of
https://github.com/hamster1963/nezha-dash.git
synced 2025-04-24 21:10:45 +08:00
refactor: modularize ServerListClient with utility functions and components
This commit is contained in:
parent
1713189333
commit
07afc44eb7
@ -20,6 +20,77 @@ const ServerGlobal = dynamic(() => import("./Global"), {
|
||||
loading: () => <GlobalLoading />,
|
||||
})
|
||||
|
||||
const sortServersByDisplayIndex = (servers: any[]) => {
|
||||
return servers.sort((a, b) => {
|
||||
const displayIndexDiff = (b.display_index || 0) - (a.display_index || 0)
|
||||
return displayIndexDiff !== 0 ? displayIndexDiff : a.id - b.id
|
||||
})
|
||||
}
|
||||
|
||||
const filterServersByStatus = (servers: any[], status: string) => {
|
||||
return status === "all"
|
||||
? servers
|
||||
: servers.filter((server) => [status].includes(server.online_status ? "online" : "offline"))
|
||||
}
|
||||
|
||||
const filterServersByTag = (servers: any[], tag: string, defaultTag: string) => {
|
||||
return tag === defaultTag ? servers : servers.filter((server) => server.tag === tag)
|
||||
}
|
||||
|
||||
const sortServersByNetwork = (servers: any[]) => {
|
||||
return [...servers].sort((a, b) => {
|
||||
if (!a.online_status && b.online_status) return 1
|
||||
if (a.online_status && !b.online_status) return -1
|
||||
if (!a.online_status && !b.online_status) return 0
|
||||
return b.status.NetInSpeed + b.status.NetOutSpeed - (a.status.NetInSpeed + a.status.NetOutSpeed)
|
||||
})
|
||||
}
|
||||
|
||||
const getTagCounts = (servers: any[]) => {
|
||||
return servers.reduce((acc: Record<string, number>, server) => {
|
||||
if (server.tag) {
|
||||
acc[server.tag] = (acc[server.tag] || 0) + 1
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
const LoadingState = ({ t }: { t: any }) => (
|
||||
<div className="flex flex-col items-center min-h-96 justify-center ">
|
||||
<div className="font-semibold flex items-center gap-2 text-sm">
|
||||
<Loader visible={true} />
|
||||
{t("connecting")}...
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
const ErrorState = ({ error, t }: { error: Error; t: any }) => (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<p className="text-sm font-medium opacity-40">{error.message}</p>
|
||||
<p className="text-sm font-medium opacity-40">{t("error_message")}</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
const ServerList = ({ servers, inline, containerRef }: { servers: any[]; inline: string; containerRef: any }) => {
|
||||
if (inline === "1") {
|
||||
return (
|
||||
<section ref={containerRef} className="flex flex-col gap-2 overflow-x-scroll scrollbar-hidden">
|
||||
{servers.map((serverInfo) => (
|
||||
<ServerCardInline key={serverInfo.id} serverInfo={serverInfo} />
|
||||
))}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section ref={containerRef} className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
||||
{servers.map((serverInfo) => (
|
||||
<ServerCard key={serverInfo.id} serverInfo={serverInfo} />
|
||||
))}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default function ServerListClient() {
|
||||
const { status } = useStatus()
|
||||
const { filter } = useFilter()
|
||||
@ -36,12 +107,9 @@ export default function ServerListClient() {
|
||||
if (inlineState !== null) {
|
||||
setInline(inlineState)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const savedTag = sessionStorage.getItem("selectedTag") || defaultTag
|
||||
setTag(savedTag)
|
||||
|
||||
restoreScrollPosition()
|
||||
}, [])
|
||||
|
||||
@ -71,73 +139,30 @@ export default function ServerListClient() {
|
||||
|
||||
const { data, error } = useServerData()
|
||||
|
||||
if (error)
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<p className="text-sm font-medium opacity-40">{error.message}</p>
|
||||
<p className="text-sm font-medium opacity-40">{t("error_message")}</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (!data?.result)
|
||||
return (
|
||||
<div className="flex flex-col items-center min-h-96 justify-center ">
|
||||
<div className="font-semibold flex items-center gap-2 text-sm">
|
||||
<Loader visible={true} />
|
||||
{t("connecting")}...
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
if (error) return <ErrorState error={error} t={t} />
|
||||
if (!data?.result) return <LoadingState t={t} />
|
||||
|
||||
const { result } = data
|
||||
const sortedServers = result.sort((a, b) => {
|
||||
const displayIndexDiff = (b.display_index || 0) - (a.display_index || 0)
|
||||
if (displayIndexDiff !== 0) return displayIndexDiff
|
||||
return a.id - b.id
|
||||
})
|
||||
|
||||
const filteredServersByStatus =
|
||||
status === "all"
|
||||
? sortedServers
|
||||
: sortedServers.filter((server) =>
|
||||
[status].includes(server.online_status ? "online" : "offline"),
|
||||
)
|
||||
|
||||
const sortedServers = sortServersByDisplayIndex(result)
|
||||
const filteredServersByStatus = filterServersByStatus(sortedServers, status)
|
||||
const allTag = filteredServersByStatus.map((server) => server.tag).filter(Boolean)
|
||||
const uniqueTags = [...new Set(allTag)]
|
||||
uniqueTags.unshift(defaultTag)
|
||||
|
||||
const filteredServers =
|
||||
tag === defaultTag
|
||||
? filteredServersByStatus
|
||||
: filteredServersByStatus.filter((server) => server.tag === tag)
|
||||
let filteredServers = filterServersByTag(filteredServersByStatus, tag, defaultTag)
|
||||
|
||||
if (filter) {
|
||||
filteredServers.sort((a, b) => {
|
||||
if (!a.online_status && b.online_status) return 1
|
||||
if (a.online_status && !b.online_status) return -1
|
||||
if (!a.online_status && !b.online_status) return 0
|
||||
return (
|
||||
b.status.NetInSpeed + b.status.NetOutSpeed - (a.status.NetInSpeed + a.status.NetOutSpeed)
|
||||
)
|
||||
})
|
||||
filteredServers = sortServersByNetwork(filteredServers)
|
||||
}
|
||||
|
||||
const tagCountMap: Record<string, number> = {}
|
||||
for (const server of filteredServersByStatus) {
|
||||
if (server.tag) {
|
||||
tagCountMap[server.tag] = (tagCountMap[server.tag] || 0) + 1
|
||||
}
|
||||
}
|
||||
const tagCountMap = getTagCounts(filteredServersByStatus)
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="flex items-center gap-2 w-full overflow-hidden">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setShowMap(!showMap)
|
||||
}}
|
||||
onClick={() => setShowMap(!showMap)}
|
||||
className={cn(
|
||||
"rounded-[50px] text-white cursor-pointer [text-shadow:_0_1px_0_rgb(0_0_0_/_20%)] bg-blue-600 p-[10px] transition-all shadow-[inset_0_1px_0_rgba(255,255,255,0.2)]",
|
||||
{
|
||||
@ -150,11 +175,12 @@ export default function ServerListClient() {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setInline(inline === "0" ? "1" : "0")
|
||||
localStorage.setItem("inline", inline === "0" ? "1" : "0")
|
||||
const newInline = inline === "0" ? "1" : "0"
|
||||
setInline(newInline)
|
||||
localStorage.setItem("inline", newInline)
|
||||
}}
|
||||
className={cn(
|
||||
"rounded-[50px] text-white cursor-pointer [text-shadow:_0_1px_0_rgb(0_0_0_/_20%)] bg-blue-600 p-[10px] transition-all shadow-[inset_0_1px_0_rgba(255,255,255,0.2)] ",
|
||||
"rounded-[50px] text-white cursor-pointer [text-shadow:_0_1px_0_rgb(0_0_0_/_20%)] bg-blue-600 p-[10px] transition-all shadow-[inset_0_1px_0_rgba(255,255,255,0.2)]",
|
||||
{
|
||||
"shadow-[inset_0_1px_0_rgba(0,0,0,0.2)] bg-blue-500": inline === "1",
|
||||
},
|
||||
@ -172,24 +198,7 @@ export default function ServerListClient() {
|
||||
)}
|
||||
</section>
|
||||
{showMap && <ServerGlobal />}
|
||||
{inline === "1" && (
|
||||
<section
|
||||
ref={containerRef}
|
||||
className="flex flex-col gap-2 overflow-x-scroll scrollbar-hidden"
|
||||
>
|
||||
{filteredServers.map((serverInfo) => (
|
||||
<ServerCardInline key={serverInfo.id} serverInfo={serverInfo} />
|
||||
))}
|
||||
</section>
|
||||
)}
|
||||
|
||||
{inline === "0" && (
|
||||
<section ref={containerRef} className="grid grid-cols-1 gap-2 md:grid-cols-2">
|
||||
{filteredServers.map((serverInfo) => (
|
||||
<ServerCard key={serverInfo.id} serverInfo={serverInfo} />
|
||||
))}
|
||||
</section>
|
||||
)}
|
||||
<ServerList servers={filteredServers} inline={inline} containerRef={containerRef} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user