1+ import { Table , TableBody , TableCell , TableHead , TableHeader , TableRow } from "@/components/ui/table"
2+ import { Card , CardContent , CardHeader , CardTitle , CardFooter } from "@/components/ui/card"
3+ import { formatPercentage } from "@/lib/utils"
4+ import { useState } from "react"
5+ import { ArrowUpDown , ChevronLeft , ChevronRight } from "lucide-react"
6+ import { Button } from "@/components/ui/button"
7+
8+ interface IncidentType {
9+ title : string
10+ cloud : string
11+ cluster : string
12+ total_incidents : number
13+ high_urgency_incidents : number
14+ example_title : string
15+ }
16+
17+ interface IncidentCategoriesTableProps {
18+ data : IncidentType [ ]
19+ page : number
20+ onPageChange : ( page : number ) => void
21+ pageSize : number
22+ isLoading : boolean
23+ }
24+
25+ export default function IncidentCategoriesTable ( { data, onPageChange, page, pageSize, isLoading } : IncidentCategoriesTableProps ) {
26+ const [ sortConfig , setSortConfig ] = useState < {
27+ key : keyof IncidentType
28+ direction : 'asc' | 'desc'
29+ } > ( { key : 'total_incidents' , direction : 'desc' } )
30+
31+ const sortedData = [ ...data ] . sort ( ( a , b ) => {
32+ if ( sortConfig . direction === 'asc' ) {
33+ return a [ sortConfig . key ] > b [ sortConfig . key ] ? 1 : - 1
34+ }
35+ return a [ sortConfig . key ] < b [ sortConfig . key ] ? 1 : - 1
36+ } )
37+
38+ const requestSort = ( key : keyof IncidentType ) => {
39+ setSortConfig ( {
40+ key,
41+ direction : sortConfig . key === key && sortConfig . direction === 'asc' ? 'desc' : 'asc' ,
42+ } )
43+ }
44+
45+ return (
46+ < Card >
47+ < CardHeader >
48+ < CardTitle > Incident Categories</ CardTitle >
49+ </ CardHeader >
50+ < CardContent >
51+ < Table >
52+ < TableHeader >
53+ < TableRow >
54+ < TableHead className = "max-w-[300px]" >
55+ < Button variant = "ghost" onClick = { ( ) => requestSort ( 'title' ) } >
56+ Title < ArrowUpDown className = "ml-2 h-4 w-4" />
57+ </ Button >
58+ </ TableHead >
59+ < TableHead className = "max-w-[100px]" >
60+ < Button variant = "ghost" onClick = { ( ) => requestSort ( 'cloud' ) } >
61+ Cloud < ArrowUpDown className = "ml-2 h-4 w-4" />
62+ </ Button >
63+ </ TableHead >
64+ < TableHead className = "max-w-[150px]" >
65+ < Button variant = "ghost" onClick = { ( ) => requestSort ( 'cluster' ) } >
66+ Cluster < ArrowUpDown className = "ml-2 h-4 w-4" />
67+ </ Button >
68+ </ TableHead >
69+ < TableHead className = "text-right" >
70+ < Button variant = "ghost" onClick = { ( ) => requestSort ( 'total_incidents' ) } >
71+ Total < ArrowUpDown className = "ml-2 h-4 w-4" />
72+ </ Button >
73+ </ TableHead >
74+ < TableHead className = "text-right" >
75+ < Button variant = "ghost" onClick = { ( ) => requestSort ( 'high_urgency_incidents' ) } >
76+ High Urgency < ArrowUpDown className = "ml-2 h-4 w-4" />
77+ </ Button >
78+ </ TableHead >
79+ </ TableRow >
80+ </ TableHeader >
81+ < TableBody >
82+ { isLoading ? (
83+ < TableRow >
84+ < TableCell colSpan = { 5 } className = "text-center" >
85+ Loading...
86+ </ TableCell >
87+ </ TableRow >
88+ ) : (
89+ sortedData . map ( ( item ) => (
90+ < TableRow key = { `${ item . title } -${ item . cloud } -${ item . cluster } ` } >
91+ < TableCell className = "truncate max-w-[300px]" > { item . title } </ TableCell >
92+ < TableCell className = "truncate max-w-[100px]" > { item . cloud } </ TableCell >
93+ < TableCell className = "truncate max-w-[150px]" > { item . cluster } </ TableCell >
94+ < TableCell className = "text-right" > { item . total_incidents } </ TableCell >
95+ < TableCell className = "text-right" > { parseInt ( formatPercentage ( item . high_urgency_incidents / item . total_incidents * 100 ) ) } %</ TableCell >
96+ </ TableRow >
97+ ) )
98+ ) }
99+ </ TableBody >
100+ </ Table >
101+ </ CardContent >
102+ < CardFooter className = "flex items-center justify-end space-x-2" >
103+ < Button
104+ variant = "outline"
105+ size = "sm"
106+ onClick = { ( ) => onPageChange ( Math . max ( 0 , page - 1 ) ) }
107+ disabled = { page === 0 }
108+ >
109+ < ChevronLeft className = "h-4 w-4" />
110+ Previous
111+ </ Button >
112+ < div className = "flex items-center gap-1" >
113+ < span className = "text-sm text-muted-foreground" >
114+ Page { page + 1 }
115+ </ span >
116+ </ div >
117+ < Button
118+ variant = "outline"
119+ size = "sm"
120+ onClick = { ( ) => onPageChange ( page + 1 ) }
121+ disabled = { data . length < pageSize }
122+ >
123+ Next
124+ < ChevronRight className = "h-4 w-4" />
125+ </ Button >
126+ </ CardFooter >
127+ </ Card >
128+ )
129+ }
0 commit comments