import { useState } from 'react' import { useQuery } from '@tanstack/react-query' import { useBreadcrumb } from '../hooks/useBreadcrumb' import { breadcrumbConfig } from '../config/breadcrumbConfig' import { Activity, AlertCircle, CheckCircle, Clock, TrendingUp, RefreshCw, Filter, Gauge, } from 'lucide-react' import { api } from '../lib/api' import { formatRelativeTime } from '../lib/utils' export default function Monitoring() { useBreadcrumb(breadcrumbConfig['/monitoring']) const [timeWindow, setTimeWindow] = useState(24) const [selectedDownloader, setSelectedDownloader] = useState(null) const [historyLimit, setHistoryLimit] = useState(100) const { data: statusData, isLoading: statusLoading, refetch: refetchStatus } = useQuery({ queryKey: ['monitoring', 'status', timeWindow], queryFn: () => api.getMonitoringStatus(timeWindow), refetchInterval: 30000, // Refresh every 30 seconds }) const { data: historyData, isLoading: historyLoading, refetch: refetchHistory } = useQuery({ queryKey: ['monitoring', 'history', selectedDownloader, historyLimit], queryFn: () => api.getMonitoringHistory(selectedDownloader, historyLimit), refetchInterval: 60000, // Refresh every minute }) const downloaders = statusData?.downloaders || [] const history = historyData?.history || [] // Calculate overall stats const totalAttempts = downloaders.reduce((sum, d) => sum + d.total_attempts, 0) const totalSuccessful = downloaders.reduce((sum, d) => sum + d.successful, 0) const totalFailed = downloaders.reduce((sum, d) => sum + d.failed, 0) const overallSuccessRate = totalAttempts > 0 ? (totalSuccessful / totalAttempts * 100).toFixed(1) : 0 // Get downloader display name const getDownloaderName = (downloader: string) => { const names: Record = { fastdl: 'FastDL', imginn: 'ImgInn', toolzu: 'Toolzu', instagram: 'Instagram', snapchat: 'Snapchat', tiktok: 'TikTok', forums: 'Forums', coppermine: 'Coppermine' } return names[downloader] || downloader } // Get status color const getStatusColor = (successRate: number) => { if (successRate >= 80) return 'text-green-600 dark:text-green-400' if (successRate >= 50) return 'text-yellow-600 dark:text-yellow-400' return 'text-red-600 dark:text-red-400' } return (
{/* Header */}

Downloader Monitoring

Track downloader health and performance

{/* Overall Stats */}

Total Attempts

{totalAttempts}

Successful

{totalSuccessful}

Failed

{totalFailed}

Success Rate

{overallSuccessRate}%

{/* Downloader Status Cards */}

Downloader Status

{statusLoading ? (
Loading...
) : downloaders.length === 0 ? (

No monitoring data available yet

Data will appear after downloaders run

) : (
{downloaders.map((downloader) => (
setSelectedDownloader( selectedDownloader === downloader.downloader ? null : downloader.downloader )} >

{getDownloaderName(downloader.downloader)}

{downloader.success_rate}%
Attempts {downloader.total_attempts}
Successful {downloader.successful}
Failed {downloader.failed}
Files {downloader.total_files}
Last: {downloader.last_attempt ? formatRelativeTime(downloader.last_attempt) : 'Never'}
{downloader.last_success && (
Success: {formatRelativeTime(downloader.last_success)}
)}
))}
)}
{/* History Table */}

Download History

{selectedDownloader && ( )}
{historyLoading ? (
Loading history...
) : history.length === 0 ? (
No history available
) : (
{history.map((entry) => ( ))}
Time Downloader Username Status Files Error Alert
{formatRelativeTime(entry.timestamp)} {getDownloaderName(entry.downloader)} {entry.username} {entry.success ? ( Success ) : ( Failed )} {entry.file_count} {entry.error_message || '-'} {entry.alert_sent && ( Alerted )}
)}
) }