diff --git a/package.json b/package.json
index 748cf32d41..cc1e769e3a 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,8 @@
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.8.3",
"@mui/material": "^5.14.1",
+ "@mui/private-theming": "^5.14.13",
+ "@mui/system": "^5.14.12",
"@mui/x-charts": "^6.0.0-alpha.13",
"@mui/x-data-grid": "^6.8.0",
"@mui/x-date-pickers": "^6.6.0",
diff --git a/public/locales/en.json b/public/locales/en.json
index eac995857e..ba7670d2a7 100644
--- a/public/locales/en.json
+++ b/public/locales/en.json
@@ -631,5 +631,15 @@
"EXlink": "Ex. http://yourwebsite.com/photo",
"register": "Create Advertisement",
"close": "Close "
+ },
+ "userChat": {
+ "chat": "Chat",
+ "search": "Search",
+ "contacts": "Contacts"
+ },
+ "userChatRoom": {
+ "selectContact": "Select a contact to start conversation",
+ "sendMessage": "Send Message"
+
}
}
diff --git a/public/locales/fr.json b/public/locales/fr.json
index e27461dceb..60756082f7 100644
--- a/public/locales/fr.json
+++ b/public/locales/fr.json
@@ -612,5 +612,14 @@
"archievedAds": "Campagnes terminées",
"pMessage": "Aucune publicité n'est présente pour cette campagne.",
"delete": "Supprimer"
+ },
+ "userChat": {
+ "chat": "Chat",
+ "search": "Recherche",
+ "contacts": "Contacts"
+ },
+ "userChatRoom": {
+ "selectContact": "Sélectionnez un contact pour démarrer la conversation",
+ "sendMessage": "Envoyer le message"
}
}
diff --git a/public/locales/hi.json b/public/locales/hi.json
index 4f4b0a8a99..63037b86f8 100644
--- a/public/locales/hi.json
+++ b/public/locales/hi.json
@@ -613,5 +613,14 @@
"archievedAds": "संपन्न अभियान",
"pMessage": "इस अभियान के लिए कोई विज्ञापन नहीं हैं।",
"delete": "हटाएँ"
+ },
+ "userChat": {
+ "chat": "बात",
+ "search": "खोज",
+ "contacts": "संपर्क"
+ },
+ "userChatRoom": {
+ "selectContact": "बातचीत शुरू करने के लिए एक संपर्क चुनें",
+ "sendMessage": "मेसेज भेजें"
}
}
diff --git a/public/locales/sp.json b/public/locales/sp.json
index 2b4c4093f0..04a932094a 100644
--- a/public/locales/sp.json
+++ b/public/locales/sp.json
@@ -613,5 +613,14 @@
"archievedAds": "Campañas completadas",
"pMessage": "No hay anuncios disponibles para esta campaña.",
"delete": "Eliminar"
+ },
+ "userChat": {
+ "chat": "Charlar",
+ "search": "Buscar",
+ "contacts": "Contactos"
+ },
+ "userChatRoom": {
+ "selectContact": "Seleccione un contacto para iniciar una conversación",
+ "sendMessage": "Enviar mensaje"
}
}
diff --git a/public/locales/zh.json b/public/locales/zh.json
index bf461a1956..5506b5a7bf 100644
--- a/public/locales/zh.json
+++ b/public/locales/zh.json
@@ -613,5 +613,13 @@
"archievedAds": "已完成的广告活动",
"pMessage": "此广告活动没有相关广告。",
"delete": "删除"
+ },
+ "chat": "聊天",
+ "search": "搜尋",
+ "contacts": "聯絡方式"
+ },
+ "userChatRoom": {
+ "selectContact": "選擇聯絡人開始對話",
+ "sendMessage": "傳訊息"
}
}
diff --git a/src/App.tsx b/src/App.tsx
index 4752f65982..1c69256c32 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -33,6 +33,7 @@ import Donate from 'screens/UserPortal/Donate/Donate';
import Events from 'screens/UserPortal/Events/Events';
import Tasks from 'screens/UserPortal/Tasks/Tasks';
import Advertisements from 'components/Advertisements/Advertisements';
+import Chat from 'screens/UserPortal/Chat/Chat';
function app(): JSX.Element {
/*const { updatePluginLinks, updateInstalled } = bindActionCreators(
@@ -129,6 +130,7 @@ function app(): JSX.Element {
+
diff --git a/src/GraphQl/Mutations/mutations.ts b/src/GraphQl/Mutations/mutations.ts
index 6421736071..32ffddc9d5 100644
--- a/src/GraphQl/Mutations/mutations.ts
+++ b/src/GraphQl/Mutations/mutations.ts
@@ -643,6 +643,17 @@ export const UNLIKE_COMMENT = gql`
}
}
`;
+
+export const CREATE_DIRECT_CHAT = gql`
+ mutation createDirectChat($userIds: [ID!]!, $organizationId: ID!) {
+ createDirectChat(
+ data: { userIds: $userIds, organizationId: $organizationId }
+ ) {
+ _id
+ }
+ }
+`;
+
//Plugin WebSocket listner
export const PLUGIN_SUBSCRIPTION = gql`
subscription onPluginUpdate {
diff --git a/src/GraphQl/Queries/Queries.ts b/src/GraphQl/Queries/Queries.ts
index 5469f45b0f..d758b6c6be 100644
--- a/src/GraphQl/Queries/Queries.ts
+++ b/src/GraphQl/Queries/Queries.ts
@@ -726,3 +726,45 @@ export const USER_TASKS_LIST = gql`
}
}
`;
+
+export const DIRECT_CHATS_LIST = gql`
+ query DirectChatsByUserID($id: ID!) {
+ directChatsByUserID(id: $id) {
+ _id
+ creator {
+ _id
+ firstName
+ lastName
+ email
+ }
+ messages {
+ _id
+ createdAt
+ messageContent
+ receiver {
+ _id
+ firstName
+ lastName
+ email
+ }
+ sender {
+ _id
+ firstName
+ lastName
+ email
+ }
+ }
+ organization {
+ _id
+ name
+ }
+ users {
+ _id
+ firstName
+ lastName
+ email
+ image
+ }
+ }
+ }
+`;
diff --git a/src/components/EventStats/Statistics/AverageRating.test.tsx b/src/components/EventStats/Statistics/AverageRating.test.tsx
index 79328965f6..53f0acacba 100644
--- a/src/components/EventStats/Statistics/AverageRating.test.tsx
+++ b/src/components/EventStats/Statistics/AverageRating.test.tsx
@@ -52,7 +52,7 @@ describe('Testing Average Rating Card', () => {
);
await waitFor(() =>
- expect(queryByText('Rated 5.00 / 10')).toBeInTheDocument()
+ expect(queryByText('Rated 5.00 / 5')).toBeInTheDocument()
);
});
});
diff --git a/src/components/EventStats/Statistics/AverageRating.tsx b/src/components/EventStats/Statistics/AverageRating.tsx
index dac7b208df..a3769934d8 100644
--- a/src/components/EventStats/Statistics/AverageRating.tsx
+++ b/src/components/EventStats/Statistics/AverageRating.tsx
@@ -10,7 +10,7 @@ type ModalPropType = {
data: {
event: {
_id: string;
- averageFeedbackScore: number | null;
+ averageFeedbackScore: number;
feedback: FeedbackType[];
};
};
@@ -41,12 +41,12 @@ export const AverageRating = ({ data }: ModalPropType): JSX.Element => {
Average Review Score
- Rated {(data.event.averageFeedbackScore || 0).toFixed(2)} / 10
+ Rated {data.event.averageFeedbackScore.toFixed(2)} / 5
}
diff --git a/src/components/EventStats/Statistics/Feedback.tsx b/src/components/EventStats/Statistics/Feedback.tsx
index 6a78e29884..ff4fe7a647 100644
--- a/src/components/EventStats/Statistics/Feedback.tsx
+++ b/src/components/EventStats/Statistics/Feedback.tsx
@@ -25,15 +25,10 @@ type FeedbackType = {
export const FeedbackStats = ({ data }: ModalPropType): JSX.Element => {
const ratingColors = [
'#57bb8a', // Green
- '#73b87e',
'#94bd77',
- '#b0be6e',
'#d4c86a',
- '#f5ce62',
'#e9b861',
- '#ecac67',
'#e79a69',
- '#e2886c',
'#dd776e', // Red
];
@@ -45,13 +40,13 @@ export const FeedbackStats = ({ data }: ModalPropType): JSX.Element => {
});
const chartData = [];
- for (let rating = 0; rating <= 10; rating++) {
+ for (let rating = 0; rating <= 5; rating++) {
if (rating in count)
chartData.push({
id: rating,
value: count[rating],
label: `${rating} (${count[rating]})`,
- color: ratingColors[10 - rating],
+ color: ratingColors[5 - rating],
});
}
diff --git a/src/components/EventStats/Statistics/Review.tsx b/src/components/EventStats/Statistics/Review.tsx
index 0528de79d3..b5aecd61de 100644
--- a/src/components/EventStats/Statistics/Review.tsx
+++ b/src/components/EventStats/Statistics/Review.tsx
@@ -42,7 +42,7 @@ export const ReviewStats = ({ data }: ModalPropType): JSX.Element => {
reviews.map((review) => (
diff --git a/src/components/UserPortal/ChatRoom/ChatRoom.module.css b/src/components/UserPortal/ChatRoom/ChatRoom.module.css
new file mode 100644
index 0000000000..592004d523
--- /dev/null
+++ b/src/components/UserPortal/ChatRoom/ChatRoom.module.css
@@ -0,0 +1,13 @@
+.chatAreaContainer {
+ padding: 10px;
+ flex-grow: 1;
+ background-color: rgba(196, 255, 211, 0.3);
+}
+
+.backgroundWhite {
+ background-color: white;
+}
+
+.grey {
+ color: grey;
+}
diff --git a/src/components/UserPortal/ChatRoom/ChatRoom.tsx b/src/components/UserPortal/ChatRoom/ChatRoom.tsx
new file mode 100644
index 0000000000..c7ada20a13
--- /dev/null
+++ b/src/components/UserPortal/ChatRoom/ChatRoom.tsx
@@ -0,0 +1,81 @@
+import React from 'react';
+import type { ChangeEvent } from 'react';
+import { Paper } from '@mui/material';
+import SendIcon from '@mui/icons-material/Send';
+import { Button, Form, InputGroup } from 'react-bootstrap';
+import styles from './ChatRoom.module.css';
+import PermContactCalendarIcon from '@mui/icons-material/PermContactCalendar';
+import { useTranslation } from 'react-i18next';
+
+interface InterfaceChatRoomProps {
+ selectedContact: string;
+}
+
+export default function chatRoom(props: InterfaceChatRoomProps): JSX.Element {
+ const { t } = useTranslation('translation', {
+ keyPrefix: 'userChatRoom',
+ });
+
+ const [newMessage, setNewMessage] = React.useState('');
+
+ const handleNewMessageChange = (e: ChangeEvent): void => {
+ const newMessageValue = e.target.value;
+
+ setNewMessage(newMessageValue);
+ };
+
+ return (
+
+ {!props.selectedContact ? (
+
+
+
{t('selectContact')}
+
+ ) : (
+ <>
+
+
+ My message
+
+
+ Other message
+
+
+
+
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/src/components/UserPortal/ContactCard/ContactCard.module.css b/src/components/UserPortal/ContactCard/ContactCard.module.css
new file mode 100644
index 0000000000..d722a3a302
--- /dev/null
+++ b/src/components/UserPortal/ContactCard/ContactCard.module.css
@@ -0,0 +1,33 @@
+.contact {
+ display: flex;
+ flex-direction: row;
+ padding: 10px 10px;
+ cursor: pointer;
+ border-radius: 10px;
+ margin-bottom: 10px;
+ border: 2px solid #f5f5f5;
+}
+
+.contactImage {
+ width: 50px;
+ height: auto;
+ border-radius: 10px;
+}
+
+.contactNameContainer {
+ display: flex;
+ flex-direction: column;
+ padding: 0px 10px;
+}
+
+.grey {
+ color: grey;
+}
+
+.bgGrey {
+ background-color: #f5f5f5;
+}
+
+.bgWhite {
+ background-color: white;
+}
diff --git a/src/components/UserPortal/ContactCard/ContactCard.test.tsx b/src/components/UserPortal/ContactCard/ContactCard.test.tsx
new file mode 100644
index 0000000000..cb7aaec882
--- /dev/null
+++ b/src/components/UserPortal/ContactCard/ContactCard.test.tsx
@@ -0,0 +1,116 @@
+import React from 'react';
+import { act, render, screen } from '@testing-library/react';
+import { MockedProvider } from '@apollo/react-testing';
+import { I18nextProvider } from 'react-i18next';
+
+import { BrowserRouter } from 'react-router-dom';
+import { Provider } from 'react-redux';
+import { store } from 'state/store';
+import i18nForTest from 'utils/i18nForTest';
+import { StaticMockLink } from 'utils/StaticMockLink';
+import ContactCard from './ContactCard';
+import userEvent from '@testing-library/user-event';
+
+const link = new StaticMockLink([], true);
+
+async function wait(ms = 100): Promise {
+ await act(() => {
+ return new Promise((resolve) => {
+ setTimeout(resolve, ms);
+ });
+ });
+}
+
+let props = {
+ id: '1',
+ firstName: 'Noble',
+ lastName: 'Mittal',
+ email: 'noble@mittal.com',
+ image: '',
+ selectedContact: '',
+ setSelectedContact: jest.fn(),
+ setSelectedContactName: jest.fn(),
+};
+
+describe('Testing ContactCard Component [User Portal]', () => {
+ test('Component should be rendered properly if person image is undefined', async () => {
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+ });
+
+ test('Component should be rendered properly if person image is not undefined', async () => {
+ props = {
+ ...props,
+ image: 'personImage',
+ };
+
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+ });
+
+ test('Contact gets selectected when component is clicked', async () => {
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+
+ userEvent.click(screen.getByTestId('contactContainer'));
+
+ await wait();
+ });
+
+ test('Component is rendered with background color grey if the contact is selected', async () => {
+ props = {
+ ...props,
+ selectedContact: '1',
+ };
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+
+ userEvent.click(screen.getByTestId('contactContainer'));
+
+ await wait();
+ });
+});
diff --git a/src/components/UserPortal/ContactCard/ContactCard.tsx b/src/components/UserPortal/ContactCard/ContactCard.tsx
new file mode 100644
index 0000000000..8dd5352b43
--- /dev/null
+++ b/src/components/UserPortal/ContactCard/ContactCard.tsx
@@ -0,0 +1,53 @@
+import React from 'react';
+import styles from './ContactCard.module.css';
+
+interface InterfaceContactCardProps {
+ id: string;
+ firstName: string;
+ lastName: string;
+ email: string;
+ image: string;
+ selectedContact: string;
+ setSelectedContact: React.Dispatch>;
+ setSelectedContactName: React.Dispatch>;
+}
+
+function contactCard(props: InterfaceContactCardProps): JSX.Element {
+ const contactName = `${props.firstName} ${props.lastName}`;
+ const imageUrl = props.image
+ ? props.image
+ : `https://api.dicebear.com/5.x/initials/svg?seed=${contactName}`;
+
+ const handleSelectedContactChange = (): void => {
+ props.setSelectedContact(props.id);
+ props.setSelectedContactName(contactName);
+ };
+
+ const [isSelected, setIsSelected] = React.useState(
+ props.selectedContact === props.id
+ );
+
+ React.useEffect(() => {
+ setIsSelected(props.selectedContact === props.id);
+ }, [props.selectedContact]);
+
+ return (
+ <>
+
+
+
+ {contactName}
+ {props.email}
+
+
+ >
+ );
+}
+
+export default contactCard;
diff --git a/src/screens/UserPortal/Chat/Chat.module.css b/src/screens/UserPortal/Chat/Chat.module.css
new file mode 100644
index 0000000000..40add650f4
--- /dev/null
+++ b/src/screens/UserPortal/Chat/Chat.module.css
@@ -0,0 +1,63 @@
+.containerHeight {
+ height: calc(100vh - 66px);
+}
+
+.mainContainer {
+ width: 50%;
+ flex-grow: 3;
+ padding: 20px;
+ max-height: 100%;
+ overflow: auto;
+ display: flex;
+ flex-direction: row;
+}
+
+.chatContainer {
+ flex-grow: 4;
+ display: flex;
+ flex-direction: column;
+ background-color: white;
+ border-top-right-radius: 10px;
+ border-bottom-right-radius: 10px;
+}
+
+.contactContainer {
+ flex-grow: 1;
+ display: flex;
+ flex-direction: column;
+ background-color: white;
+ border-top-left-radius: 10px;
+ border-bottom-left-radius: 10px;
+}
+
+.colorLight {
+ background-color: #f5f5f5;
+}
+
+.addChatContainer {
+ gap: 5px;
+ padding: 10px;
+}
+
+.contactListContainer {
+ flex-grow: 1;
+ padding: 15px 10px;
+}
+
+.chatHeadingContainer {
+ padding: 10px;
+ color: white;
+ border-radius: 0px 10px 0px 0px;
+}
+
+.borderNone {
+ border: none;
+}
+
+.colorWhite {
+ color: white;
+}
+
+.colorPrimary {
+ background: #31bb6b;
+}
diff --git a/src/screens/UserPortal/Chat/Chat.test.tsx b/src/screens/UserPortal/Chat/Chat.test.tsx
new file mode 100644
index 0000000000..6476e9ee40
--- /dev/null
+++ b/src/screens/UserPortal/Chat/Chat.test.tsx
@@ -0,0 +1,173 @@
+import React from 'react';
+import { act, render, screen } from '@testing-library/react';
+import { MockedProvider } from '@apollo/react-testing';
+import { I18nextProvider } from 'react-i18next';
+
+import { ORGANIZATIONS_MEMBER_CONNECTION_LIST } from 'GraphQl/Queries/Queries';
+import { BrowserRouter } from 'react-router-dom';
+import { Provider } from 'react-redux';
+import { store } from 'state/store';
+import i18nForTest from 'utils/i18nForTest';
+import { StaticMockLink } from 'utils/StaticMockLink';
+import Chat from './Chat';
+import * as getOrganizationId from 'utils/getOrganizationId';
+import userEvent from '@testing-library/user-event';
+
+const MOCKS = [
+ {
+ request: {
+ query: ORGANIZATIONS_MEMBER_CONNECTION_LIST,
+ variables: {
+ orgId: '',
+ firstName_contains: '',
+ },
+ },
+ result: {
+ data: {
+ organizationsMemberConnection: {
+ edges: [
+ {
+ _id: '64001660a711c62d5b4076a2',
+ firstName: 'Noble',
+ lastName: 'Mittal',
+ image: null,
+ email: 'noble1@gmail.com',
+ createdAt: '2023-03-02T03:22:08.101Z',
+ },
+ {
+ _id: '64001660a711c62d5b4076a3',
+ firstName: 'Noble',
+ lastName: 'Mittal',
+ image: 'mockImage',
+ email: 'noble@gmail.com',
+ createdAt: '2023-03-02T03:22:08.101Z',
+ },
+ ],
+ },
+ },
+ },
+ },
+ {
+ request: {
+ query: ORGANIZATIONS_MEMBER_CONNECTION_LIST,
+ variables: {
+ orgId: '',
+ firstName_contains: 'j',
+ },
+ },
+ result: {
+ data: {
+ organizationsMemberConnection: {
+ edges: [
+ {
+ _id: '64001660a711c62d5b4076a2',
+ firstName: 'John',
+ lastName: 'Cena',
+ image: null,
+ email: 'john@gmail.com',
+ createdAt: '2023-03-02T03:22:08.101Z',
+ },
+ ],
+ },
+ },
+ },
+ },
+];
+
+const link = new StaticMockLink(MOCKS, true);
+
+async function wait(ms = 100): Promise {
+ await act(() => {
+ return new Promise((resolve) => {
+ setTimeout(resolve, ms);
+ });
+ });
+}
+
+describe('Testing People Screen [User Portal]', () => {
+ jest.mock('utils/getOrganizationId');
+
+ Object.defineProperty(window, 'matchMedia', {
+ writable: true,
+ value: jest.fn().mockImplementation((query) => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: jest.fn(), // Deprecated
+ removeListener: jest.fn(), // Deprecated
+ addEventListener: jest.fn(),
+ removeEventListener: jest.fn(),
+ dispatchEvent: jest.fn(),
+ })),
+ });
+
+ const getOrganizationIdSpy = jest
+ .spyOn(getOrganizationId, 'default')
+ .mockImplementation(() => {
+ return '';
+ });
+
+ test('Screen should be rendered properly', async () => {
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+
+ expect(getOrganizationIdSpy).toHaveBeenCalled();
+ expect(screen.queryAllByText('Noble Mittal')).not.toBe([]);
+ });
+
+ test('User is able to select a contact', async () => {
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+
+ userEvent.click(screen.getByText('noble1@gmail.com'));
+ await wait();
+
+ expect(getOrganizationIdSpy).toHaveBeenCalled();
+ expect(screen.queryAllByText('Noble Mittal')).not.toBe([]);
+ });
+
+ test('Search functionality works as expected', async () => {
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ await wait();
+
+ userEvent.type(screen.getByTestId('searchInput'), 'j');
+ await wait();
+
+ expect(getOrganizationIdSpy).toHaveBeenCalled();
+ expect(screen.queryByText('John Cena')).toBeInTheDocument();
+ expect(screen.queryByText('Noble Mittal')).not.toBeInTheDocument();
+ });
+});
diff --git a/src/screens/UserPortal/Chat/Chat.tsx b/src/screens/UserPortal/Chat/Chat.tsx
new file mode 100644
index 0000000000..1ae9d5764d
--- /dev/null
+++ b/src/screens/UserPortal/Chat/Chat.tsx
@@ -0,0 +1,142 @@
+import React from 'react';
+import OrganizationNavbar from 'components/UserPortal/OrganizationNavbar/OrganizationNavbar';
+import UserSidebar from 'components/UserPortal/UserSidebar/UserSidebar';
+import { ORGANIZATIONS_MEMBER_CONNECTION_LIST } from 'GraphQl/Queries/Queries';
+import { useQuery } from '@apollo/client';
+import styles from './Chat.module.css';
+import getOrganizationId from 'utils/getOrganizationId';
+import { useTranslation } from 'react-i18next';
+import { Form, InputGroup } from 'react-bootstrap';
+import { SearchOutlined } from '@mui/icons-material';
+import HourglassBottomIcon from '@mui/icons-material/HourglassBottom';
+import ContactCard from 'components/UserPortal/ContactCard/ContactCard';
+import ChatRoom from 'components/UserPortal/ChatRoom/ChatRoom';
+
+interface InterfaceContactCardProps {
+ id: string;
+ firstName: string;
+ lastName: string;
+ email: string;
+ image: string;
+ selectedContact: string;
+ setSelectedContact: React.Dispatch>;
+ setSelectedContactName: React.Dispatch>;
+}
+
+interface InterfaceChatRoomProps {
+ selectedContact: string;
+}
+
+export default function chat(): JSX.Element {
+ const { t } = useTranslation('translation', {
+ keyPrefix: 'userChat',
+ });
+ const organizationId = getOrganizationId(location.href);
+
+ const [selectedContact, setSelectedContact] = React.useState('');
+ const [selectedContactName, setSelectedContactName] = React.useState('');
+ const [contacts, setContacts] = React.useState([]);
+ const [filterName, setFilterName] = React.useState('');
+
+ const navbarProps = {
+ currentPage: 'chat',
+ };
+
+ const chatRoomProps: InterfaceChatRoomProps = {
+ selectedContact,
+ };
+
+ const {
+ data: contactData,
+ loading: contactLoading,
+ refetch: contactRefetch,
+ } = useQuery(ORGANIZATIONS_MEMBER_CONNECTION_LIST, {
+ variables: {
+ orgId: organizationId,
+ firstName_contains: filterName,
+ },
+ });
+
+ const handleSearch = (
+ event: React.ChangeEvent
+ ): void => {
+ const newFilter = event.target.value;
+ setFilterName(newFilter);
+
+ const filter = {
+ firstName_contains: newFilter,
+ };
+
+ contactRefetch(filter);
+ };
+
+ React.useEffect(() => {
+ if (contactData) {
+ setContacts(contactData.organizationsMemberConnection.edges);
+ }
+ }, [contactData]);
+
+ return (
+ <>
+
+
+
+
+
+
+
+ {t('contacts')}
+
+
+
+
+
+
+
+
+
+ {contactLoading ? (
+
+ Loading...
+
+ ) : (
+ contacts.map((contact: any, index: number) => {
+ const cardProps: InterfaceContactCardProps = {
+ id: contact._id,
+ firstName: contact.firstName,
+ lastName: contact.lastName,
+ email: contact.email,
+ image: contact.image,
+ setSelectedContactName,
+ selectedContact,
+ setSelectedContact,
+ };
+ return
;
+ })
+ )}
+
+
+
+
+ {selectedContact ? selectedContactName : t('chat')}
+
+
+
+
+
+ >
+ );
+}