11import React , { useState } from 'react' ;
2- import {
3- TextField ,
4- FormControl ,
5- FormLabel ,
6- Select ,
7- MenuItem ,
8- SelectChangeEvent ,
9- TableCell ,
10- TableRow ,
11- Grid ,
12- Typography
13- } from '@mui/material' ;
2+ import { TextField , FormControl , FormLabel , TableCell , TableRow , Grid , Typography } from '@mui/material' ;
143import AdminToolTable from './AdminToolTable' ;
4+ import { useAllTeams } from '../../hooks/teams.hooks' ;
5+ import LoadingIndicator from '../../components/LoadingIndicator' ;
6+ import ErrorPage from '../ErrorPage' ;
7+ import { fullNamePipe } from '../../utils/pipes' ;
8+ import { useAllUsers } from '../../hooks/users.hooks' ;
9+ import { useAllDesignReviews } from '../../hooks/design-reviews.hooks' ;
1510
1611const AdminToolsAttendeeDesignReviewInfo : React . FC = ( ) => {
17- const [ selectedTeam , setSelectedTeam ] = useState ( '' ) ;
1812 const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
1913
20- // TODO: to be deleted later, this is just stub data for filter options
21- const teams = [ 'All' , 'Team A' , 'Team B' , 'Team C' ] ;
14+ const { data : allTeams , isLoading : teamsIsLoading , isError : teamsIsError , error : teamsError } = useAllTeams ( ) ;
15+ const { data : allUsers , isLoading : usersIsLoading , isError : usersIsError , error : usersError } = useAllUsers ( ) ;
16+ const {
17+ data : allDesignReviews ,
18+ isLoading : designReviewsIsLoading ,
19+ isError : designReviewsIsError ,
20+ error : designReviewsError
21+ } = useAllDesignReviews ( ) ;
2222
23- // TODO: Stub data for team members, replace with dynamic data here
24- const teamMembers = [
25- { name : 'Batman' , reviewsAttended : 2 , missedReviews : 4 } ,
26- { name : 'Superman' , reviewsAttended : 4 , missedReviews : 1 }
27- ] ;
23+ if ( ! allTeams || teamsIsLoading || ! allUsers || usersIsLoading || ! allDesignReviews || designReviewsIsLoading )
24+ return < LoadingIndicator /> ;
25+ if ( teamsIsError ) return < ErrorPage message = { teamsError . message } /> ;
26+ if ( usersIsError ) return < ErrorPage message = { usersError . message } /> ;
27+ if ( designReviewsIsError ) return < ErrorPage message = { designReviewsError . message } /> ;
2828
29- // TODO: Filtering team members based on search query here
30- const filteredMembers = teamMembers . filter ( ( member ) => member . name . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) ) ) ;
31-
32- // TODO: Filtering for teams backend logic comes here
33- const handleTeamChange = ( event : SelectChangeEvent ) => {
34- setSelectedTeam ( event . target . value as string ) ;
35- } ;
29+ const filteredMembers = allUsers . filter ( ( member ) =>
30+ fullNamePipe ( member ) . toLowerCase ( ) . includes ( searchQuery . toLowerCase ( ) )
31+ ) ;
3632
3733 const handleSearchChange = ( event : React . ChangeEvent < HTMLInputElement > ) => {
3834 setSearchQuery ( event . target . value ) ;
3935 } ;
4036
37+ const attendanceDict : Map < number , number > = new Map ( ) ;
38+ const missedDict : Map < number , number > = new Map ( ) ;
39+
40+ allDesignReviews . forEach ( ( review ) => {
41+ review . attendees . forEach ( ( member ) => {
42+ if ( attendanceDict . has ( member . userId ) ) {
43+ attendanceDict . set ( member . userId , attendanceDict . get ( member . userId ) ! + 1 ) ;
44+ } else {
45+ attendanceDict . set ( member . userId , 1 ) ;
46+ }
47+ } ) ;
48+ review . requiredMembers . forEach ( ( member ) => {
49+ if ( ! review . attendees . map ( ( user ) => user . userId ) . includes ( member . userId ) ) {
50+ if ( missedDict . has ( member . userId ) ) {
51+ missedDict . set ( member . userId , missedDict . get ( member . userId ) ! + 1 ) ;
52+ } else {
53+ missedDict . set ( member . userId , 1 ) ;
54+ }
55+ }
56+ } ) ;
57+ } ) ;
58+
4159 const attendeeRows = filteredMembers . map ( ( member , index ) => (
4260 < TableRow key = { index } >
43- < TableCell sx = { { border : '2px solid black' } } > { member . name } </ TableCell >
44- < TableCell sx = { { border : '2px solid black' } } > { member . reviewsAttended } </ TableCell >
45- < TableCell sx = { { border : '2px solid black' } } > { member . missedReviews } </ TableCell >
61+ < TableCell sx = { { border : '2px solid black' } } > { fullNamePipe ( member ) } </ TableCell >
62+ < TableCell sx = { { border : '2px solid black' } } > { attendanceDict . get ( member . userId ) ?? 0 } </ TableCell >
63+ < TableCell sx = { { border : '2px solid black' } } > { missedDict . get ( member . userId ) ?? 0 } </ TableCell >
4664 </ TableRow >
4765 ) ) ;
4866
@@ -55,24 +73,6 @@ const AdminToolsAttendeeDesignReviewInfo: React.FC = () => {
5573 < FormLabel htmlFor = "search-by-name" > Search by team member name</ FormLabel >
5674 < TextField id = "search-by-name" variant = "outlined" value = { searchQuery } onChange = { handleSearchChange } fullWidth />
5775 </ FormControl >
58- < FormControl fullWidth sx = { { marginBottom : 2 } } >
59- < FormLabel id = "team-select-label" > Team</ FormLabel >
60- < Select
61- labelId = "team-select-label"
62- id = "team-select"
63- value = { selectedTeam }
64- onChange = { handleTeamChange }
65- displayEmpty
66- fullWidth
67- >
68- { teams . map ( ( team ) => (
69- < MenuItem key = { team } value = { team } >
70- { team }
71- </ MenuItem >
72- ) ) }
73- { /* TODO: we'll have to change this here as well for backend logic, above is just a stub implementation. */ }
74- </ Select >
75- </ FormControl >
7676 < AdminToolTable
7777 columns = { [
7878 { name : 'Team Member Name' , width : '33%' } ,
0 commit comments