@@ -77,6 +77,7 @@ export default function AIUsagePage() {
7777 { label : 'Estimated Cost' , value : summary ?. total_cost_usd ? `$${ summary . total_cost_usd . toFixed ( 4 ) } ` : '$0.0000' , Icon : DollarSign } ,
7878 { label : 'Avg Cost / Call' , value : summary ?. total_calls ? `$${ ( summary . total_cost_usd / summary . total_calls ) . toFixed ( 5 ) } ` : '$0.00000' , Icon : Zap } ,
7979 ] ;
80+ const featureChartData : Array < Record < string , string | number > > = featureData . map ( ( item ) => ( { ...item } ) ) ;
8081
8182 return (
8283 < div className = "flex flex-col gap-6 p-6 min-h-screen bg-[#050505] text-foreground" >
@@ -122,59 +123,71 @@ export default function AIUsagePage() {
122123 { /* Cost Over Time */ }
123124 < CyberCard className = "lg:col-span-2" title = "COST_TRENDS_30D" subtitle = "Daily AI expenditure in USD" >
124125 < div className = "h-[300px] w-full mt-4" >
125- < ResponsiveContainer width = "100%" height = "100%" >
126- < LineChart data = { dailyData } >
127- < CartesianGrid strokeDasharray = "3 3" stroke = "#222" />
128- < XAxis
129- dataKey = "date"
130- stroke = "#666"
131- fontSize = { 10 }
132- tickFormatter = { ( val ) => val . split ( '-' ) . slice ( 1 ) . join ( '/' ) }
133- />
134- < YAxis stroke = "#666" fontSize = { 10 } />
135- < Tooltip
136- contentStyle = { { backgroundColor : '#0a0a0a' , border : '1px solid #333' , fontSize : '10px' } }
137- itemStyle = { { color : '#00FFCC' } }
138- />
139- < Legend iconType = "circle" wrapperStyle = { { fontSize : '10px' , paddingTop : '10px' } } />
140- < Line
141- type = "monotone"
142- dataKey = "cost"
143- name = "Cost ($)"
144- stroke = "#00FFCC"
145- strokeWidth = { 2 }
146- dot = { { r : 3 , fill : '#00FFCC' } }
147- activeDot = { { r : 5 , stroke : '#00FFCC' , strokeWidth : 2 , fill : '#050505' } }
148- />
149- </ LineChart >
150- </ ResponsiveContainer >
126+ { dailyData . length > 0 ? (
127+ < ResponsiveContainer width = "100%" height = "100%" minWidth = { 1 } minHeight = { 1 } >
128+ < LineChart data = { dailyData } >
129+ < CartesianGrid strokeDasharray = "3 3" stroke = "#222" />
130+ < XAxis
131+ dataKey = "date"
132+ stroke = "#666"
133+ fontSize = { 10 }
134+ tickFormatter = { ( val ) => val . split ( '-' ) . slice ( 1 ) . join ( '/' ) }
135+ />
136+ < YAxis stroke = "#666" fontSize = { 10 } />
137+ < Tooltip
138+ contentStyle = { { backgroundColor : '#0a0a0a' , border : '1px solid #333' , fontSize : '10px' } }
139+ itemStyle = { { color : '#00FFCC' } }
140+ />
141+ < Legend iconType = "circle" wrapperStyle = { { fontSize : '10px' , paddingTop : '10px' } } />
142+ < Line
143+ type = "monotone"
144+ dataKey = "cost"
145+ name = "Cost ($)"
146+ stroke = "#00FFCC"
147+ strokeWidth = { 2 }
148+ dot = { { r : 3 , fill : '#00FFCC' } }
149+ activeDot = { { r : 5 , stroke : '#00FFCC' , strokeWidth : 2 , fill : '#050505' } }
150+ />
151+ </ LineChart >
152+ </ ResponsiveContainer >
153+ ) : (
154+ < div className = "h-full border border-dashed border-border/40 flex items-center justify-center text-xs uppercase tracking-widest opacity-40" >
155+ No cost trend telemetry available
156+ </ div >
157+ ) }
151158 </ div >
152159 </ CyberCard >
153160
154161 { /* Feature Distribution */ }
155162 < CyberCard title = "FEATURE_DISTRIBUTION" subtitle = "Cost by AI capability" >
156163 < div className = "h-[300px] w-full flex flex-col items-center" >
157- < ResponsiveContainer width = "100%" height = { 220 } >
158- < PieChart >
159- < Pie
160- data = { featureData }
161- cx = "50%"
162- cy = "50%"
163- innerRadius = { 60 }
164- outerRadius = { 80 }
165- paddingAngle = { 5 }
166- dataKey = "cost"
167- nameKey = "feature"
168- >
169- { featureData . map ( ( _ , index ) => (
170- < Cell key = { `cell-${ index } ` } fill = { COLORS [ index % COLORS . length ] } />
171- ) ) }
172- </ Pie >
173- < Tooltip
174- contentStyle = { { backgroundColor : '#0a0a0a' , border : '1px solid #333' , fontSize : '10px' } }
175- />
176- </ PieChart >
177- </ ResponsiveContainer >
164+ { featureChartData . length > 0 ? (
165+ < ResponsiveContainer width = "100%" height = { 220 } minWidth = { 1 } minHeight = { 1 } >
166+ < PieChart >
167+ < Pie
168+ data = { featureChartData }
169+ cx = "50%"
170+ cy = "50%"
171+ innerRadius = { 60 }
172+ outerRadius = { 80 }
173+ paddingAngle = { 5 }
174+ dataKey = "cost"
175+ nameKey = "feature"
176+ >
177+ { featureChartData . map ( ( _ , index ) => (
178+ < Cell key = { `cell-${ index } ` } fill = { COLORS [ index % COLORS . length ] } />
179+ ) ) }
180+ </ Pie >
181+ < Tooltip
182+ contentStyle = { { backgroundColor : '#0a0a0a' , border : '1px solid #333' , fontSize : '10px' } }
183+ />
184+ </ PieChart >
185+ </ ResponsiveContainer >
186+ ) : (
187+ < div className = "h-[220px] w-full border border-dashed border-border/40 flex items-center justify-center text-xs uppercase tracking-widest opacity-40" >
188+ No feature telemetry available
189+ </ div >
190+ ) }
178191 < div className = "grid grid-cols-2 gap-x-4 gap-y-1 w-full px-4" >
179192 { featureData . map ( ( entry , index ) => (
180193 < div key = { entry . feature } className = "flex items-center gap-2" >
@@ -233,4 +246,3 @@ export default function AIUsagePage() {
233246 </ div >
234247 ) ;
235248}
236-
0 commit comments