"use client"; import { useState, useEffect } from "react"; import { fetchAppDetails, AppDetails } from "@/lib/api"; import { fmtBytes } from "@/lib/utils"; import { Loader2, X, Globe, Server, Monitor } from "lucide-react"; interface Props { appLabel: string; favicon?: string | null; category?: string | null; onClose: () => void; } export function AppDetailModal({ appLabel, favicon, category, onClose }: Props) { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [isClosing, setIsClosing] = useState(false); const handleClose = () => { setIsClosing(true); setTimeout(() => { onClose(); }, 480); }; useEffect(() => { setIsLoading(true); setError(null); fetchAppDetails(appLabel) .then(setData) .catch((e) => setError(e.message)) .finally(() => setIsLoading(false)); }, [appLabel]); return (
e.stopPropagation()} > {/* Header */}
{favicon ? ( {appLabel} ) : ( )}

{appLabel}

{category &&

{category}

}
{/* Body */}
{isLoading ? (

Loading application data...

) : error ? (
{error}
) : data ? (
{/* Total Summary */}

Total Download

{fmtBytes(data.total_download ?? 0)}

Total Upload

{fmtBytes(data.total_upload ?? 0)}

{/* Per-Agent Breakdown */}

Usage per Agent

{data.agent_scorecard.length === 0 ? (

No traffic from known agents for this app yet.

) : (
{data.agent_scorecard.map((a, i) => { const maxDl = Math.max(...data.agent_scorecard.map(x => x.download), 1); const pct = (a.download / maxDl) * 100; return (
{a.agent_label} {a.agent_uuid && ( {a.agent_uuid} )}
↓ {fmtBytes(a.download)} ↑ {fmtBytes(a.upload ?? 0)}
); })}
)}
{/* Top IPs */}

Top 5 Flow Records (Realtime) {data.top_ips.filter(ip => ip.blacklisted).length > 0 && ( 🚫 {data.top_ips.filter(ip => ip.blacklisted).length} Blacklisted )}

{data.top_ips.length === 0 ? (

No device data available.

) : (
{data.top_ips.map((ip, i) => { const maxDl = Math.max(...data.top_ips.map(x => x.download), 1); const pct = (ip.download / maxDl) * 100; return ( ); })}
# Source IP Dest IP Label / Domain Time Download Upload
{i + 1}
{ip.ip_address || "-"} {ip.blacklisted && ( 🚫 )} {!ip.blacklisted && ip.reputation && ip.reputation !== "Unknown" && ( {ip.reputation} )}
{ip.dst_ip || "-"} {ip.domain || data.app_label || "-"} {ip.last_seen ? new Date(ip.last_seen).toLocaleString('id-ID', { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' }) : "-"} {fmtBytes(ip.download)} {fmtBytes(ip.upload ?? 0)}
)}
) : null}
); }