llm-file-proxy / jorki /src /components /TransferMonitor.jsx
josephrw's picture
Upload folder using huggingface_hub
55153d0 verified
Raw
History Blame Contribute Delete
5.94 kB
import { useState } from 'react'
import { motion } from 'framer-motion'
import { Activity, Zap, Wifi, Timer, TrendingUp, TrendingDown } from 'lucide-react'
import { useAnimatedNumber, useLiveData, useInterval } from '../hooks/useUtils.js'
function WaveChart({ values, max, color = 'primary', height = 80 }) {
const points = values.map((v, i) => {
const x = (i / (values.length - 1)) * 100
const y = 100 - (v / max) * 100
return `${x},${y}`
}).join(' ')
return (
<div className="relative" style={{ height }}>
<svg className="absolute inset-0 w-full h-full" preserveAspectRatio="none" viewBox="0 0 100 100">
<defs>
<linearGradient id={`grad-${color}`} x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#FF8A00" stopOpacity="0.3" />
<stop offset="100%" stopColor="#FF8A00" stopOpacity="0" />
</linearGradient>
</defs>
<polygon
points={`0,100 ${points} 100,100`}
fill={`url(#grad-${color})`}
/>
<polyline
points={points}
fill="none"
stroke="#FF8A00"
strokeWidth="1.5"
vectorEffect="non-scaling-stroke"
/>
</svg>
</div>
)
}
export default function TransferMonitor() {
const [uploadHistory, setUploadHistory] = useState(Array.from({ length: 40 }, () => 1.5 + Math.random() * 1.5))
const [downloadHistory, setDownloadHistory] = useState(Array.from({ length: 40 }, () => 1.2 + Math.random() * 1.2))
const liveData = useLiveData({
uploadRate: 2.34,
downloadRate: 1.92,
connections: 128,
latency: 19,
}, 1500, 0.05)
useInterval(() => {
setUploadHistory(prev => [...prev.slice(1), liveData.uploadRate])
setDownloadHistory(prev => [...prev.slice(1), liveData.downloadRate])
}, 1500)
const animatedUpload = useAnimatedNumber(liveData.uploadRate, 500)
const animatedDownload = useAnimatedNumber(liveData.downloadRate, 500)
const animatedConn = useAnimatedNumber(liveData.connections, 500)
const animatedLat = useAnimatedNumber(liveData.latency, 500)
const uploadTrend = uploadHistory[uploadHistory.length - 1] > uploadHistory[uploadHistory.length - 5]
const downloadTrend = downloadHistory[downloadHistory.length - 1] > downloadHistory[downloadHistory.length - 5]
return (
<div className="p-6 h-full overflow-y-auto thin-scrollbar space-y-4">
{/* Live banner */}
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
className="glass rounded-2xl p-5 scanline"
>
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2">
<span className="w-2 h-2 rounded-full bg-success animate-pulse" />
<span className="text-sm font-semibold">Transfer Monitor</span>
<span className="text-[10px] text-success font-mono ml-2">LIVE</span>
</div>
<span className="text-[10px] text-secondary">Updates every 1.5s</span>
</div>
{/* Upload wave */}
<div className="mb-4">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<TrendingUp className={`w-3.5 h-3.5 ${uploadTrend ? 'text-success' : 'text-critical'}`} />
<span className="text-xs text-secondary">Upload Rate</span>
</div>
<span className="text-lg font-bold tabular-nums">
{animatedUpload.toFixed(2)}<span className="text-xs text-secondary ml-1">GB/s</span>
</span>
</div>
<WaveChart values={uploadHistory} max={4} color="primary" height={60} />
</div>
{/* Download wave */}
<div className="mb-4">
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<TrendingDown className={`w-3.5 h-3.5 ${downloadTrend ? 'text-success' : 'text-critical'}`} />
<span className="text-xs text-secondary">Download Rate</span>
</div>
<span className="text-lg font-bold tabular-nums">
{animatedDownload.toFixed(2)}<span className="text-xs text-secondary ml-1">GB/s</span>
</span>
</div>
<WaveChart values={downloadHistory} max={3} color="accent" height={60} />
</div>
{/* Stats row */}
<div className="grid grid-cols-3 gap-3 pt-3 border-t border-white/5">
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1.5">
<Wifi className="w-3 h-3 text-primary" />
<span className="text-[10px] uppercase tracking-wider text-secondary">Connections</span>
</div>
<span className="text-lg font-bold tabular-nums">{Math.round(animatedConn)}</span>
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1.5">
<Timer className="w-3 h-3 text-warning" />
<span className="text-[10px] uppercase tracking-wider text-secondary">Latency</span>
</div>
<span className="text-lg font-bold tabular-nums">{animatedLat.toFixed(0)}<span className="text-xs text-secondary ml-1">ms</span></span>
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1.5">
<Zap className="w-3 h-3 text-accent" />
<span className="text-[10px] uppercase tracking-wider text-secondary">Total</span>
</div>
<span className="text-lg font-bold tabular-nums">{(animatedUpload + animatedDownload).toFixed(2)}<span className="text-xs text-secondary ml-1">GB/s</span></span>
</div>
</div>
</motion.div>
{/* Active transfers list */}
<TransferGrid />
</div>
)
}