55
66import { Autocomplete , Box , Grid , IconButton , TextField , Typography } from '@mui/material' ;
77import { useState } from 'react' ;
8- import { useAuth } from '../../hooks/auth.hooks' ;
9- import { useAllUsers } from '../../hooks/users.hooks' ;
10- import { useSetTeamHead , useSetTeamMembers } from '../../hooks/teams.hooks' ;
11- import { isAdmin , isHead , Team , User } from 'shared' ;
8+ import { useAllUsers , useCurrentUser } from '../../hooks/users.hooks' ;
9+ import { useSetTeamHead , useSetTeamLeads , useSetTeamMembers } from '../../hooks/teams.hooks' ;
10+ import { isAdmin , isHead , isLeadership , Team , User } from 'shared' ;
1211import { fullNamePipe } from '../../utils/pipes' ;
1312import { Cancel , Edit , Save } from '@mui/icons-material' ;
1413import LoadingIndicator from '../../components/LoadingIndicator' ;
@@ -27,22 +26,26 @@ const userToAutocompleteOption = (user: User): { label: string; id: string } =>
2726} ;
2827
2928const TeamMembersPageBlock : React . FC < TeamMembersPageBlockProps > = ( { team } ) => {
30- const auth = useAuth ( ) ;
29+ const user = useCurrentUser ( ) ;
3130 const [ isEditingMembers , setIsEditingMembers ] = useState ( false ) ;
3231 const [ isEditingHead , setIsEditingHead ] = useState ( false ) ;
32+ const [ isEditingLeads , setIsEditingLeads ] = useState ( false ) ;
3333 const [ members , setMembers ] = useState ( team . members . map ( userToAutocompleteOption ) ) ;
3434 const [ head , setHead ] = useState ( userToAutocompleteOption ( team . head ) ) ;
35+ const [ leads , setLeads ] = useState ( team . leads . map ( userToAutocompleteOption ) ) ;
3536
3637 const { isLoading : allUsersIsLoading , isError : allUsersIsError , error : allUsersError , data : users } = useAllUsers ( ) ;
3738 const { isLoading : setTeamMembersIsLoading , mutateAsync : setTeamMembersMutateAsync } = useSetTeamMembers ( team . teamId ) ;
3839 const { isLoading : setTeamHeadIsLoading , mutateAsync : setTeamHeadMutateAsync } = useSetTeamHead ( team . teamId ) ;
40+ const { isLoading : setTeamLeadsIsLoading , mutateAsync : setTeamLeadsMutateAsync } = useSetTeamLeads ( team . teamId ) ;
3941
4042 const toast = useToast ( ) ;
4143
4244 if ( allUsersIsError ) return < ErrorPage message = { allUsersError ?. message } /> ;
43- if ( allUsersIsLoading || setTeamMembersIsLoading || setTeamHeadIsLoading || ! users ) return < LoadingIndicator /> ;
45+ if ( allUsersIsLoading || setTeamMembersIsLoading || setTeamHeadIsLoading || setTeamLeadsIsLoading || ! users )
46+ return < LoadingIndicator /> ;
4447
45- const hasPerms = auth . user && ( isAdmin ( auth . user . role ) || auth . user . userId === team . head . userId ) ;
48+ const hasPerms = isAdmin ( user . role ) || user . userId === team . head . userId ;
4649
4750 const memberOptions = users
4851 . filter ( ( user ) => user . userId !== team . head . userId && ! team . leads . map ( ( lead ) => lead . userId ) . includes ( user . userId ) )
@@ -54,6 +57,11 @@ const TeamMembersPageBlock: React.FC<TeamMembersPageBlockProps> = ({ team }) =>
5457 . sort ( ( a , b ) => ( a . firstName > b . firstName ? 1 : - 1 ) )
5558 . map ( userToAutocompleteOption ) ;
5659
60+ const leadOptions = users
61+ . filter ( ( user ) => memberOptions . some ( ( option ) => parseInt ( option . id ) === user . userId ) && isLeadership ( user . role ) )
62+ . sort ( ( a , b ) => ( a . firstName > b . firstName ? 1 : - 1 ) )
63+ . map ( userToAutocompleteOption ) ;
64+
5765 const submitHead = async ( ) => {
5866 try {
5967 await setTeamHeadMutateAsync ( parseInt ( head . id ) ) ;
@@ -72,6 +80,15 @@ const TeamMembersPageBlock: React.FC<TeamMembersPageBlockProps> = ({ team }) =>
7280 }
7381 } ;
7482
83+ const submitLeads = async ( ) => {
84+ try {
85+ await setTeamLeadsMutateAsync ( leads . map ( ( lead ) => parseInt ( lead . id ) ) ) ;
86+ setIsEditingLeads ( false ) ;
87+ } catch ( error ) {
88+ error instanceof Error && toast . error ( error . message ) ;
89+ }
90+ } ;
91+
7592 const EditingHeadView = ( ) => (
7693 < Grid container spacing = { 1 } >
7794 < Grid item >
@@ -132,6 +149,37 @@ const TeamMembersPageBlock: React.FC<TeamMembersPageBlockProps> = ({ team }) =>
132149 </ Box >
133150 ) ;
134151
152+ const EditingLeadsView = ( ) => (
153+ < Box >
154+ < Typography sx = { { fontWeight : 'bold' } } display = "inline" >
155+ Leads:
156+ </ Typography >
157+ < Grid container direction = { 'row' } >
158+ < Grid item xs = { 9 } md = { 10 } lg = { 11 } >
159+ < Autocomplete
160+ isOptionEqualToValue = { ( option , value ) => option . id === value . id }
161+ filterSelectedOptions
162+ multiple
163+ id = "tags-standard"
164+ options = { leadOptions }
165+ value = { leads }
166+ onChange = { ( _event , newValue ) => setLeads ( newValue ) }
167+ getOptionLabel = { ( option ) => option . label }
168+ renderInput = { ( params ) => < TextField { ...params } variant = "standard" placeholder = "Select A Lead" /> }
169+ />
170+ </ Grid >
171+ < Grid container xs = { 3 } md = { 2 } lg = { 1 } >
172+ < Grid item >
173+ < IconButton children = { < Save /> } onClick = { submitLeads } />
174+ </ Grid >
175+ < Grid item >
176+ < IconButton children = { < Cancel /> } onClick = { ( ) => setIsEditingLeads ( false ) } />
177+ </ Grid >
178+ </ Grid >
179+ </ Grid >
180+ </ Box >
181+ ) ;
182+
135183 const NonEditingHeadView = ( ) => (
136184 < Grid container >
137185 < Grid item >
@@ -144,7 +192,14 @@ const TeamMembersPageBlock: React.FC<TeamMembersPageBlockProps> = ({ team }) =>
144192 ) ;
145193
146194 const NonEditingLeadsView = ( ) => (
147- < DetailDisplay label = "Leads" content = { team . leads . map ( ( lead ) => fullNamePipe ( lead ) ) . join ( ', ' ) } />
195+ < Grid container >
196+ < Grid item xs = { 11 } lg = "auto" >
197+ < DetailDisplay label = "Leads" content = { team . leads . map ( ( lead ) => fullNamePipe ( lead ) ) . join ( ', ' ) } />
198+ </ Grid >
199+ < Grid item xs = { 1 } mt = { - 1 } >
200+ { hasPerms && < IconButton children = { < Edit /> } onClick = { ( ) => setIsEditingLeads ( true ) } /> }
201+ </ Grid >
202+ </ Grid >
148203 ) ;
149204
150205 const NonEditingMembersView = ( ) => (
@@ -161,7 +216,7 @@ const TeamMembersPageBlock: React.FC<TeamMembersPageBlockProps> = ({ team }) =>
161216 return (
162217 < PageBlock title = { 'People' } >
163218 { isEditingHead ? < EditingHeadView /> : < NonEditingHeadView /> }
164- < NonEditingLeadsView />
219+ { isEditingLeads ? < EditingLeadsView /> : < NonEditingLeadsView /> }
165220 { isEditingMembers ? < EditingMembersView /> : < NonEditingMembersView /> }
166221 </ PageBlock >
167222 ) ;
0 commit comments