22
33// src/app/(auth)/trackers/[id]/page.tsx
44//
5- // Functions: formatGiB, formatRatio, formatHours, TrackerDetailPage
5+ // Functions: formatHours, TrackerDetailPage
66
77import { useParams } from "next/navigation"
88import { useCallback , useEffect , useState } from "react"
@@ -11,58 +11,13 @@ import { Badge } from "@/components/ui/Badge"
1111import { Button } from "@/components/ui/Button"
1212import { Card } from "@/components/ui/Card"
1313import { StatCard } from "@/components/ui/StatCard"
14-
15- interface TrackerLatestStats {
16- ratio : number | null
17- uploadedBytes : string | null
18- downloadedBytes : string | null
19- seedingCount : number | null
20- leechingCount : number | null
21- username : string | null
22- group : string | null
23- }
24-
25- interface Tracker {
26- id : number
27- name : string
28- baseUrl : string
29- platformType : string
30- pollIntervalMinutes : number
31- isActive : boolean
32- lastPolledAt : string | null
33- lastError : string | null
34- color : string
35- latestStats : TrackerLatestStats | null
36- }
37-
38- interface Snapshot {
39- polledAt : string
40- uploadedBytes : string
41- downloadedBytes : string
42- ratio : number | null
43- bufferBytes : string
44- seedbonus : number | null
45- seedingCount : number | null
46- leechingCount : number | null
47- hitAndRuns : number | null
48- }
14+ import { formatBytesFromString , formatRatio } from "@/lib/formatters"
15+ import type { Snapshot , TrackerSummary } from "@/types/api"
4916
5017type DayRange = 7 | 30 | 90 | 365
5118
5219const DAY_RANGES : DayRange [ ] = [ 7 , 30 , 90 , 365 ]
5320
54- function formatGiB ( bytesStr : string | null ) : string {
55- if ( ! bytesStr ) return "—"
56- const gib = Number ( BigInt ( bytesStr ) ) / 1024 ** 3
57- if ( gib >= 1024 ) return `${ ( gib / 1024 ) . toFixed ( 2 ) } TiB`
58- return `${ gib . toFixed ( 2 ) } GiB`
59- }
60-
61- function formatRatio ( ratio : number | null | undefined ) : string {
62- if ( ratio === null || ratio === undefined ) return "—"
63- return ratio . toFixed ( 2 )
64- }
65-
6621function formatHours ( minutes : number ) : string {
6722 if ( minutes < 60 ) return `${ minutes } m`
6823 const hours = minutes / 60
@@ -73,7 +28,7 @@ export default function TrackerDetailPage() {
7328 const params = useParams ( )
7429 const id = params . id as string
7530
76- const [ tracker , setTracker ] = useState < Tracker | null > ( null )
31+ const [ tracker , setTracker ] = useState < TrackerSummary | null > ( null )
7732 const [ snapshots , setSnapshots ] = useState < Snapshot [ ] > ( [ ] )
7833 const [ days , setDays ] = useState < DayRange > ( 30 )
7934 const [ loading , setLoading ] = useState ( true )
@@ -88,7 +43,7 @@ export default function TrackerDetailPage() {
8843 ] )
8944
9045 if ( trackersRes . ok ) {
91- const allTrackers : Tracker [ ] = await trackersRes . json ( )
46+ const allTrackers : TrackerSummary [ ] = await trackersRes . json ( )
9247 const found = allTrackers . find ( ( t ) => t . id === Number ( id ) )
9348 setTracker ( found ?? null )
9449 }
@@ -211,11 +166,11 @@ export default function TrackerDetailPage() {
211166 < div className = "grid grid-cols-2 gap-4 sm:grid-cols-4" >
212167 < StatCard
213168 label = "Uploaded"
214- value = { formatGiB ( stats ?. uploadedBytes ?? null ) }
169+ value = { formatBytesFromString ( stats ?. uploadedBytes ?? null ) }
215170 />
216171 < StatCard
217172 label = "Downloaded"
218- value = { formatGiB ( stats ?. downloadedBytes ?? null ) }
173+ value = { formatBytesFromString ( stats ?. downloadedBytes ?? null ) }
219174 />
220175 < StatCard
221176 label = "Ratio"
@@ -232,7 +187,7 @@ export default function TrackerDetailPage() {
232187 />
233188 < StatCard
234189 label = "Buffer"
235- value = { formatGiB ( latestSnapshot ?. bufferBytes ?? null ) }
190+ value = { formatBytesFromString ( latestSnapshot ?. bufferBytes ?? null ) }
236191 />
237192 </ div >
238193
0 commit comments