This commit is contained in:
ryan
2026-07-13 15:08:40 +08:00
parent 08e8eea932
commit 1eff7878a1
441 changed files with 26491 additions and 18405 deletions
@@ -1,21 +1,21 @@
'use client';
import Link from 'next/link';
import {useMemo} from 'react';
import {useSearchParams} from 'next/navigation';
import {useQuery} from '@tanstack/react-query';
import {ArrowLeft, Server} from 'lucide-react';
import { useMemo } from 'react';
import { useSearchParams } from 'next/navigation';
import { useQuery } from '@tanstack/react-query';
import { ArrowLeft, Server } from 'lucide-react';
import {Button} from '@/components/ui/button';
import {EmptyStateWithBorder} from '@/components/layout/empty';
import {ErrorInline} from '@/components/layout/error';
import {LoadingStateWithBorder} from '@/components/layout/loading';
import {NodeService} from '@/lib/services/openflare';
import { Button } from '@/components/ui/button';
import { EmptyStateWithBorder } from '@/components/layout/empty';
import { ErrorInline } from '@/components/layout/error';
import { LoadingStateWithBorder } from '@/components/layout/loading';
import { NodeService } from '@/lib/services/openflare';
import {EdgeNodeDetail} from '../components/edge-node-detail';
import {RelayNodeDetail} from '../components/relay-node-detail';
import {TunnelNodeDetail} from '../components/tunnel-node-detail';
import {getErrorMessage} from '../components/node-utils';
import { EdgeNodeDetail } from '../components/edge-node-detail';
import { RelayNodeDetail } from '../components/relay-node-detail';
import { TunnelNodeDetail } from '../components/tunnel-node-detail';
import { getErrorMessage } from '../components/node-utils';
const nodesQueryKey = ['openflare', 'nodes'];
@@ -31,15 +31,17 @@ export function NodeDetailPageClient() {
const node = useMemo(() => {
if (!nodeId) return null;
return (nodesQuery.data ?? []).find((item) => String(item.id) === nodeId) ?? null;
return (
(nodesQuery.data ?? []).find((item) => String(item.id) === nodeId) ?? null
);
}, [nodeId, nodesQuery.data]);
if (!nodeId) {
return (
<div className="py-6 px-1">
<div className='py-6 px-1'>
<EmptyStateWithBorder
icon={Server}
description="缺少节点 ID,请从节点列表进入详情页。"
description='缺少节点 ID,请从节点列表进入详情页。'
/>
</div>
);
@@ -47,20 +49,20 @@ export function NodeDetailPageClient() {
if (nodesQuery.isLoading) {
return (
<div className="py-6 px-1">
<LoadingStateWithBorder icon={Server} description="加载节点详情中..." />
<div className='py-6 px-1'>
<LoadingStateWithBorder icon={Server} description='加载节点详情中...' />
</div>
);
}
if (nodesQuery.isError) {
return (
<div className="py-6 px-1">
<div className="p-8 border border-dashed rounded-lg">
<div className='py-6 px-1'>
<div className='p-8 border border-dashed rounded-lg'>
<ErrorInline
message={getErrorMessage(nodesQuery.error)}
onRetry={() => void nodesQuery.refetch()}
className="justify-center"
className='justify-center'
/>
</div>
</div>
@@ -69,16 +71,16 @@ export function NodeDetailPageClient() {
if (!node) {
return (
<div className="py-6 px-1 space-y-4">
<Button variant="ghost" size="sm" className="h-8 px-2" asChild>
<Link href="/nodes">
<ArrowLeft className="size-4 mr-1" />
<div className='py-6 px-1 space-y-4'>
<Button variant='ghost' size='sm' className='h-8 px-2' asChild>
<Link href='/nodes'>
<ArrowLeft className='size-4 mr-1' />
返回节点列表
</Link>
</Button>
<EmptyStateWithBorder
icon={Server}
description="节点不存在,可能已被删除或 ID 无效。"
description='节点不存在,可能已被删除或 ID 无效。'
/>
</div>
);
+8 -8
View File
@@ -1,15 +1,15 @@
import {Suspense} from 'react';
import { Suspense } from 'react';
import {Skeleton} from '@/components/ui/skeleton';
import { Skeleton } from '@/components/ui/skeleton';
import {NodeDetailPageClient} from './page-client';
import { NodeDetailPageClient } from './page-client';
function NodeDetailPageFallback() {
return (
<div className="py-6 px-1 space-y-6">
<Skeleton className="h-8 w-48" />
<Skeleton className="h-10 w-full max-w-xl" />
<Skeleton className="h-64 w-full" />
<div className='py-6 px-1 space-y-6'>
<Skeleton className='h-8 w-48' />
<Skeleton className='h-10 w-full max-w-xl' />
<Skeleton className='h-64 w-full' />
</div>
);
}
@@ -20,4 +20,4 @@ export default function NodeDetailPage() {
<NodeDetailPageClient />
</Suspense>
);
}
}