import { useCallback, useMemo, useState } from 'react' import { Button, Col, Form, FormControl, Row } from 'react-bootstrap' import { Trans, useTranslation } from 'react-i18next' import { User } from '../../../../../types/group-management/user' import { deleteJSON, FetchError, postJSON, } from '../../../infrastructure/fetch-json' import Tooltip from '../../../shared/components/tooltip' import useWaitForI18n from '../../../shared/hooks/use-wait-for-i18n' import getMeta from '../../../utils/meta' import { parseEmails } from '../utils/emails' import ErrorAlert, { APIError } from './error-alert' import GroupMemberRow from './group-member-row' import useUserSelection from '../hooks/use-user-selection' export default function GroupMembers() { const { isReady } = useWaitForI18n() const { t } = useTranslation() const { users, setUsers, selectedUsers, selectAllUsers, unselectAllUsers, selectUser, unselectUser, } = useUserSelection(getMeta('ol-users', [])) const [emailString, setEmailString] = useState('') const [inviteUserInflightCount, setInviteUserInflightCount] = useState(0) const [inviteError, setInviteError] = useState() const [removeMemberInflightCount, setRemoveMemberInflightCount] = useState(0) const [removeMemberError, setRemoveMemberError] = useState() const groupId: string = getMeta('ol-groupId') const groupName: string = getMeta('ol-groupName') const groupSize: number = getMeta('ol-groupSize') const paths = useMemo( () => ({ addMember: `/manage/groups/${groupId}/invites`, removeMember: `/manage/groups/${groupId}/user`, removeInvite: `/manage/groups/${groupId}/invites`, exportMembers: `/manage/groups/${groupId}/members/export`, }), [groupId] ) const addMembers = useCallback( e => { e.preventDefault() setInviteError(undefined) const emails = parseEmails(emailString) ;(async () => { for (const email of emails) { setInviteUserInflightCount(count => count + 1) try { const data = await postJSON<{ user: User }>(paths.addMember, { body: { email, }, }) if (data.user) { const alreadyListed = users.find( user => user.email === data.user.email ) if (!alreadyListed) { setUsers(users => [...users, data.user]) } } setEmailString('') } catch (error: unknown) { console.error(error) setInviteError((error as FetchError)?.data?.error || {}) } setInviteUserInflightCount(count => count - 1) } })() }, [emailString, paths.addMember, users, setUsers] ) const removeMembers = useCallback( e => { e.preventDefault() setRemoveMemberError(undefined) ;(async () => { for (const user of selectedUsers) { let url if (paths.removeInvite && user.invite && user._id == null) { url = `${paths.removeInvite}/${encodeURIComponent(user.email)}` } else if (paths.removeMember && user._id) { url = `${paths.removeMember}/${user._id}` } else { return } setRemoveMemberInflightCount(count => count + 1) try { await deleteJSON(url, {}) setUsers(users => users.filter(u => u !== user)) unselectUser(user) } catch (error: unknown) { console.error(error) setRemoveMemberError((error as FetchError)?.data?.error || {}) } setRemoveMemberInflightCount(count => count - 1) } })() }, [ selectedUsers, unselectUser, setUsers, paths.removeInvite, paths.removeMember, ] ) const handleSelectAllClick = useCallback( (e: React.ChangeEvent) => { if (e.target.checked) { selectAllUsers() } else { unselectAllUsers() } }, [selectAllUsers, unselectAllUsers] ) const handleEmailsChange = useCallback( e => { setEmailString(e.target.value) }, [setEmailString] ) if (!isReady) { return null } return (

{groupName || t('group_subscription')}

{selectedUsers.length === 0 && ( , ]} // eslint-disable-line react/jsx-key values={{ addedUsersSize: users.length, groupSize }} /> )} {removeMemberInflightCount > 0 ? ( ) : ( <> {selectedUsers.length > 0 && ( )} )}

{t('members_management')}

  • {t('email')} {t('name')} {t('last_active')} (?) {t('accepted_invite')}
  • {users.length === 0 && (
  • {t('no_members')}
  • )} {users.map((user: any) => ( ))}

{users.length < groupSize && (

{t('add_more_members')}

{inviteUserInflightCount > 0 ? ( ) : ( )} {t('export_csv')} {t('add_comma_separated_emails_help')}
)} {users.length >= groupSize && users.length > 0 && ( <> {t('export_csv')} )}
) }