import { useState } from "react"; import { Switch } from "@/components/ui/switch"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { useProxyStatus } from "@/hooks/useProxyStatus"; import { Settings, Activity, Clock, TrendingUp, Server } from "lucide-react"; import { ProxySettingsDialog } from "./ProxySettingsDialog"; import { toast } from "sonner"; export function ProxyPanel() { const { status, isRunning, start, stop, isPending } = useProxyStatus(); const [showSettings, setShowSettings] = useState(false); const handleToggle = async () => { try { if (isRunning) { await stop(); } else { await start(); } } catch (error) { console.error("Toggle proxy failed:", error); } }; const formatUptime = (seconds: number): string => { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; if (hours > 0) { return `${hours}h ${minutes}m ${secs}s`; } else if (minutes > 0) { return `${minutes}m ${secs}s`; } else { return `${secs}s`; } }; return ( <>

本地代理服务

{isRunning ? `运行中 · ${status?.address}:${status?.port}` : "已停止"}

{isRunning ? "运行中" : "已停止"}
{isRunning && status ? (

服务地址

http://{status.address}:{status.port}

当前代理

{status.active_targets && status.active_targets.length > 0 ? (
{status.active_targets.map((target) => (
{target.app_type} {target.provider_name}
))}
) : status.current_provider ? (

当前 Provider:{" "} {status.current_provider}

) : (

当前 Provider:等待首次请求…

)}
} label="活跃连接" value={status.active_connections} /> } label="总请求数" value={status.total_requests} /> } label="成功率" value={`${status.success_rate.toFixed(1)}%`} variant={status.success_rate > 90 ? "success" : "warning"} /> } label="运行时间" value={formatUptime(status.uptime_seconds)} />
) : (

代理服务已停止

使用右上角开关即可启动服务

)}
); } interface StatCardProps { icon: React.ReactNode; label: string; value: string | number; variant?: "default" | "success" | "warning"; } function StatCard({ icon, label, value, variant = "default" }: StatCardProps) { const variantStyles = { default: "", success: "border-green-500/40 bg-green-500/5", warning: "border-yellow-500/40 bg-yellow-500/5", }; return (
{icon} {label}

{value}

); }