Skip to content

Commit 42d07ae

Browse files
authored
Merge pull request #123 from DamyanBG/implement-chat
chat page
2 parents df14051 + cc540a6 commit 42d07ae

File tree

4 files changed

+153
-1
lines changed

4 files changed

+153
-1
lines changed

src/App.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import HomeDetails from './components/Homes/HomeDetails';
1010
import SignInPage from './components/User/SignInPage';
1111
import Rent from './components/Rent/Rent';
1212
import NewsList from './components/News/NewsList';
13+
import Chat from './components/Chat/Chat';
1314
import Profile from './components/User/Profile';
1415
import ChangeEmail from './components/User/ChangeEmail';
1516
import ChangePassword from './components/User/ChangePassword';
@@ -34,6 +35,7 @@ function App() {
3435
<Route path="/edit-home" element={<EditHome />} />
3536
<Route path="/create-land" element={<CreateLand />} />
3637
<Route path="/signup" element={<SignUpPage />} />
38+
<Route path="/chat" element={<Chat />} />
3739
<Route path="/signin" element={<SignInPage />} />
3840
<Route path="/all-homes" element={<AllHomes />} />
3941
<Route path="/all-lands" element={<AllLands />} />

src/components/Chat/Chat.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { useContext, useEffect, useRef, useState } from 'react';
2+
import './Chat.scss';
3+
import { hostUrl } from '../../common/urls';
4+
import { UserContext } from '../../context/UserContext';
5+
6+
export default function Chat() {
7+
const params = new URLSearchParams(window.location.search);
8+
const interlocutorId = params.get('interlocutorId');
9+
const names = params.get('names')
10+
const [message, setMessage] = useState('');
11+
const [messages, setMessages] = useState();
12+
const [chatHistory, setChatHistory] = useState([]);
13+
const { user } = useContext(UserContext);
14+
const ref = useRef()
15+
16+
const getMessages = () => {
17+
fetch(`${hostUrl}/message/${user._id}&${interlocutorId}`)
18+
.then((resp) => resp.json())
19+
.then(setMessages);
20+
};
21+
22+
const sortMessages = () => {
23+
let sorted = Object.entries(messages)
24+
.map((arr) =>
25+
arr[1].map((v) => ({
26+
position: v.sender_id === user._id ? 'right' : 'left',
27+
text: v.text,
28+
id: v._id,
29+
date: v.createdAt,
30+
}))
31+
)
32+
.flat()
33+
.sort((a, b) => new Date(a.date) - new Date(b.date));
34+
setChatHistory(sorted);
35+
};
36+
37+
useEffect(() => {
38+
if (!interlocutorId || !user._id) return;
39+
getMessages();
40+
}, [interlocutorId, user._id]);
41+
42+
useEffect(() => {
43+
if (!messages) return;
44+
sortMessages();
45+
}, [messages]);
46+
47+
const handleOnMessageChange = (e) => {
48+
setMessage(e.target.value);
49+
};
50+
51+
const postMessage = () => {
52+
const postBody = {
53+
sender_id: user._id,
54+
receiver_id: interlocutorId,
55+
text: message,
56+
};
57+
fetch(`${hostUrl}/message`, {
58+
method: 'POST',
59+
body: JSON.stringify(postBody),
60+
headers: {
61+
'Content-Type': 'application/json',
62+
},
63+
})
64+
.then((resp) => resp.json())
65+
.then((json) => {
66+
setChatHistory([...chatHistory, {
67+
id: json._id,
68+
text: json.text,
69+
position: "right"
70+
}])
71+
setMessage('');
72+
ref.current.focus()
73+
});
74+
}
75+
76+
const handleOnMessageSend = () => {
77+
postMessage()
78+
};
79+
80+
const handleOnKeyDown = (e) => {
81+
if (e.key === "Enter") {
82+
postMessage()
83+
}
84+
}
85+
86+
return (
87+
<div className="chat-container">
88+
<h2>Chat with {names}</h2>
89+
<section className="chat-messages">
90+
{chatHistory.map((ch) => (
91+
<p key={ch.id} className={`message-${ch.position}`}>
92+
{ch.text}
93+
</p>
94+
))}
95+
</section>
96+
<input
97+
ref={ref}
98+
className="chat-input"
99+
type="text"
100+
value={message}
101+
onChange={handleOnMessageChange}
102+
onKeyDown={handleOnKeyDown}
103+
/>
104+
<button className="chat-button" onClick={handleOnMessageSend} type="button">
105+
Send
106+
</button>
107+
</div>
108+
);
109+
}

src/components/Chat/Chat.scss

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
.chat-container {
2+
margin: 64px 128px;
3+
border: 1px solid black;
4+
text-align: center;
5+
}
6+
7+
.chat-messages {
8+
display: flex;
9+
margin: 24px;
10+
flex-direction: column;
11+
min-height: 65vh;
12+
p {
13+
min-width: 200px;
14+
border: 1px solid black;
15+
border-radius: 6px;
16+
padding: 6px;
17+
margin-top: 6px;
18+
}
19+
}
20+
21+
.message-left {
22+
align-self: flex-start;
23+
text-align: start;
24+
}
25+
26+
.message-right {
27+
align-self: flex-end;
28+
text-align: end;
29+
}
30+
31+
.chat-input {
32+
width: 95%
33+
34+
}
35+
36+
.chat-button {
37+
width: 5%;
38+
padding: 8px;
39+
border-radius: 6px;
40+
border: 1px solid black;
41+
}

src/components/Homes/HomeDetails.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default function HomeDetails() {
4545
<p>
4646
Owner: {homeDetails.owner_names}{' '}
4747
{user._id !== homeDetails.owner_id && (
48-
<Link to={`/chat?interlocutorId=${homeDetails.owner_id}`}>
48+
<Link to={`/chat?interlocutorId=${homeDetails.owner_id}&names=${homeDetails.owner_names}`}>
4949
<button>Start chat</button>
5050
</Link>
5151
)}

0 commit comments

Comments
 (0)