Skip to content

Commit

Permalink
Add chat screen along with components
Browse files Browse the repository at this point in the history
  • Loading branch information
beingnoble03 committed Oct 9, 2023
1 parent f6e3562 commit 326e631
Show file tree
Hide file tree
Showing 14 changed files with 487 additions and 0 deletions.
9 changes: 9 additions & 0 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -611,5 +611,14 @@
"taskNotCompleted": "The task has not been completed yet",
"event": "Event",
"organization": "Organization"
},
"userChat": {
"chat": "Chat",
"search": "Search",
"contacts": "Contacts"
},
"userChatRoom": {
"selectContact": "Select a contact to start conversation",
"sendMessage": "Send Message"
}
}
9 changes: 9 additions & 0 deletions public/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -604,5 +604,14 @@
"taskNotCompleted": "La tâche n'est pas encore terminée",
"event": "Événement",
"organization": "Organisation"
},
"userChat": {
"chat": "Chat",
"search": "Recherche",
"contacts": "Contacts"
},
"userChatRoom": {
"selectContact": "Sélectionnez un contact pour démarrer la conversation",
"sendMessage": "Envoyer le message"
}
}
9 changes: 9 additions & 0 deletions public/locales/hi.json
Original file line number Diff line number Diff line change
Expand Up @@ -605,5 +605,14 @@
"taskNotCompleted": "कार्य अभी तक पूरा नहीं हुआ है",
"event": "आयोजन",
"organization": "संगठन"
},
"userChat": {
"chat": "बात",
"search": "खोज",
"contacts": "संपर्क"
},
"userChatRoom": {
"selectContact": "बातचीत शुरू करने के लिए एक संपर्क चुनें",
"sendMessage": "मेसेज भेजें"
}
}
9 changes: 9 additions & 0 deletions public/locales/sp.json
Original file line number Diff line number Diff line change
Expand Up @@ -605,5 +605,14 @@
"taskNotCompleted": "La tarea aún no se ha completado",
"event": "Evento",
"organization": "Organización"
},
"userChat": {
"chat": "Charlar",
"search": "Buscar",
"contacts": "Contactos"
},
"userChatRoom": {
"selectContact": "Seleccione un contacto para iniciar una conversación",
"sendMessage": "Enviar mensaje"
}
}
9 changes: 9 additions & 0 deletions public/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -605,5 +605,14 @@
"taskNotCompleted": "任務還沒完成",
"event": "事件",
"organization": "組織"
},
"userChat": {
"chat": "聊天",
"search": "搜尋",
"contacts": "聯絡方式"
},
"userChatRoom": {
"selectContact": "選擇聯絡人開始對話",
"sendMessage": "傳訊息"
}
}
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import Settings from 'screens/UserPortal/Settings/Settings';
import Donate from 'screens/UserPortal/Donate/Donate';
import Events from 'screens/UserPortal/Events/Events';
import Tasks from 'screens/UserPortal/Tasks/Tasks';
import Chat from 'screens/UserPortal/Chat/Chat';

function app(): JSX.Element {
/*const { updatePluginLinks, updateInstalled } = bindActionCreators(
Expand Down Expand Up @@ -127,6 +128,7 @@ function app(): JSX.Element {
<SecuredRouteForUser path="/user/donate" component={Donate} />
<SecuredRouteForUser path="/user/events" component={Events} />
<SecuredRouteForUser path="/user/tasks" component={Tasks} />
<SecuredRouteForUser path="/user/chat" component={Chat} />

<Route exact path="*" component={PageNotFound} />
</Switch>
Expand Down
10 changes: 10 additions & 0 deletions src/GraphQl/Mutations/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,3 +622,13 @@ export const UNLIKE_COMMENT = gql`
}
}
`;

export const CREATE_DIRECT_CHAT = gql`
mutation createDirectChat($userIds: [ID!]!, $organizationId: ID!) {
createDirectChat(
data: { userIds: $userIds, organizationId: $organizationId }
) {
_id
}
}
`;
42 changes: 42 additions & 0 deletions src/GraphQl/Queries/Queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,3 +699,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
}
}
}
`;
13 changes: 13 additions & 0 deletions src/components/UserPortal/ChatRoom/ChatRoom.module.css
Original file line number Diff line number Diff line change
@@ -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;
}
81 changes: 81 additions & 0 deletions src/components/UserPortal/ChatRoom/ChatRoom.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLInputElement>): void => {
const newMessageValue = e.target.value;

setNewMessage(newMessageValue);
};

return (
<div className={`d-flex flex-column ${styles.chatAreaContainer}`}>
{!props.selectedContact ? (
<div
className={`d-flex flex-column justify-content-center align-items-center w-100 h-75 gap-2 ${styles.grey}`}
>
<PermContactCalendarIcon fontSize="medium" className={styles.grey} />
<h6>{t('selectContact')}</h6>
</div>
) : (
<>
<div className={`d-flex flex-grow-1 flex-column`}>
<Paper
variant="outlined"
sx={{
p: 2,
backgroundColor: 'white',
borderRadius: '20px 20px 5px 20px',
marginBottom: `10px`,
}}
>
My message
</Paper>
<Paper
variant="outlined"
sx={{
p: 2,
backgroundColor: '#31bb6b',
borderRadius: '20px 20px 20px 5px',
color: 'white',
marginBottom: `10px`,
}}
>
Other message
</Paper>
</div>
<div>
<InputGroup>
<Form.Control
placeholder={t('sendMessage')}
aria-label="Send Message"
value={newMessage}
onChange={handleNewMessageChange}
className={styles.backgroundWhite}
/>
<Button variant="primary" id="button-addon2">
<SendIcon fontSize="small" />
</Button>
</InputGroup>
</div>
</>
)}
</div>
);
}
33 changes: 33 additions & 0 deletions src/components/UserPortal/ContactCard/ContactCard.module.css
Original file line number Diff line number Diff line change
@@ -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;
}
52 changes: 52 additions & 0 deletions src/components/UserPortal/ContactCard/ContactCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
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<React.SetStateAction<string>>;
setSelectedContactName: React.Dispatch<React.SetStateAction<string>>;
}

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 (
<>
<div
className={`${styles.contact} ${
isSelected ? styles.bgGrey : styles.bgWhite
}`}
onClick={handleSelectedContactChange}
>
<img src={imageUrl} alt={contactName} className={styles.contactImage} />
<div className={styles.contactNameContainer}>
<b>{contactName}</b>
<small className={styles.grey}>{props.email}</small>
</div>
</div>
</>
);
}

export default contactCard;
63 changes: 63 additions & 0 deletions src/screens/UserPortal/Chat/Chat.module.css
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit 326e631

Please sign in to comment.