Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix users chat #36

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ const App: React.FC = () => {
{location.pathname !== "/chat"
&& location.pathname !== "/login"
&& location.pathname !== "/register" && (
<Link to="/chat">
<div className="fixed bg-primary text-white shadow-md rounded px-3 py-3 z-50 right-6 bottom-6 cursor-pointer group">
<div onClick={() => (window.location.href = "/chat")}>
<div className="fixed bg-[#DB4444] text-white shadow-md rounded px-3 py-3 z-50 right-6 bottom-6 cursor-pointer group">
<IoChatbubbleEllipsesOutline className="text-[30px] text-white" />
</div>
</Link>
</div>
)}
</main>
);
Expand Down
5 changes: 5 additions & 0 deletions src/__test__/addProducts.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ describe("FileUpload component", () => {
new File(["dummy content"], "example.png", { type: "image/png" }),
];

jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useParams: jest.fn(),
}));

beforeEach(() => {
(useDropzone as jest.Mock).mockImplementation(() => ({
getRootProps: jest.fn(() => ({ onClick: () => {} })),
Expand Down
33 changes: 33 additions & 0 deletions src/__test__/productcard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,39 @@ describe("ProductCard Component", () => {
// expect(addToCartButton).toBeDefined();
});

test("renders rating and review count correctly", () => {
render(
<Provider store={store}>
<BrowserRouter>
<ProductCard product={product} />
</BrowserRouter>
</Provider>,
);

const rating = screen.getByTestId("rating");
const reviewCount = screen.getByTestId("review");

expect(rating).toBeDefined();
expect(reviewCount).toBeDefined();
});

test("truncates long product names", () => {
const longNameProduct = {
...product,
name: "This is a very long product name that should be truncated",
};
render(
<Provider store={store}>
<BrowserRouter>
<ProductCard product={longNameProduct} />
</BrowserRouter>
</Provider>,
);

const productName = screen.getByTestId("product-name");
expect(productName.textContent).toHaveLength(15);
});

test("renders wishlist and view details buttons", () => {
render(
<Provider store={store}>
Expand Down
9 changes: 9 additions & 0 deletions src/__test__/userList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ import MockAdapter from "axios-mock-adapter";
import UserList from "../page-sections/UserList";
import chatSlice from "../redux/reducers/chatSlice";
import api from "../redux/api/api";
import { socket } from "../config/socket";

const mockApi = new MockAdapter(api);

jest.mock("../config/socket", () => ({
socket: {
on: jest.fn(),
off: jest.fn(),
},
}));

const mockStore = (initialState) =>
configureStore({
reducer: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/dashboard/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const Header: React.FC<HeaderProps> = ({ toggleSidebar }) => {

return (
<>
<header className="flex lg:w-[80%] lg:ml-[5%] px-8 fixed z-30 top-0 items-center w-full justify-between py-4 bg-white dark:bg-secondary-black">
<header className="flex lg:w-[80%] lg:ml-[5%] px-8 fixed z-30 top-0 items-center w-full justify-between py-4 bg-white">
<div className="relative flex items-center justify-between w-full lg:hidden">
<FiMenu className="w-6 h-6 mr-3 text-black" onClick={toggleSidebar} />
<div className="flex items-center gap-4" />
Expand All @@ -67,7 +67,7 @@ const Header: React.FC<HeaderProps> = ({ toggleSidebar }) => {
<input
type="text"
placeholder="Search..."
className="pl-10 pr-10 py-2 rounded-md dark:border-[0.3px] outline-none bg-[#F7F8FA] focus:outline-none"
className="pl-10 pr-10 py-2 rounded-md border-[0.3px] outline-none bg-[#F7F8FA] focus:outline-none"
/>
</div>
<div className="flex items-center gap-6">
Expand Down
4 changes: 2 additions & 2 deletions src/components/dashboard/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const SideBar: React.FC<SidebarProps> = ({ isOpen }) => {
isOpen ? "translate-x-0" : "-translate-x-full"
} lg:translate-x-0`}
>
<div className="flex flex-col justify-between min-h-screen py-6 dark:bg-secondary-black">
<div className="flex flex-col items-center justify-center">
<div className="flex flex-col justify-between py-6 min-h-screen">
<div className="flex flex-col justify-center items-center">
<Link to="/">
<div className="flex items-center justify-center gap-1 py-2 font-bold text-black">
<span className="font-[550] text-2xl"> eagles</span>
Expand Down
2 changes: 1 addition & 1 deletion src/components/dashboard/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Spinner = () => (
<span className="inline-block dark:text-white">
<span className="inline-block">
<svg
width="20"
height="20"
Expand Down
2 changes: 1 addition & 1 deletion src/components/dashboard/admin/AdminSideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const AdminSideBar: React.FC<SidebarProps> = ({ isOpen }) => {
isOpen ? "translate-x-0" : "-translate-x-full"
} lg:translate-x-0`}
>
<div className="flex flex-col justify-between min-h-screen py-6 dark:bg-secondary-black">
<div className="flex flex-col justify-between min-h-screen py-6">
<div className="flex flex-col items-center justify-center">
<div className="flex items-center justify-center gap-1 py-2 font-bold text-black">
<span className="font-[550] text-2xl">eagles</span>
Expand Down
5 changes: 1 addition & 4 deletions src/components/dashboard/products/ProductsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,7 @@ const ProductsTable: React.FC = () => {
</tr>
) : products.length === 0 ? (
<tr>
<td
colSpan={6}
className="text-center py-10 text-dark-gray dark:text-white"
>
<td colSpan={6} className="text-center py-10 text-dark-gray">
No products found.
</td>
</tr>
Expand Down
16 changes: 14 additions & 2 deletions src/page-sections/UserList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { HiMiniUserGroup } from "react-icons/hi2";
import { useAppDispatch } from "../redux/hooks";
import Spinner from "../components/dashboard/Spinner";
import { fetchChats, fetchUsers } from "../redux/reducers/chatSlice";
import { socket } from "../config/socket";

interface UserListProps {
onUserSelect: (chat: any | null, user: any) => void;
Expand Down Expand Up @@ -38,6 +39,17 @@ const UserList: React.FC<UserListProps> = ({
useEffect(() => {
dispatch(fetchChats());
dispatch(fetchUsers());

const handlePrivateMessage = () => {
dispatch(fetchChats());
dispatch(fetchUsers());
};

socket.on("private message recieved", handlePrivateMessage);

return () => {
socket.off("private message recieved", handlePrivateMessage);
};
}, [dispatch]);

useEffect(() => {
Expand Down Expand Up @@ -114,7 +126,7 @@ const UserList: React.FC<UserListProps> = ({
<input
type="text"
placeholder="Search..."
className="px-10 py-2 rounded-md dark:border-[1px] text-gray-500 w-full outline-none bg-bg-gray dark:bg-transparent dark:border-dark-gray focus:outline-none"
className="px-10 py-2 rounded-md border-[1px] text-gray-500 w-full outline-none bg-bg-gray bg-transparent border-dark-gray focus:outline-none"
value={searchTerm}
onChange={handleSearchChange}
/>
Expand Down Expand Up @@ -193,7 +205,7 @@ const UserList: React.FC<UserListProps> = ({
{chat.messages.length > 0
? chat.messages[
chat.messages.length - 1
].message.substring(0, 20)
].message.substring(0, 15)
: "No messages yet"}
...
</p>
Expand Down
48 changes: 32 additions & 16 deletions src/pages/ChatPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useState, useEffect, useRef } from "react";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import { MdSportsGolf } from "react-icons/md";

import UserList from "../page-sections/UserList";
import ChatWindow from "../page-sections/ChatWindow";
Expand Down Expand Up @@ -31,8 +30,20 @@ const ChatPage: React.FC = () => {
setRefetch(true);
};

const handlePastMessages = (pastMessages: any[]) => {
setPublicMessages(
pastMessages.map((msg) => ({
isOwner: msg.sender === profile?.name,
message: msg.message,
sender: msg.sender,
createdAt: msg.createdAt,
})),
);
};

useEffect(() => {
dispatch(fetchUser());
socket.on("past messages", handlePastMessages);
}, [dispatch]);

useEffect(() => {
Expand All @@ -43,32 +54,31 @@ const ChatPage: React.FC = () => {
}, []);

useEffect(() => {
const handleConnect = () => {
socket.emit("private chats");
};
socket.on("past messages", handlePastMessages);
}, [isPublicChat]);

useEffect(() => {
const handleChatMessage = (msg: any) => {
if (!publicMessageIds.current.has(msg.id)) {
setPublicMessages((prevMessages) => [...prevMessages, msg]);
publicMessageIds.current.add(msg.id);
}
};
socket.on("chat message", handleChatMessage);
socket.on("past messages", handlePastMessages);

const handlePastMessages = (pastMessages: any[]) => {
setPublicMessages(
pastMessages.map((msg) => ({
isOwner: msg.sender === profile?.name,
message: msg.message,
sender: msg.sender,
createdAt: msg.createdAt,
})),
);
return () => {
socket.off("chat message", handleChatMessage);
socket.off("past messages", handlePastMessages);
};
}, [publicMessageIds, selectedChat]);

useEffect(() => {
const handleConnect = () => {
socket.emit("private chats");
};
socket.on("connect", handleConnect);
socket.on("chat message", handleChatMessage);
socket.on("past messages", handlePastMessages);
}, [publicMessages]);
}, [selectedChat]);

useEffect(() => {
const handlePrivateMessage = (message: any) => {
Expand Down Expand Up @@ -191,6 +201,12 @@ const ChatPage: React.FC = () => {
}));

try {
socket.emit("private chat message", {
sender: profile?.username,
userId: profile?.id,
receiverId: newChatUser.id,
message: text,
});
await dispatch(
sendMessage({ message: text, id: newChatUser.id }),
).unwrap();
Expand Down
Loading