import { PlusOutlined } from '@ant-design/icons'; import { Button, Modal, notification, Space, Table, Typography } from 'antd'; import { ColumnsType } from 'antd/lib/table'; import deleteInvite from 'api/user/deleteInvite'; import getPendingInvites from 'api/user/getPendingInvites'; import sendInvite from 'api/user/sendInvite'; import { INVITE_MEMBERS_HASH } from 'constants/app'; import ROUTES from 'constants/routes'; import React, { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useQuery } from 'react-query'; import { useLocation } from 'react-router-dom'; import { useCopyToClipboard } from 'react-use'; import { PayloadProps } from 'types/api/user/getPendingInvites'; import { ROLES } from 'types/roles'; import InviteTeamMembers from '../InviteTeamMembers'; import { TitleWrapper } from './styles'; function PendingInvitesContainer(): JSX.Element { const [ isInviteTeamMemberModalOpen, setIsInviteTeamMemberModalOpen, ] = useState(false); const [isInvitingMembers, setIsInvitingMembers] = useState(false); const { t } = useTranslation(['organizationsettings', 'common']); const [state, setText] = useCopyToClipboard(); const [notifications, NotificationElement] = notification.useNotification(); useEffect(() => { if (state.error) { notifications.error({ message: state.error.message, }); } if (state.value) { notifications.success({ message: t('success', { ns: 'common', }), }); } }, [state.error, state.value, t, notifications]); const getPendingInvitesResponse = useQuery({ queryFn: () => getPendingInvites(), queryKey: 'getPendingInvites', }); const toggleModal = (value: boolean): void => { setIsInviteTeamMemberModalOpen(value); }; const [allMembers, setAllMembers] = useState([ { email: '', name: '', role: 'VIEWER', }, ]); const [dataSource, setDataSource] = useState([]); const { hash } = useLocation(); const getParsedInviteData = useCallback( (payload: PayloadProps = []) => payload?.map((data) => ({ key: data.createdAt, name: data.name, email: data.email, accessLevel: data.role, inviteLink: `${window.location.origin}${ROUTES.SIGN_UP}?token=${data.token}`, })), [], ); useEffect(() => { if (hash === INVITE_MEMBERS_HASH) { toggleModal(true); } }, [hash]); useEffect(() => { if ( getPendingInvitesResponse.status === 'success' && getPendingInvitesResponse?.data?.payload ) { const data = getParsedInviteData( getPendingInvitesResponse?.data?.payload || [], ); setDataSource(data); } }, [ getParsedInviteData, getPendingInvitesResponse?.data?.payload, getPendingInvitesResponse.status, ]); const onRevokeHandler = async (email: string): Promise => { try { const response = await deleteInvite({ email, }); if (response.statusCode === 200) { // remove from the client data const index = dataSource.findIndex((e) => e.email === email); if (index !== -1) { setDataSource([ ...dataSource.slice(0, index), ...dataSource.slice(index + 1, dataSource.length), ]); } notifications.success({ message: t('success', { ns: 'common', }), }); } else { notifications.error({ message: response.error || t('something_went_wrong', { ns: 'common', }), }); } } catch (error) { notifications.error({ message: t('something_went_wrong', { ns: 'common', }), }); } }; const columns: ColumnsType = [ { title: 'Name', dataIndex: 'name', key: 'name', }, { title: 'Emails', dataIndex: 'email', key: 'email', }, { title: 'Access Level', dataIndex: 'accessLevel', key: 'accessLevel', }, { title: 'Invite Link', dataIndex: 'inviteLink', key: 'Invite Link', ellipsis: true, }, { title: 'Action', dataIndex: 'action', key: 'Action', render: (_, record): JSX.Element => ( => onRevokeHandler(record.email)} > Revoke { setText(record.inviteLink); }} > Copy Invite Link ), }, ]; const onInviteClickHandler = async (): Promise => { try { setIsInvitingMembers(true); allMembers.forEach( async (members): Promise => { const { error, statusCode } = await sendInvite({ email: members.email, name: members.name, role: members.role, }); if (statusCode !== 200) { notifications.error({ message: error || t('something_went_wrong', { ns: 'common', }), }); } }, ); setTimeout(async () => { const { data, status } = await getPendingInvitesResponse.refetch(); if (status === 'success' && data.payload) { setDataSource(getParsedInviteData(data?.payload || [])); } setIsInvitingMembers(false); toggleModal(false); }, 2000); } catch (error) { notifications.error({ message: t('something_went_wrong', { ns: 'common', }), }); } }; return (
{NotificationElement} toggleModal(false)} centered destroyOnClose footer={[ , , ]} > {t('pending_invites')} ); } export interface InviteTeamMembersProps { email: string; name: string; role: ROLES; } interface DataProps { key: number; name: string; email: string; accessLevel: ROLES; inviteLink: string; } export default PendingInvitesContainer;