Skip to content

Commit

Permalink
Merge pull request #9 from Gin-n-Tonicc/FE_Chat
Browse files Browse the repository at this point in the history
Fe chat
  • Loading branch information
stefan-petrov1 committed Apr 21, 2024
2 parents 1f1d2f4 + d63672d commit 217622a
Show file tree
Hide file tree
Showing 37 changed files with 1,263 additions and 26 deletions.
4 changes: 4 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import AdminTableUsers from './pages/admin/admin-tables/AdminTableUsers';
import Login from './pages/auth/login/Login';
import Logout from './pages/auth/logout/Logout';
import Register from './pages/auth/register/Register';
import Chat from './pages/chat/Chat';
import ContactUs from './pages/contact-us/ContactUs';
import EventsCreate from './pages/events-create/EventsCreate';
import EventsDetails from './pages/events-details/EventsDetails';
import Events from './pages/events/Events';
import Home from './pages/home/Home';
import NotFound from './pages/not-found/NotFound';
import Profile from './pages/profile/Profile';
import './scss/styles.scss';
import { PageEnum, RoleEnum } from './types';
import { AdminPageEnum } from './types/enums/AdminPageEnum';
Expand Down Expand Up @@ -54,7 +56,9 @@ function App() {
element={
<ProtectedRoute role={RoleEnum.USER} onlyAuth={true} />
}>
<Route path={PageEnum.Chat} element={<Chat />} />
<Route path={PageEnum.Logout} element={<Logout />} />
<Route path={PageEnum.Profile} element={<Profile />} />
</Route>

{/* Only organisations */}
Expand Down
9 changes: 8 additions & 1 deletion client/src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ function AdminNav() {
function LoggedNav(props: {
isOrganisation: boolean;
hasFinishedOAuth2: boolean;
userId: number;
}) {
return (
<>
<NavItem to={PageEnum.Logout} text="Log out" />
<NavItem to={PageEnum.Profile} text="Profile" img={profileUserIcon} />
<NavItem
to={PageEnum.Profile.replace(':userId', props.userId.toString())}
text="Profile"
img={profileUserIcon}
/>
</>
);
}
Expand All @@ -40,6 +45,7 @@ function UserNav(props: {
isOrganisation: boolean;
hasFinishedOAuth2: boolean;
isAdmin: boolean;
userId: number;
}) {
return (
<>
Expand Down Expand Up @@ -100,6 +106,7 @@ function Navbar() {
isOrganisation={isOrganisation}
hasFinishedOAuth2={hasFinishedOAuth2}
isAdmin={isAdmin}
userId={user.id || -1}
/>
)}
</div>
Expand Down
13 changes: 13 additions & 0 deletions client/src/config/api/friends.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { baseApiUrl } from './base';

const base = `${baseApiUrl}/userFriend`;

export const friendsPaths = Object.seal({
getById: (userId: number) => `${base}/list/${userId}`,
hasSentRequest: (userId: number) => `${base}/has-sent-request/${userId}`,
add: (friendId: number) => `${base}/add/${friendId}`,
requestsById: (userId: number) => `${base}/requests/${userId}`,
confirmRequest: (friendId: number) => `${base}/confirm/${friendId}`,
removeRequest: (friendId: number) => `${base}/remove/${friendId}`,
removeFriendship: (friendId: number) => `${base}/${friendId}`,
});
3 changes: 3 additions & 0 deletions client/src/config/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ export * from './admin';
export * from './auth';
export * from './events';
export * from './files';
export * from './friends';
export * from './messages';
export * from './oAuth';
export * from './skills';
export * from './userEventStatuses';
export * from './users';
8 changes: 8 additions & 0 deletions client/src/config/api/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { baseApiUrl } from './base';

const base = `${baseApiUrl}/messages`;

export const messagesPaths = Object.seal({
get: (userId: number) => `${base}/${userId}`,
send: `${base}/send`,
});
7 changes: 7 additions & 0 deletions client/src/config/api/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { baseApiUrl } from './base';

const base = `${baseApiUrl}/users`;

export const usersPaths = Object.seal({
getById: (userId: number) => `${base}/byId/${userId}`,
});
95 changes: 95 additions & 0 deletions client/src/pages/chat/Chat.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
.custom-chatter .wrapper {
display: flex;
justify-content: center;
align-items: center;
}

.custom-chatter .main {
background-color: #eee;
width: 50vw;
position: relative;
border-radius: 8px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
padding: 6px 0px 0px 0px;
padding: 5rem;
}

.custom-chatter .scroll {
overflow-y: scroll;
scroll-behavior: smooth;
height: 100%;
max-height: 70vh;
}

.custom-chatter .img1 {
border-radius: 50%;
background-color: #66bb6a;
}

.custom-chatter .name {
font-size: 12px;
}

.custom-chatter .msg {
background-color: #fff;
font-size: 15px;
padding: 5px;
border-radius: 5px;
font-weight: 500;
color: #3e3c3c;
}

.custom-chatter .between {
font-size: 8px;
font-weight: 500;
color: #a09e9e;
}

.custom-chatter .navbar {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}

.custom-chatter .form-control {
font-size: 10px;
font-weight: 400;
width: 230px;
height: 30px;
border: none;
}

.custom-chatter .form-control:focus {
box-shadow: none;
overflow: hidden;
border: none;
}

.custom-chatter .form-control:focus {
box-shadow: none !important;
}

.custom-chatter .icon1 {
/* color: #7c4dff !important; */
font-size: 18px !important;
cursor: pointer;
margin: 0 10px;
}

.custom-chatter .icon2 {
/* color: #512da8 !important; */
font-size: 18px !important;
position: relative;
padding: 0px;
padding-right: 0.5rem;
cursor: pointer;
}

.custom-chatter .icondiv {
border-radius: 50%;
width: 15px;
height: 15px;
padding: 2px;
position: relative;
bottom: 1px;
}
123 changes: 123 additions & 0 deletions client/src/pages/chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { useEffect, useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import { useFetch } from 'use-http';
import Spinner from '../../components/spinner/Spinner';
import { messagesPaths, usersPaths } from '../../config/api';
import { useAuthContext } from '../../contexts/AuthContext';
import { IFullUser, IMessage, PageEnum } from '../../types';
import './Chat.css';
import ChatLeftMessage from './chat-left-message/ChatLeftMessage';
import ChatRightMessage from './chat-right-message/ChatRightMessage';

function Chat() {
const { user } = useAuthContext();
const { userId: userIdParam } = useParams();
const [messages, setMessages] = useState<IMessage[]>([]);
const [inputValue, setInputValue] = useState<string>('');

const userId = Number(userIdParam || -1);

const { get, data: messagesFetch } = useFetch<IMessage[]>(
messagesPaths.get(userId),
[]
);

const { data: userFetch, loading } = useFetch<IFullUser>(
usersPaths.getById(userId),
[]
);

const { post, response } = useFetch<IMessage>(messagesPaths.send);

const onMessageSend = async () => {
const body = {
id: 0,
content: inputValue,
sentAt: new Date(Date.now()),
senderId: user.id,
receiverId: userId,
};

const message = await post(body);

if (response.ok) {
setInputValue('');
setMessages((prev) => [...prev, message]);
}
};

useEffect(() => {
if (!messagesFetch) {
return;
}
setMessages(messagesFetch);
}, [messagesFetch]);

useEffect(() => {
const interval = setInterval(async () => {
await get();
}, 1000 * 15);

return () => clearInterval(interval);
}, []);

if (loading) {
return <Spinner />;
}

return (
<div className="d-flex flex-column justify-content-center container mt-5 custom-chatter">
<h2 className="text-center">Chat With</h2>
<Link
to={PageEnum.Profile.replace(
':userId',
userFetch?.id.toString() as string
)}
className="mb-5">
<h5 className="text-primary text-center text-decoration-underline">
{userFetch?.firstname} {userFetch?.lastname}
</h5>
</Link>
<div className="wrapper">
<div className="main">
<div className="px-2 scroll">
{messages.map((x) => {
if (x.senderId.id === user.id) {
return <ChatRightMessage message={x.content} key={x.id} />;
}

const fullName = `${x.senderId.firstname} ${x.senderId.lastname}`;
return (
<ChatLeftMessage
content={x.content}
senderFullName={fullName}
key={x.id}
/>
);
})}
</div>
<nav className="navbar bg-white navbar-expand-sm d-flex justify-content-between">
{' '}
<input
type="text number"
name="text"
className="form-control"
placeholder="Type a message..."
value={inputValue}
onChange={(e) => setInputValue(e.currentTarget.value)}
/>
<div className="icondiv d-flex justify-content-end align-content-center text-center ml-2">
{' '}
<i
className="fa fa-arrow-circle-right icon2 text-primary"
onClick={onMessageSend}
/>{' '}
</div>
</nav>
</div>
</div>
</div>
);
}

export default Chat;
25 changes: 25 additions & 0 deletions client/src/pages/chat/chat-left-message/ChatLeftMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
interface ChatLeftMessageProps {
content: string;
senderFullName: string;
}

function ChatLeftMessage(props: ChatLeftMessageProps) {
return (
<div className="d-flex align-items-center">
<div className="text-left pr-1">
<img
src="https://img.icons8.com/color/40/000000/guest-female.png"
width={30}
className="img1"
/>
</div>
<div className="pr-2 pl-1">
{' '}
<span className="name">{props.senderFullName}</span>
<p className="msg">{props.content}</p>
</div>
</div>
);
}

export default ChatLeftMessage;
24 changes: 24 additions & 0 deletions client/src/pages/chat/chat-right-message/ChatRightMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
interface ChatRightMessageProps {
message: string;
}

function ChatRightMessage({ message }: ChatRightMessageProps) {
return (
<div className="d-flex align-items-center text-right justify-content-end ">
<div className="pr-2">
{' '}
<span className="name">You</span>
<p className="msg">{message}</p>
</div>
<div>
<img
src="https://i.imgur.com/HpF4BFG.jpg"
width={30}
className="img1"
/>
</div>
</div>
);
}

export default ChatRightMessage;
17 changes: 17 additions & 0 deletions client/src/pages/profile/Profile.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border: 0 solid transparent;
border-radius: 0.25rem;
margin-bottom: 1.5rem;
box-shadow: 0 2px 6px 0 rgb(218 218 253 / 65%),
0 2px 6px 0 rgb(206 206 238 / 54%);
}
.me-2 {
margin-right: 0.5rem !important;
}
Loading

0 comments on commit 217622a

Please sign in to comment.