@@ -3,6 +3,7 @@ import { useQuery } from "@tanstack/react-query";
33import { api } from "@/api/client" ;
44import { Button , Card , PageHeader , Select } from "@/components/ui" ;
55import { formatBytes } from "@/lib/utils" ;
6+ import { useI18n } from "@/i18n/i18n" ;
67
78interface GeoPoint {
89 country : string ;
@@ -32,6 +33,7 @@ interface AnalyticsData {
3233}
3334
3435export function Analytics ( ) {
36+ const { t } = useI18n ( ) ;
3537 const [ range , setRange ] = useState ( "7d" ) ;
3638 const rangeMap : Record < string , number > = { "1d" : 1 , "7d" : 7 , "30d" : 30 } ;
3739
@@ -46,44 +48,44 @@ export function Analytics() {
4648 return (
4749 < div className = "space-y-6 animate-fade-in" >
4850 < div className = "flex items-center justify-between" >
49- < PageHeader title = "Analytics" subtitle = "Traffic insights and geo breakdown" />
51+ < PageHeader title = { t ( "analytics.title" ) } subtitle = { t ( "analytics.subtitle" ) } />
5052 < div className = "flex gap-2" >
5153 < Select value = { range } onChange = { ( e ) => setRange ( e . target . value ) } >
5254 < option value = "1d" > Last 24h</ option >
5355 < option value = "7d" > Last 7 days</ option >
5456 < option value = "30d" > Last 30 days</ option >
5557 </ Select >
5658 < Button variant = "outline" onClick = { ( ) => window . open ( `/api/analytics/export?from=${ from } &to=${ to } ` , "_blank" ) } >
57- Export CSV
59+ { t ( "analytics.export" ) }
5860 </ Button >
5961 </ div >
6062 </ div >
6163
62- { isLoading && < div className = "text-center text-fg-muted py-8" > Loading analytics... </ div > }
63- { isError && < div className = "text-center text-fg-muted py-8" > Unable to load analytics data. Make sure the analytics feature is configured. </ div > }
64- { ! isLoading && ! isError && ! data && < div className = "text-center text-fg-muted py-8" > No analytics data available for this time range. </ div > }
64+ { isLoading && < div className = "text-center text-fg-muted py-8" > { t ( "common.loading" ) } </ div > }
65+ { isError && < div className = "text-center text-fg-muted py-8" > { t ( " analytics.error" ) } </ div > }
66+ { ! isLoading && ! isError && ! data && < div className = "text-center text-fg-muted py-8" > { t ( " analytics.noData" ) } </ div > }
6567
6668 { data && (
6769 < >
6870 { /* Summary cards */ }
6971 < div className = "grid grid-cols-1 gap-4 md:grid-cols-3" >
7072 < Card className = "space-y-2" >
71- < div className = "text-xs text-fg-subtle uppercase" > Total Upload </ div >
73+ < div className = "text-xs text-fg-subtle uppercase" > { t ( "analytics.totalUp" ) } </ div >
7274 < div className = "text-lg font-bold text-fg" > { formatBytes ( data . total_up , false ) } </ div >
7375 </ Card >
7476 < Card className = "space-y-2" >
75- < div className = "text-xs text-fg-subtle uppercase" > Total Download </ div >
77+ < div className = "text-xs text-fg-subtle uppercase" > { t ( "analytics.totalDown" ) } </ div >
7678 < div className = "text-lg font-bold text-fg" > { formatBytes ( data . total_down , false ) } </ div >
7779 </ Card >
7880 < Card className = "space-y-2" >
79- < div className = "text-xs text-fg-subtle uppercase" > Countries </ div >
81+ < div className = "text-xs text-fg-subtle uppercase" > { t ( "analytics.countries" ) } </ div >
8082 < div className = "text-lg font-bold text-fg" > { data . geo_breakdown ?. length ?? 0 } </ div >
8183 </ Card >
8284 </ div >
8385
8486 { /* Geo breakdown table */ }
8587 < Card >
86- < h3 className = "text-sm font-bold text-fg mb-3" > Traffic by Country </ h3 >
88+ < h3 className = "text-sm font-bold text-fg mb-3" > { t ( "analytics.byCountry" ) } </ h3 >
8789 < div className = "overflow-x-auto" >
8890 < table className = "w-full text-sm" >
8991 < thead >
@@ -110,7 +112,7 @@ export function Analytics() {
110112
111113 { /* Top users */ }
112114 < Card >
113- < h3 className = "text-sm font-bold text-fg mb-3" > Top Users by Traffic </ h3 >
115+ < h3 className = "text-sm font-bold text-fg mb-3" > { t ( "analytics.topUsers" ) } </ h3 >
114116 < div className = "overflow-x-auto" >
115117 < table className = "w-full text-sm" >
116118 < thead >
@@ -135,7 +137,7 @@ export function Analytics() {
135137
136138 { /* Peak hours */ }
137139 < Card >
138- < h3 className = "text-sm font-bold text-fg mb-3" > Peak Hours </ h3 >
140+ < h3 className = "text-sm font-bold text-fg mb-3" > { t ( "analytics.peakHours" ) } </ h3 >
139141 < div className = "flex items-end gap-1 h-32" >
140142 { data . peak_hours ?. map ( ( p ) => {
141143 const maxBytes = Math . max ( ...( data . peak_hours ?. map ( h => h . bytes_total ) ?? [ 1 ] ) ) ;
0 commit comments