'use client'; import { Suspense, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useQuery } from '@tanstack/react-query'; import { Gauge } from 'lucide-react'; import { useAuth } from '@/components/providers/auth-provider'; import { EmptyStateWithBorder } from '@/components/layout/empty'; import { LoadingStateWithBorder } from '@/components/layout/loading'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { AccessLogService } from '@/lib/services/openflare'; import type { RateLimitRangeHours } from '../access-logs/components/access-log-utils'; import { AnalysisTab } from './components/analysis-tab'; import { ConfigTab } from './components/config-tab'; type RateLimitTab = 'analysis' | 'config'; function resolveTab(value: string | null): RateLimitTab { if (value === 'config') return 'config'; return 'analysis'; } function RateLimitsPageContent() { const { user, loading: authLoading } = useAuth(); const router = useRouter(); const searchParams = useSearchParams(); const tab = resolveTab(searchParams.get('tab')); const [hours, setHours] = useState(24); const [hosts, setHosts] = useState([]); const overviewQuery = useQuery({ queryKey: ['openflare', 'rate-limits', 'overview', hours, hosts, 3], queryFn: () => AccessLogService.getOverview({ hours, hosts: hosts.length > 0 ? hosts : undefined, bucket_minutes: 3, }), enabled: !!user?.is_admin && tab === 'analysis', }); const handleTabChange = (value: string) => { const next = resolveTab(value); router.replace( next === 'analysis' ? '/rate-limits' : '/rate-limits?tab=config', ); }; if (authLoading) { return (
); } if (!user?.is_admin) { return (
); } return (

限流

查看边缘请求压力,并配置站点默认并发与带宽限流。

分析 配置 void overviewQuery.refetch()} />
); } export default function RateLimitsPage() { return ( } > ); }