1+ import { useQuery } from '@apollo/client' ;
12import React , { useState } from 'react' ;
23import { FaEye } from 'react-icons/fa' ;
4+ import { useTranslation } from 'react-i18next' ;
5+ import DataTable from './DataTable' ;
6+ import { GET_TEAMS_CARDS } from './CoordinatorCard' ;
37import TeamDetailsModal from './AdminTeamDetails' ;
48
5- interface TeamData {
6- ttlName ?: string ;
7- team ?: string ;
8- organization ?: string ;
9- program ?: string ;
10- phase ?: string ;
11- cohort ?: string ;
12- activeUsers ?: number ;
13- droppedUsers ?: number ;
14- rating ?: number ;
15- logins : string ;
16- users : number ;
17- }
18-
19- const DashboardTableDesign : React . FC = ( ) => {
20- const [ selectedTeam , setSelectedTeam ] = useState < TeamData | null > ( null ) ;
9+ function DashboardTableDesign ( ) {
10+ const { t } = useTranslation ( ) ;
11+ const [ selectedTeam , setSelectedTeam ] = useState < any | null > ( null ) ;
2112 const [ isModalOpen , setIsModalOpen ] = useState < boolean > ( false ) ;
2213
23- const dummyData : TeamData [ ] = [
24- {
25- team : 'Nova' ,
26- logins : '2.4k' ,
27- users : 45 ,
28- ttlName : 'Sostene' ,
29- organization : 'Tech Corp' ,
30- program : 'Atlp1' ,
31- phase : 'Phase 2' ,
32- cohort : 'Cohort 3' ,
33- activeUsers : 42 ,
34- droppedUsers : 3 ,
35- rating : 4.8
36- } ,
37- {
38- team : 'Fighters' ,
39- logins : '1.8k' ,
40- users : 32 ,
41- ttlName : 'Sostene' ,
42- organization : 'Andela' ,
43- program : 'Atlp1' ,
44- phase : 'Phase 1' ,
45- cohort : 'Cohort 2' ,
46- activeUsers : 30 ,
47- droppedUsers : 2 ,
48- rating : 4.5
49- } ,
50- {
51- team : 'Bitcrafters' ,
52- logins : '1.2k' ,
53- users : 28 ,
54- ttlName : 'Jacqueline' ,
55- organization : 'Irembo' ,
56- program : 'Data Science' ,
57- phase : 'Phase 3' ,
58- cohort : 'Cohort 1' ,
59- activeUsers : 25 ,
60- droppedUsers : 3 ,
61- rating : 4.6
14+ const {
15+ data : TeamsData ,
16+ loading,
17+ error,
18+ refetch,
19+ } = useQuery ( GET_TEAMS_CARDS , {
20+ variables : {
21+ orgToken : localStorage . getItem ( 'orgToken' ) ,
6222 } ,
63- {
64- team : 'Team1' ,
65- logins : '3.1k' ,
66- users : 52 ,
67- ttlName : 'Alice' ,
68- organization : 'Tech Corp' ,
69- program : 'Cloud Computing' ,
70- phase : 'Phase 2' ,
71- cohort : 'Cohort 4' ,
72- activeUsers : 48 ,
73- droppedUsers : 4 ,
74- rating : 4.7
75- } ,
76- {
77- team : 'Team2' ,
78- logins : '0.9k' ,
79- users : 19 ,
80- ttlName : 'Bob' ,
81- organization : 'Tech' ,
82- program : 'DevOps' ,
83- phase : 'Phase 1' ,
84- cohort : 'Cohort 2' ,
85- activeUsers : 17 ,
86- droppedUsers : 2 ,
87- rating : 4.4
88- }
89- ] ;
23+ fetchPolicy : 'network-only' ,
24+ } ) ;
25+
26+ const TableData = TeamsData ?. getAllTeams . map ( ( items : any ) => ( {
27+ teams : items . name ,
28+ users : items . members . length ,
29+ logins : items . members . reduce (
30+ ( total : number , i : any ) => total + i . profile . activity . length ,
31+ 0 ,
32+ ) ,
33+ } ) ) ;
9034
91- const handleViewClick = ( team : TeamData ) => {
35+ const handleViewClick = ( team : any ) => {
9236 setSelectedTeam ( team ) ;
9337 setIsModalOpen ( true ) ;
9438 } ;
9539
40+ const organizationColumns = [
41+ { Header : t ( 'Teams' ) , accessor : 'teams' } ,
42+ { Header : t ( 'Logins' ) , accessor : 'logins' } ,
43+ { Header : t ( 'Users' ) , accessor : 'users' } ,
44+ {
45+ Header : t ( 'action' ) ,
46+ accessor : '' ,
47+ Cell : ( { row } : any ) => (
48+ < button
49+ type = "button"
50+ className = "flex items-center space-x-2 text-blue-500 hover:text-blue-700"
51+ aria-label = "View"
52+ onClick = { ( ) => handleViewClick ( row . original ) }
53+ >
54+ < FaEye className = "w-4 h-4" />
55+ < span > { t ( 'View' ) } </ span >
56+ </ button >
57+ ) ,
58+ } ,
59+ ] ;
9660 return (
9761 < div className = "w-full max-w-7xl mx-auto px-6 space-y-4" >
98- < div className = "flex justify-between items-center mb-6" >
99- < h2 className = "text-xl font-semibold text-gray-800 dark:text-gray-200" > Team Analytics</ h2 >
100- < div className = "flex gap-3" >
101- < input
102- type = "search"
103- placeholder = "Search teams..."
104- className = "px-4 py-2 bg-white dark:bg-gray-700 rounded-lg text-sm text-gray-700 dark:text-gray-200 border border-gray-200 dark:border-gray-600 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500"
105- />
106- </ div >
107- </ div >
108-
109- < div className = "bg-white dark:bg-gray-800 rounded-xl shadow-lg dark:shadow-xl overflow-hidden border border-gray-200 dark:border-gray-700" >
110- < div className = "overflow-x-auto" >
111- < table className = "w-full table-fixed" >
112- < thead >
113- < tr className = "bg-gray-50 dark:bg-gray-900" >
114- < th className = "w-[30%] px-6 py-4 text-left" >
115- < div className = "flex items-center gap-2 text-sm font-semibold text-gray-700 dark:text-gray-300" >
116- Team Name
117- </ div >
118- </ th >
119- < th className = "w-[25%] px-6 py-4 text-left" >
120- < div className = "flex items-center gap-2 text-sm font-semibold text-gray-700 dark:text-gray-300" >
121- Logins
122- </ div >
123- </ th >
124- < th className = "w-[25%] px-6 py-4 text-left" >
125- < div className = "flex items-center gap-2 text-sm font-semibold text-gray-700 dark:text-gray-300" >
126- Users
127- </ div >
128- </ th >
129- < th className = "w-[20%] px-10 py-4 text-left" >
130- < div className = "flex items-center gap-2 text-sm font-semibold text-gray-700 dark:text-gray-300" >
131- Actions
132- </ div >
133- </ th >
134- </ tr >
135- </ thead >
136- < tbody >
137- { dummyData . map ( ( row , index ) => (
138- < tr
139- key = { index }
140- className = "border-t border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors"
141- >
142- < td className = "px-6 py-4" >
143- < div className = "flex items-center gap-3" >
144- < div className = "w-2 h-2 rounded-full bg-blue-500" > </ div >
145- < span className = "text-gray-800 dark:text-gray-200 font-medium" > { row . team } </ span >
146- </ div >
147- </ td >
148- < td className = "px-6 py-4" >
149- < div className = "text-gray-600 dark:text-gray-300" > { row . logins } </ div >
150- </ td >
151- < td className = "px-6 py-4" >
152- < div className = "inline-flex items-center px-3 py-1 rounded-full bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300" >
153- { row . users }
154- </ div >
155- </ td >
156- < td className = "px-6 py-4" >
157- < button
158- onClick = { ( ) => handleViewClick ( row ) }
159- className = "flex items-center justify-center gap-2 px-4 py-2 text-sm text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-500/10 rounded-full hover:bg-blue-100 dark:hover:bg-blue-500/20 transition-colors"
160- >
161- < FaEye className = "text-xs" />
162- View
163- </ button >
164- </ td >
165- </ tr >
166- ) ) }
167- </ tbody >
168- </ table >
169- </ div >
170-
171- < div className = "px-6 py-4 bg-gray-50 dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 flex items-center justify-between" >
172- < div className = "text-sm text-gray-500 dark:text-gray-400" >
173- Showing 5 of 12 teams
174- </ div >
175- < div className = "flex gap-2" >
176- < button className = "px-4 py-2 text-sm text-gray-600 dark:text-gray-300 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" >
177- Previous
178- </ button >
179- < button className = "px-4 py-2 text-sm text-gray-600 dark:text-gray-300 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors" >
180- Next
181- </ button >
182- </ div >
183- </ div >
184- </ div >
185-
186- < TeamDetailsModal
62+ < DataTable
63+ columns = { organizationColumns }
64+ data = { TableData ? ( TableData as any [ ] ) : [ ] }
65+ title = { t ( 'Teams metrices' ) }
66+ loading = { loading }
67+ />
68+ < TeamDetailsModal
18769 isOpen = { isModalOpen }
18870 onClose = { ( ) => setIsModalOpen ( false ) }
18971 teamData = { selectedTeam }
19072 />
19173 </ div >
19274 ) ;
193- } ;
75+ }
19476
195- export default DashboardTableDesign ;
77+ export default DashboardTableDesign ;
0 commit comments