@@ -42,6 +42,17 @@ interface Torrent {
4242 seeds : number
4343}
4444
45+ interface DownloadItem {
46+ id : string
47+ name : string
48+ type : string
49+ status : string
50+ progress : number
51+ size : number
52+ provider : string
53+ addedAt : string
54+ }
55+
4556interface ServiceStatus {
4657 webhook : boolean
4758 poller : boolean
@@ -105,26 +116,30 @@ function getStatusBadgeVariant(status: string, progress: number): "default" | "s
105116export default function DashboardPage ( ) {
106117 const [ providers , setProviders ] = useState < Provider [ ] > ( [ ] )
107118 const [ torrents , setTorrents ] = useState < Torrent [ ] > ( [ ] )
119+ const [ downloads , setDownloads ] = useState < DownloadItem [ ] > ( [ ] )
108120 const [ services , setServices ] = useState < ServiceStatus | null > ( null )
109121 const [ loading , setLoading ] = useState ( true )
110122 const [ refreshing , setRefreshing ] = useState ( false )
111123
112124 async function fetchData ( ) {
113125 try {
114- const [ providersRes , torrentsRes , statusRes ] = await Promise . all ( [
126+ const [ providersRes , torrentsRes , downloadsRes , statusRes ] = await Promise . all ( [
115127 fetch ( "/api/providers" ) ,
116128 fetch ( "/api/torrents" ) ,
129+ fetch ( "/api/downloads" ) ,
117130 fetch ( "/api/status" ) ,
118131 ] )
119132
120- const [ providersData , torrentsData , statusData ] = await Promise . all ( [
133+ const [ providersData , torrentsData , downloadsData , statusData ] = await Promise . all ( [
121134 providersRes . json ( ) ,
122135 torrentsRes . json ( ) ,
136+ downloadsRes . json ( ) ,
123137 statusRes . json ( ) ,
124138 ] )
125139
126140 if ( providersData . ok !== false ) setProviders ( providersData . providers || [ ] )
127141 if ( torrentsData . ok !== false ) setTorrents ( torrentsData . torrents || [ ] )
142+ if ( downloadsData . ok !== false ) setDownloads ( downloadsData . downloads || [ ] )
128143 if ( statusData . ok !== false ) setServices ( statusData . services || null )
129144 } catch ( error ) {
130145 console . error ( "Failed to fetch dashboard data:" , error )
@@ -146,13 +161,25 @@ export default function DashboardPage() {
146161 fetchData ( )
147162 }
148163
149- // Calculate stats from real data
164+ // Calculate stats from real data - combine torrents + downloads
150165 const totalTorrents = torrents . length
166+ const totalDownloads = downloads . length
151167 const activeTorrents = torrents . filter ( t =>
152168 t . progress < 100 && ! t . status . toLowerCase ( ) . includes ( "error" )
153169 ) . length
154- const totalSize = torrents . reduce ( ( acc , t ) => acc + ( t . size || 0 ) , 0 )
170+ const activeDownloads = downloads . filter ( d =>
171+ d . progress < 100 && ! d . status . toLowerCase ( ) . includes ( "error" )
172+ ) . length
173+ const totalTorrentSize = torrents . reduce ( ( acc , t ) => acc + ( t . size || 0 ) , 0 )
174+ const totalDownloadSize = downloads . reduce ( ( acc , d ) => acc + ( d . size || 0 ) , 0 )
175+ const totalSize = totalTorrentSize + totalDownloadSize
155176 const connectedProviders = providers . filter ( p => p . connected ) . length
177+
178+ // Combine recent activity from both sources
179+ const allActivity = [
180+ ...torrents . map ( t => ( { ...t , source : "torrent" as const } ) ) ,
181+ ...downloads . map ( d => ( { ...d , source : "download" as const , seeds : 0 , downloadSpeed : 0 } ) ) ,
182+ ] . sort ( ( a , b ) => new Date ( b . addedAt ) . getTime ( ) - new Date ( a . addedAt ) . getTime ( ) )
156183
157184 const servicesList = services ? [
158185 { name : "Webhook Server" , status : services . webhook ? "running" : "stopped" , port : 8978 } ,
@@ -216,30 +243,29 @@ export default function DashboardPage() {
216243 < Card >
217244 < CardHeader className = "flex flex-row items-center justify-between pb-2" >
218245 < CardTitle className = "text-sm font-medium text-muted-foreground" >
219- Total Torrents
246+ Torrents
220247 </ CardTitle >
221248 < Download className = "h-4 w-4 text-muted-foreground" />
222249 </ CardHeader >
223250 < CardContent >
224251 < div className = "text-2xl font-bold" > { totalTorrents } </ div >
225252 < p className = "text-xs text-muted-foreground" >
226- Across all providers
253+ { activeTorrents > 0 ? ` ${ activeTorrents } active` : " Across all providers" }
227254 </ p >
228255 </ CardContent >
229256 </ Card >
230257
231258 < Card >
232259 < CardHeader className = "flex flex-row items-center justify-between pb-2" >
233260 < CardTitle className = "text-sm font-medium text-muted-foreground" >
234- Active Transfers
261+ Downloads
235262 </ CardTitle >
236263 < Activity className = "h-4 w-4 text-muted-foreground" />
237264 </ CardHeader >
238265 < CardContent >
239- < div className = "text-2xl font-bold" > { activeTorrents } </ div >
266+ < div className = "text-2xl font-bold" > { totalDownloads } </ div >
240267 < p className = "text-xs text-muted-foreground" >
241- In progress
242- { activeTorrents > 0 && < span className = "ml-2 text-blue-500" > Live</ span > }
268+ { activeDownloads > 0 ? `${ activeDownloads } active` : "Ready to stream" }
243269 </ p >
244270 </ CardContent >
245271 </ Card >
@@ -254,7 +280,7 @@ export default function DashboardPage() {
254280 < CardContent >
255281 < div className = "text-2xl font-bold" > { formatBytes ( totalSize ) } </ div >
256282 < p className = "text-xs text-muted-foreground" >
257- Across all torrents
283+ { totalTorrents + totalDownloads } items total
258284 </ p >
259285 </ CardContent >
260286 </ Card >
@@ -286,29 +312,31 @@ export default function DashboardPage() {
286312 < CardDescription > Latest downloads and transfers</ CardDescription >
287313 </ CardHeader >
288314 < CardContent >
289- { torrents . length === 0 ? (
315+ { allActivity . length === 0 ? (
290316 < div className = "text-center py-8 text-muted-foreground" >
291317 < Download className = "h-8 w-8 mx-auto mb-2 opacity-50" />
292- < p > No torrents found</ p >
318+ < p > No activity found</ p >
293319 < p className = "text-sm" > Add content to see activity here</ p >
294320 </ div >
295321 ) : (
296322 < div className = "space-y-4" >
297- { torrents . slice ( 0 , 5 ) . map ( ( torrent ) => (
298- < div key = { torrent . id } className = "flex items-center justify-between" >
323+ { allActivity . slice ( 0 , 5 ) . map ( ( item ) => (
324+ < div key = { ` ${ item . source } - ${ item . provider } - ${ item . id } ` } className = "flex items-center justify-between" >
299325 < div className = "flex items-center gap-3 min-w-0 flex-1" >
300- { getStatusIcon ( torrent . status , torrent . progress ) }
326+ { getStatusIcon ( item . status , item . progress ) }
301327 < div className = "min-w-0 flex-1" >
302- < p className = "text-sm font-medium truncate" > { torrent . name } </ p >
303- < p className = "text-xs text-muted-foreground capitalize" > { torrent . provider } </ p >
328+ < p className = "text-sm font-medium truncate" > { item . name } </ p >
329+ < p className = "text-xs text-muted-foreground capitalize" >
330+ { item . provider } • { item . source }
331+ </ p >
304332 </ div >
305333 </ div >
306334 < div className = "flex items-center gap-2 ml-2" >
307- < Badge variant = { getStatusBadgeVariant ( torrent . status , torrent . progress ) } >
308- { torrent . progress >= 100 ? "completed" : torrent . status }
335+ < Badge variant = { getStatusBadgeVariant ( item . status , item . progress ) } >
336+ { item . progress >= 100 ? "completed" : item . status }
309337 </ Badge >
310338 < span className = "text-xs text-muted-foreground whitespace-nowrap" >
311- { formatRelativeTime ( torrent . addedAt ) }
339+ { formatRelativeTime ( item . addedAt ) }
312340 </ span >
313341 </ div >
314342 </ div >
0 commit comments