1- import { FC , useRef , useState } from 'react' ;
1+ import { FC , useRef , useState , useCallback } from 'react' ;
22import {
33 Button ,
44 FlexBox ,
@@ -19,73 +19,83 @@ export interface EditMembersProps {
1919}
2020
2121export const EditMembers : FC < EditMembersProps > = ( {
22- members = [ ] ,
22+ members,
2323 onMemberChanged,
2424 isValidationError = false ,
2525} ) => {
26- const emailInput = useRef < InputDomRef > ( null ) ;
27- const [ valueStateMessage , setValueStateMessage ] = useState < string > ( '' ) ;
28- const [ highlightEmail , setHighlightEmail ] = useState < ValueState > ( 'None ') ;
29- const [ role , setRole ] = useState ( MemberRoles . viewer ) ;
26+ const emailInputRef = useRef < InputDomRef > ( null ) ;
27+ const [ emailState , setEmailState ] = useState < ValueState > ( 'None ' ) ;
28+ const [ emailMessage , setEmailMessage ] = useState ( ' ') ;
29+ const [ selectedRole , setSelectedRole ] = useState ( MemberRoles . viewer ) ;
3030 const { t } = useTranslation ( ) ;
3131
32- const addMember = ( ) => {
33- setValueStateMessage ( '' ) ;
34- setHighlightEmail ( 'None' ) ;
35- if ( ! emailInput . current ) {
32+ const handleAddMember = useCallback ( ( ) => {
33+ setEmailState ( 'None' ) ;
34+ setEmailMessage ( '' ) ;
35+ const input = emailInputRef . current ;
36+ const email = input ?. value . trim ( ) || '' ;
37+ if ( ! email ) {
38+ setEmailState ( 'Negative' ) ;
39+ setEmailMessage ( t ( 'validationErrors.required' ) ) ;
3640 return ;
3741 }
38- // Check if the email is already in the list, highlight as error
39- if ( members . find ( ( m ) => m . name === emailInput . current ! . value ) ) {
40- setValueStateMessage ( t ( 'validationErrors.userExists' ) ) ;
41- setHighlightEmail ( 'Negative' ) ;
42+ if ( members . some ( ( m ) => m . name === email ) ) {
43+ setEmailState ( 'Negative' ) ;
44+ setEmailMessage ( t ( 'validationErrors.userExists' ) ) ;
4245 return ;
4346 }
44-
45- const newMembers = [
47+ onMemberChanged ( [
4648 ...members ,
47- { name : emailInput . current . value , roles : [ role ] , kind : 'User' } ,
48- ] ;
49- onMemberChanged ( newMembers ) ;
50- emailInput . current ! . value = '' ;
51- } ;
52- const removeMember = ( email : string ) => {
53- const newMembers = members . filter ( ( m ) => m . name !== email ) ;
54- onMemberChanged ( newMembers ) ;
55- } ;
49+ { name : email , roles : [ selectedRole ] , kind : 'User' } ,
50+ ] ) ;
51+ if ( input ) input . value = '' ;
52+ } , [ members , onMemberChanged , selectedRole , t ] ) ;
53+
54+ const handleRemoveMember = useCallback (
55+ ( email : string ) => {
56+ onMemberChanged ( members . filter ( ( m ) => m . name !== email ) ) ;
57+ } ,
58+ [ members , onMemberChanged ] ,
59+ ) ;
60+
61+ const handleRoleChange = useCallback ( ( role : MemberRoles ) => {
62+ setSelectedRole ( role ) ;
63+ } , [ ] ) ;
5664
57- const changeSelectedRole = ( role : MemberRoles ) => {
58- setRole ( role ) ;
59- } ;
65+ const handleEmailInputChange = useCallback ( ( ) => {
66+ setEmailState ( 'None' ) ;
67+ setEmailMessage ( '' ) ;
68+ } , [ ] ) ;
6069
6170 return (
62- < >
63- < div >
64- < FlexBox alignItems = { 'End' } gap = { 8 } >
65- < FlexBox direction = { 'Column' } >
66- < Label for = { 'member-email-input' } > Email</ Label >
67- < Input
68- ref = { emailInput }
69- id = "member-email-input"
70- type = "Email"
71- valueState = { highlightEmail }
72- valueStateMessage = { < span > { valueStateMessage } </ span > }
73- onChange = { ( ) => {
74- setHighlightEmail ( 'None' ) ;
75- } }
76- />
77- </ FlexBox >
78- < MemberRoleSelect value = { role } onChange = { changeSelectedRole } />
79- < Button data-testid = "add-member-button" onClick = { ( ) => addMember ( ) } >
80- { t ( 'EditMembers.addButton' ) }
81- </ Button >
71+ < FlexBox direction = "Column" gap = { 8 } >
72+ < FlexBox alignItems = "End" gap = { 8 } >
73+ < FlexBox direction = "Column" >
74+ < Label for = "member-email-input" > { t ( 'common.members' ) } </ Label >
75+ < Input
76+ ref = { emailInputRef }
77+ id = "member-email-input"
78+ type = "Email"
79+ valueState = { emailState }
80+ valueStateMessage = { < span > { emailMessage } </ span > }
81+ data-testid = "member-email-input"
82+ onInput = { handleEmailInputChange }
83+ />
8284 </ FlexBox >
83- < MemberTable
84- members = { members }
85- isValidationError = { isValidationError }
86- onDeleteMember = { removeMember }
87- />
88- </ div >
89- </ >
85+ < MemberRoleSelect value = { selectedRole } onChange = { handleRoleChange } />
86+ < Button
87+ data-testid = "add-member-button"
88+ design = "Emphasized"
89+ onClick = { handleAddMember }
90+ >
91+ { t ( 'EditMembers.addButton' ) }
92+ </ Button >
93+ </ FlexBox >
94+ < MemberTable
95+ members = { members }
96+ isValidationError = { isValidationError }
97+ onDeleteMember = { handleRemoveMember }
98+ />
99+ </ FlexBox >
90100 ) ;
91101} ;
0 commit comments