@@ -10,15 +10,19 @@ import { Button } from "@/components/ui/button";
1010import { Separator } from "@/components/ui/separator" ;
1111import { ChartContainer , ChartTooltip , ChartTooltipContent } from "@/components/ui/chart" ;
1212import { Table , TableBody , TableCell , TableHead , TableHeader , TableRow } from "@/components/ui/table" ;
13+ import { Sheet , SheetContent , SheetHeader , SheetTitle , SheetTrigger } from "@/components/ui/sheet" ;
1314import {
1415 AggregatedData ,
1516 CopilotUsageData ,
1617 ModelUsageSummary ,
1718 DailyModelData ,
19+ PowerUserSummary ,
1820 aggregateDataByDay ,
1921 parseCSV ,
2022 getModelUsageSummary ,
21- getDailyModelData
23+ getDailyModelData ,
24+ getPowerUsers ,
25+ getPowerUserDailyData
2226} from "@/lib/utils" ;
2327
2428function App ( ) {
@@ -27,6 +31,7 @@ function App() {
2731 const [ uniqueModels , setUniqueModels ] = useState < string [ ] > ( [ ] ) ;
2832 const [ modelSummary , setModelSummary ] = useState < ModelUsageSummary [ ] > ( [ ] ) ;
2933 const [ dailyModelData , setDailyModelData ] = useState < DailyModelData [ ] > ( [ ] ) ;
34+ const [ powerUserSummary , setPowerUserSummary ] = useState < PowerUserSummary | null > ( null ) ;
3035 const [ isDragging , setIsDragging ] = useState ( false ) ;
3136 const fileInputRef = useRef < HTMLInputElement > ( null ) ;
3237
@@ -79,6 +84,10 @@ function App() {
7984 const dailyData = getDailyModelData ( parsedData ) ;
8085 setDailyModelData ( dailyData ) ;
8186
87+ // Get power users data
88+ const powerUsers = getPowerUsers ( parsedData ) ;
89+ setPowerUserSummary ( powerUsers ) ;
90+
8291 toast . success ( `Loaded ${ parsedData . length } records successfully` ) ;
8392 } catch ( error ) {
8493 // Provide user-friendly error messages
@@ -115,6 +124,7 @@ function App() {
115124 setAggregatedData ( [ ] ) ;
116125 setModelSummary ( [ ] ) ;
117126 setDailyModelData ( [ ] ) ;
127+ setPowerUserSummary ( null ) ;
118128 }
119129 } ;
120130
@@ -344,6 +354,138 @@ function App() {
344354 { uniqueModels . length }
345355 </ span >
346356 </ div >
357+ { powerUserSummary && (
358+ < Sheet >
359+ < SheetTrigger asChild >
360+ < Button variant = "outline" className = "flex items-center gap-2" >
361+ < span className = "text-sm" > Power Users:</ span >
362+ < span className = "font-bold" > { powerUserSummary . totalPowerUsers } </ span >
363+ </ Button >
364+ </ SheetTrigger >
365+ < SheetContent className = "w-[600px] sm:w-[800px] overflow-y-auto" >
366+ < SheetHeader >
367+ < SheetTitle > Power Users Analysis</ SheetTitle >
368+ </ SheetHeader >
369+ < div className = "mt-6 space-y-6" >
370+ { /* Power User Summary */ }
371+ < div className = "grid grid-cols-1 lg:grid-cols-2 gap-4" >
372+ < Card className = "p-4" >
373+ < h3 className = "text-md font-medium mb-3" > Total Requests by Power Users</ h3 >
374+ < div className = "space-y-2" >
375+ < div className = "flex justify-between items-center" >
376+ < span className = "text-sm text-muted-foreground" > Total Requests:</ span >
377+ < span className = "font-bold" >
378+ { powerUserSummary . totalPowerUserRequests . toLocaleString ( undefined , { maximumFractionDigits : 2 , minimumFractionDigits : 0 } ) }
379+ </ span >
380+ </ div >
381+ < div className = "flex justify-between items-center" >
382+ < span className = "text-sm text-muted-foreground" > Power Users Count:</ span >
383+ < span className = "font-bold" > { powerUserSummary . totalPowerUsers } </ span >
384+ </ div >
385+ </ div >
386+ </ Card >
387+
388+ < Card className = "p-4" >
389+ < h3 className = "text-md font-medium mb-3" > Requests per Model</ h3 >
390+ < div className = "overflow-auto max-h-40" >
391+ < Table >
392+ < TableHeader >
393+ < TableRow >
394+ < TableHead > Model</ TableHead >
395+ < TableHead className = "text-right" > Requests</ TableHead >
396+ </ TableRow >
397+ </ TableHeader >
398+ < TableBody >
399+ { powerUserSummary . powerUserModelSummary . map ( ( item ) => (
400+ < TableRow key = { item . model } >
401+ < TableCell className = "font-medium" > { item . model } </ TableCell >
402+ < TableCell className = "text-right" > { item . totalRequests . toLocaleString ( undefined , { maximumFractionDigits : 2 , minimumFractionDigits : 0 } ) } </ TableCell >
403+ </ TableRow >
404+ ) ) }
405+ </ TableBody >
406+ </ Table >
407+ </ div >
408+ </ Card >
409+ </ div >
410+
411+ { /* Power User Activity Chart */ }
412+ < Card className = "p-4" >
413+ < h3 className = "text-md font-medium mb-3" > Power User Activity Over Time</ h3 >
414+ < div className = "h-[300px]" >
415+ < ChartContainer
416+ config = { {
417+ requests : { color : "#3b82f6" } ,
418+ } }
419+ className = "h-full w-full"
420+ >
421+ < LineChart data = { getPowerUserDailyData ( powerUserSummary . powerUsers ) } >
422+ < CartesianGrid strokeDasharray = "3 3" opacity = { 0.2 } />
423+ < XAxis
424+ dataKey = "date"
425+ tick = { { fill : 'var(--foreground)' } }
426+ tickLine = { { stroke : 'var(--border)' } }
427+ />
428+ < YAxis
429+ tick = { { fill : 'var(--foreground)' } }
430+ tickLine = { { stroke : 'var(--border)' } }
431+ />
432+ < ChartTooltip
433+ content = { ( { active, payload, label } ) => {
434+ if ( active && payload && payload . length ) {
435+ return (
436+ < div className = "border rounded-lg bg-background shadow-lg p-3 text-xs" >
437+ < div className = "font-medium mb-2" > { label } </ div >
438+ < div className = "flex items-center gap-2" >
439+ < div className = "w-2 h-2 rounded-full bg-[#3b82f6]" />
440+ < span > Requests: { Number ( payload [ 0 ] . value ) . toLocaleString ( undefined , { maximumFractionDigits : 2 , minimumFractionDigits : 0 } ) } </ span >
441+ </ div >
442+ </ div >
443+ ) ;
444+ }
445+ return null ;
446+ } }
447+ />
448+ < Line
449+ type = "monotone"
450+ dataKey = "requests"
451+ name = "Requests"
452+ stroke = "#3b82f6"
453+ strokeWidth = { 2 }
454+ activeDot = { { r : 6 } }
455+ />
456+ </ LineChart >
457+ </ ChartContainer >
458+ </ div >
459+ </ Card >
460+
461+ { /* Individual Power Users List */ }
462+ < Card className = "p-4" >
463+ < h3 className = "text-md font-medium mb-3" > Individual Power Users</ h3 >
464+ < div className = "overflow-auto max-h-60" >
465+ < Table >
466+ < TableHeader >
467+ < TableRow >
468+ < TableHead > User</ TableHead >
469+ < TableHead className = "text-right" > Total Requests</ TableHead >
470+ < TableHead className = "text-right" > Models Used</ TableHead >
471+ </ TableRow >
472+ </ TableHeader >
473+ < TableBody >
474+ { powerUserSummary . powerUsers . map ( ( user ) => (
475+ < TableRow key = { user . user } >
476+ < TableCell className = "font-medium" > { user . user } </ TableCell >
477+ < TableCell className = "text-right" > { user . totalRequests . toLocaleString ( undefined , { maximumFractionDigits : 2 , minimumFractionDigits : 0 } ) } </ TableCell >
478+ < TableCell className = "text-right" > { Object . keys ( user . requestsByModel ) . length } </ TableCell >
479+ </ TableRow >
480+ ) ) }
481+ </ TableBody >
482+ </ Table >
483+ </ div >
484+ </ Card >
485+ </ div >
486+ </ SheetContent >
487+ </ Sheet >
488+ ) }
347489 </ div >
348490 </ div >
349491 </ Card >
0 commit comments