"use client" import { useState, useEffect } from "react" import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./ui/dialog" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select" import { Activity, TrendingDown, TrendingUp, Minus } from "lucide-react" import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts" import { useIsMobile } from "../hooks/use-mobile" import { fetchApi } from "@/lib/api-config" const TIMEFRAME_OPTIONS = [ { value: "hour", label: "1 Hour" }, { value: "6hour", label: "6 Hours" }, { value: "day", label: "24 Hours" }, { value: "3day", label: "3 Days" }, { value: "week", label: "7 Days" }, ] const TARGET_OPTIONS = [ { value: "gateway", label: "Gateway (Router)" }, { value: "cloudflare", label: "Cloudflare (1.1.1.1)" }, { value: "google", label: "Google DNS (8.8.8.8)" }, ] interface LatencyHistoryPoint { timestamp: number value: number min?: number max?: number packet_loss?: number } interface LatencyStats { min: number max: number avg: number current: number } interface LatencyDetailModalProps { open: boolean onOpenChange: (open: boolean) => void currentLatency?: number } const CustomTooltip = ({ active, payload, label }: any) => { if (active && payload && payload.length) { const entry = payload[0] const packetLoss = entry?.payload?.packet_loss return (

{label}

Latency: {entry.value} ms
{packetLoss !== undefined && packetLoss > 0 && (
Pkt Loss: {packetLoss}%
)}
) } return null } const getStatusColor = (latency: number) => { if (latency >= 200) return "#ef4444" if (latency >= 100) return "#f59e0b" return "#22c55e" } const getStatusInfo = (latency: number) => { if (latency === 0) return { status: "N/A", color: "bg-gray-500/10 text-gray-500 border-gray-500/20" } if (latency < 50) return { status: "Excellent", color: "bg-green-500/10 text-green-500 border-green-500/20" } if (latency < 100) return { status: "Good", color: "bg-green-500/10 text-green-500 border-green-500/20" } if (latency < 200) return { status: "Fair", color: "bg-yellow-500/10 text-yellow-500 border-yellow-500/20" } return { status: "Poor", color: "bg-red-500/10 text-red-500 border-red-500/20" } } export function LatencyDetailModal({ open, onOpenChange, currentLatency }: LatencyDetailModalProps) { const [timeframe, setTimeframe] = useState("hour") const [target, setTarget] = useState("gateway") const [data, setData] = useState([]) const [stats, setStats] = useState({ min: 0, max: 0, avg: 0, current: 0 }) const [loading, setLoading] = useState(true) const isMobile = useIsMobile() useEffect(() => { if (open) { fetchHistory() } }, [open, timeframe, target]) const fetchHistory = async () => { setLoading(true) try { const result = await fetchApi<{ data: LatencyHistoryPoint[]; stats: LatencyStats; target: string }>( `/api/network/latency/history?target=${target}&timeframe=${timeframe}` ) if (result && result.data) { setData(result.data) setStats(result.stats) } } catch (err) { // Silently fail - will show empty state } finally { setLoading(false) } } const formatTime = (timestamp: number) => { const date = new Date(timestamp * 1000) if (timeframe === "hour" || timeframe === "6hour") { return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) } else if (timeframe === "day") { return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) } else { return date.toLocaleDateString([], { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) } } const chartData = data.map((d) => ({ ...d, time: formatTime(d.timestamp), })) const currentLat = currentLatency && currentLatency > 0 ? Math.round(currentLatency * 10) / 10 : stats.current const currentStatus = getStatusInfo(currentLat) const chartColor = getStatusColor(currentLat) const values = data.map((d) => d.value).filter(v => v !== null && v !== undefined) const yMin = 0 const yMax = values.length > 0 ? Math.ceil(Math.max(...values) * 1.2) : 200 return (
Network Latency
{/* Stats bar */}
Current
{currentLat} ms
Min
{stats.min} ms
Avg
{stats.avg} ms
Max
{stats.max} ms
{/* Chart */}
{loading ? (
) : chartData.length === 0 ? (

No latency data available for this period

Data is collected every 60 seconds

) : ( `${v}ms`} width={isMobile ? 45 : 50} /> } /> )}
) }