Skip to content

Commit 88cfc38

Browse files
committed
Add chat management: implement chat slice, integrate chat functionality, and refactor Chat components
1 parent 73eaf03 commit 88cfc38

8 files changed

Lines changed: 143 additions & 35 deletions

File tree

frontend/src/components/chats/ChatItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ interface ChatItemProps {
1616
unread: number;
1717
}
1818

19-
export default function ChatItem({
19+
export default function ChatRooms({
2020
name,
2121
lastMessage,
2222
avatar,

frontend/src/components/chats/ChatList.tsx

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,26 @@
1-
import ChatItem from "./ChatItem";
2-
3-
const chats = [
4-
{
5-
id: 1,
6-
name: "Alice Johnsonn",
7-
lastMessage: "Hey, how are you doing?",
8-
avatar: {
9-
image: "/placeholder.svg?height=40&width=40",
10-
fallbackColorGen: "Alice Johnsonn",
11-
},
12-
timestamp: "5m ago",
13-
unread: 2,
14-
},
15-
{
16-
id: 2,
17-
name: "Bob Smith",
18-
lastMessage: "Did you see the latest post?",
19-
avatar: {
20-
image: "/placeholder.svg?height=40&width=40",
21-
fallbackColorGen: "Bob Smith",
22-
},
23-
timestamp: "1h ago",
24-
unread: 0,
25-
},
26-
];
1+
import { useAppSelector } from "@/statemanagement/store";
2+
import ChatRooms from "./ChatItem";
273

284
export default function ChatList() {
5+
const chats = useAppSelector((state) => {
6+
const chats = state.chats.chats;
7+
return chats.map((chat) => {
8+
return {
9+
id: chat.id,
10+
name: chat.name,
11+
lastMessage: "",
12+
avatar: {
13+
fallbackColorGen: chat.id,
14+
},
15+
timestamp: "",
16+
unread: 0,
17+
};
18+
});
19+
});
2920
return (
3021
<div>
3122
{chats.map((chat) => (
32-
<ChatItem key={chat.id} {...chat} />
23+
<ChatRooms key={chat.id} {...chat} />
3324
))}
3425
</div>
3526
);

frontend/src/components/posts/postlist.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import { getAllPosts } from "@/statemanagement/posting/postSlice";
2-
import { useAppDispatch, useAppSelector } from "@/statemanagement/store";
1+
import { useAppSelector } from "@/statemanagement/store";
32
import { EnhancedPost } from "@/types/enhanced_post.type";
4-
import { useEffect } from "react";
53
import { ContentCard } from "./contentcard";
64

75
export const PostList = () => {
@@ -22,10 +20,6 @@ export const PostList = () => {
2220
});
2321
return enahncedPosts;
2422
});
25-
const dispatch = useAppDispatch();
26-
useEffect(() => {
27-
dispatch(getAllPosts());
28-
}, []);
2923

3024
return (
3125
<>

frontend/src/pages/main.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import { Header } from "@/components/header/header";
22
import { MainPage } from "@/pages/subpages/Main";
3+
import { getAllChats } from "@/statemanagement/chats/chatSlice";
4+
import { getAllPosts } from "@/statemanagement/posting/postSlice";
5+
import { useAppDispatch } from "@/statemanagement/store";
36
import { WebsocketProvider } from "@/websocket/websocketProvider";
7+
import { useEffect } from "react";
48
import { Route, Routes } from "react-router-dom";
59
import { ChatsPage } from "./subpages/Chats";
610

711
export const Main = () => {
12+
const dispatch = useAppDispatch();
13+
useEffect(() => {
14+
dispatch(getAllPosts());
15+
dispatch(getAllChats());
16+
}, []);
817
return (
918
<WebsocketProvider>
1019
<Header />
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { ChatRoom } from "@/types/chatroom.type";
2+
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
3+
export interface ChatState {
4+
chats: ChatRoom[];
5+
chatsLoading: boolean;
6+
messageSending: boolean;
7+
}
8+
9+
const initialState: ChatState = {
10+
chats: [],
11+
chatsLoading: false,
12+
messageSending: false,
13+
};
14+
15+
export const getAllChats = createAsyncThunk("chats/getAll", async () => {
16+
let token = window.sessionStorage.getItem("token");
17+
18+
const response = await fetch(
19+
"https://" + window.envUrl + "/api/v1/chats/query/chats/",
20+
{
21+
headers: {
22+
Authorization: `Bearer ${token}`,
23+
},
24+
}
25+
);
26+
if (response.status > 299) {
27+
throw new Error("Request failed with " + response.status);
28+
}
29+
const data = await response.json();
30+
console.log(data);
31+
return data;
32+
});
33+
34+
export const addMessage = createAsyncThunk(
35+
"chats/add",
36+
async (payload: { text?: string; imageBase64?: string }) => {
37+
/*let token = window.sessionStorage.getItem("token");
38+
const tokenDec = jwtDecode(token!);
39+
const chat = {
40+
id: uuidv4(),
41+
text: payload.text,
42+
image_base64: payload.imageBase64,
43+
user_id: tokenDec.sub,
44+
change_date: new Date().toISOString(),
45+
} as ChatRoom;
46+
const response = await fetch(
47+
"https://" + window.envUrl + "/api/v1/chats/command/chats/",
48+
{
49+
headers: {
50+
Authorization: `Bearer ${token}`,
51+
},
52+
body: JSON.stringify(chat),
53+
method: "Chat",
54+
}
55+
);
56+
if (response.status > 299) {
57+
throw new Error("Request failed with " + response.status);
58+
}
59+
return chat;*/
60+
}
61+
);
62+
63+
export const chatSlice = createSlice({
64+
name: "chats",
65+
initialState,
66+
reducers: {
67+
addChatSync: (state, action) => {
68+
state.chats.unshift(action.payload);
69+
},
70+
},
71+
extraReducers: (builder) => {
72+
builder.addCase(getAllChats.pending, (state) => {
73+
state.chatsLoading = true;
74+
});
75+
builder.addCase(getAllChats.rejected, (state) => {
76+
state.chatsLoading = false;
77+
});
78+
builder.addCase(getAllChats.fulfilled, (state, action) => {
79+
state.chatsLoading = false;
80+
state.chats = action.payload;
81+
});
82+
builder.addCase(addMessage.pending, (state) => {
83+
state.messageSending = true;
84+
});
85+
builder.addCase(addMessage.rejected, (state, err) => {
86+
state.messageSending = false;
87+
console.log(err);
88+
});
89+
builder.addCase(addMessage.fulfilled, (state) => {
90+
state.messageSending = false;
91+
});
92+
},
93+
});
94+
95+
export const { addChatSync } = chatSlice.actions;
96+
97+
export default chatSlice.reducer;

frontend/src/statemanagement/store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { configureStore } from "@reduxjs/toolkit";
22
import { useDispatch, useSelector } from "react-redux";
33
import authenticationReducer from "./authentication/authenticationSlice";
4+
import chatReducer from "./chats/chatSlice";
45
import postReducer from "./posting/postSlice";
56
import usersReducer from "./users/usersSlice";
67

@@ -9,6 +10,7 @@ export const store = configureStore({
910
authentication: authenticationReducer,
1011
users: usersReducer,
1112
posts: postReducer,
13+
chats: chatReducer,
1214
},
1315
});
1416

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface ChatMessage {
2+
id: string;
3+
text: string;
4+
image_base64: string;
5+
user_id: string;
6+
creation_date: string;
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { ChatMessage } from "./chatmessage.type";
2+
3+
export interface ChatRoom {
4+
id: string;
5+
name: string;
6+
messages?: ChatMessage[];
7+
isLoading?: boolean;
8+
}

0 commit comments

Comments
 (0)