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

add chat route not added to the client side for sending a message to a poster for the first time!! #6

Open
iceticshacker7 opened this issue Jun 28, 2024 · 7 comments

Comments

@iceticshacker7
Copy link

Need to add the apiRequest for addChat on the client side to start a chat with a user if it hasn't been done previously. Then, either initiate a chat or check if a chat already exists, and decide whether to create a new chat or continue with the existing one.

image

Check this image can create a handler to initiate a chat for the first time

@iceticshacker7 iceticshacker7 changed the title add chat not added to the client side for sending a message to a poster for the first time!! add chat route not added to the client side for sending a message to a poster for the first time!! Jun 28, 2024
@aditya-mistri
Copy link

aditya-mistri commented Jul 26, 2024

@iceticshacker7 did you solve this issue
@safak please solve

@iceticshacker7
Copy link
Author

@iceticshacker7 did you solve this issue @safak please solve

kind of solve the issue couldn't develop a good ui for chat

@aditya-mistri
Copy link

@iceticshacker7 did you solve this issue @safak please solve

kind of solve the issue couldn't develop a good ui for chat

can you please share the solution , i could not figure it out

@iceticshacker7
Copy link
Author

iceticshacker7 commented Jul 26, 2024

@iceticshacker7 did you solve this issue @safak please solve

kind of solve the issue couldn't develop a good ui for chat

can you please share the solution , i could not figure it out

yeah sure you will have to paste this code below in SinglePage.jsx it would work but you'll figure it out on your own how it works

import "./singlePage.scss";
import Slider from "../../components/slider/Slider";
import Map from "../../components/map/Map";
import { useNavigate, useLoaderData } from "react-router-dom";
import DOMPurify from "dompurify";
import { useContext, useState, useEffect } from "react";
import { AuthContext } from "../../context/AuthContext";
import { SocketContext } from "../../context/SocketContext";
import apiRequest from "../../lib/apiRequest";
import Chat from "../../components/chat/Chat";
import { useNotificationStore } from "../../lib/notificationStore";

function SinglePage() {
  const post = useLoaderData();
  const [saved, setSaved] = useState(post.isSaved);
  const { currentUser } = useContext(AuthContext);
  const { socket } = useContext(SocketContext);
  const [chat, setChat] = useState(null);
  const navigate = useNavigate();
  const recieverID = post.userId;
  const decrease = useNotificationStore((state) => state.decrease);

  useEffect(() => {
    const fetchChats = async () => {
      try {
        const res = await apiRequest.get("/chats");
        const chats = res.data;
        const existingChat = chats.find(
          (chat) =>
            chat.userIDs.includes(currentUser.id) && chat.userIDs.includes(recieverID)
        );
        if (existingChat) {
          setChat(existingChat);
        } else {
          const res = await apiRequest.post("/chats", {
            userIDs: [currentUser.id, recieverID],
          });
          setChat(res.data);
        }
      } catch (err) {
        console.log(err);
      }
    };
    fetchChats();
  }, [currentUser.id, recieverID]);

  const handleChat = async () => {
    if (!currentUser) {
      navigate("/login");
    } else {
      if (chat) {
        handleOpenChat(chat.id, post.user);
      } else {
        const res = await apiRequest.post("/chats", {
          userIDs: [currentUser.id, recieverID],
        });
        setChat(res.data);
        handleOpenChat(res.data.id, post.user);
      }
    }
  };

  const handleOpenChat = async (id, receiver) => {
    try {
      const res = await apiRequest.get("/chats/" + id);
      if (!res.data.seenBy.includes(currentUser.id)) {
        decrease();
      }
      setChat({ ...res.data, receiver });
    } catch (err) {
      console.log(err);
    }
  };

  const handleSave = async () => {
    if (!currentUser) {
      navigate("/login");
    } else {
      setSaved((prev) => !prev);
      try {
        await apiRequest.post("/users/save", { postId: post.id });
      } catch (err) {
        console.log(err);
        setSaved((prev) => !prev);
      }
    }
  };

  return (
    <div className="singlePage">
      <div className="details">
        <div className="wrapper">
          <Slider images={post.images} />
          <div className="info">
            <div className="top">
              <div className="post">
                <h1>{post.title}</h1>
                <div className="address">
                  <img src="/pin.png" alt="" />
                  <span>{post.address}</span>
                </div>
                <div className="price">$ {post.price}</div>
              </div>
              <div className="user">
                <img src={post.user.avatar} alt="" />
                <span>{post.user.username}</span>
              </div>
            </div>
            <div
              className="bottom"
              dangerouslySetInnerHTML={{
                __html: DOMPurify.sanitize(post.postDetail.desc),
              }}
            ></div>
          </div>
        </div>
      </div>
      <div className="features">
        <div className="wrapper">
          <p className="title">General</p>
          <div className="listVertical">
            <div className="feature">
              <img src="/utility.png" alt="" />
              <div className="featureText">
                <span>Utilities</span>
                {post.postDetail.utilities === "owner" ? (
                  <p>Owner is responsible</p>
                ) : (
                  <p>Tenant is responsible</p>
                )}
              </div>
            </div>
            <div className="feature">
              <img src="/pet.png" alt="" />
              <div className="featureText">
                <span>Pet Policy</span>
                {post.postDetail.pet === "allowed" ? (
                  <p>Pets Allowed</p>
                ) : (
                  <p>Pets not Allowed</p>
                )}
              </div>
            </div>
            <div className="feature">
              <img src="/fee.png" alt="" />
              <div className="featureText">
                <span>Income Policy</span>
                <p>{post.postDetail.income}</p>
              </div>
            </div>
          </div>
          <p className="title">Sizes</p>
          <div className="sizes">
            <div className="size">
              <img src="/size.png" alt="" />
              <span>{post.postDetail.size} sqft</span>
            </div>
            <div className="size">
              <img src="/bed.png" alt="" />
              <span>{post.bedroom} beds</span>
            </div>
            <div className="size">
              <img src="/bath.png" alt="" />
              <span>{post.bathroom} bathroom</span>
            </div>
          </div>
          <p className="title">Nearby Places</p>
          <div className="listHorizontal">
            <div className="feature">
              <img src="/school.png" alt="" />
              <div className="featureText">
                <span>School</span>
                <p>
                  {post.postDetail.school > 999
                    ? post.postDetail.school / 1000 + "km"
                    : post.postDetail.school + "m"}{" "}
                  away
                </p>
              </div>
            </div>
            <div className="feature">
              <img src="/pet.png" alt="" />
              <div className="featureText">
                <span>Bus Stop</span>
                <p>{post.postDetail.bus}m away</p>
              </div>
            </div>
            <div className="feature">
              <img src="/fee.png" alt="" />
              <div className="featureText">
                <span>Restaurant</span>
                <p>{post.postDetail.restaurant}m away</p>
              </div>
            </div>
          </div>
          <p className="title">Location</p>
          <div className="mapContainer">
            <Map items={[post]} />
          </div>
          <div className="buttons">
            <button onClick={handleChat}>
              <img src="/chat.png" alt="" />
              Send a Message
            </button>
            <button
              onClick={handleSave}
              style={{
                backgroundColor: saved ? "#fece51" : "white",
              }}
            >
              <img src="/save.png" alt="" />
              {saved ? "Place Saved" : "Save the Place"}
            </button>
          </div>
        </div>
      </div>
      {chat && <Chat chats={[chat]} />}
    </div>
  );
}

export default SinglePage;

@aditya-mistri
Copy link

@iceticshacker7 did you solve this issue @safak please solve

kind of solve the issue couldn't develop a good ui for chat

can you please share the solution , i could not figure it out

yeah sure you will have to paste this code below in SinglePage.jsx it would work but you'll figure it out on your own how it works

import "./singlePage.scss";
import Slider from "../../components/slider/Slider";
import Map from "../../components/map/Map";
import { useNavigate, useLoaderData } from "react-router-dom";
import DOMPurify from "dompurify";
import { useContext, useState, useEffect } from "react";
import { AuthContext } from "../../context/AuthContext";
import { SocketContext } from "../../context/SocketContext";
import apiRequest from "../../lib/apiRequest";
import Chat from "../../components/chat/Chat";
import { useNotificationStore } from "../../lib/notificationStore";

function SinglePage() {
  const post = useLoaderData();
  const [saved, setSaved] = useState(post.isSaved);
  const { currentUser } = useContext(AuthContext);
  const { socket } = useContext(SocketContext);
  const [chat, setChat] = useState(null);
  const navigate = useNavigate();
  const recieverID = post.userId;
  const decrease = useNotificationStore((state) => state.decrease);

  useEffect(() => {
    const fetchChats = async () => {
      try {
        const res = await apiRequest.get("/chats");
        const chats = res.data;
        const existingChat = chats.find(
          (chat) =>
            chat.userIDs.includes(currentUser.id) && chat.userIDs.includes(recieverID)
        );
        if (existingChat) {
          setChat(existingChat);
        } else {
          const res = await apiRequest.post("/chats", {
            userIDs: [currentUser.id, recieverID],
          });
          setChat(res.data);
        }
      } catch (err) {
        console.log(err);
      }
    };
    fetchChats();
  }, [currentUser.id, recieverID]);

  const handleChat = async () => {
    if (!currentUser) {
      navigate("/login");
    } else {
      if (chat) {
        handleOpenChat(chat.id, post.user);
      } else {
        const res = await apiRequest.post("/chats", {
          userIDs: [currentUser.id, recieverID],
        });
        setChat(res.data);
        handleOpenChat(res.data.id, post.user);
      }
    }
  };

  const handleOpenChat = async (id, receiver) => {
    try {
      const res = await apiRequest.get("/chats/" + id);
      if (!res.data.seenBy.includes(currentUser.id)) {
        decrease();
      }
      setChat({ ...res.data, receiver });
    } catch (err) {
      console.log(err);
    }
  };

  const handleSave = async () => {
    if (!currentUser) {
      navigate("/login");
    } else {
      setSaved((prev) => !prev);
      try {
        await apiRequest.post("/users/save", { postId: post.id });
      } catch (err) {
        console.log(err);
        setSaved((prev) => !prev);
      }
    }
  };

  return (
    <div className="singlePage">
      <div className="details">
        <div className="wrapper">
          <Slider images={post.images} />
          <div className="info">
            <div className="top">
              <div className="post">
                <h1>{post.title}</h1>
                <div className="address">
                  <img src="/pin.png" alt="" />
                  <span>{post.address}</span>
                </div>
                <div className="price">$ {post.price}</div>
              </div>
              <div className="user">
                <img src={post.user.avatar} alt="" />
                <span>{post.user.username}</span>
              </div>
            </div>
            <div
              className="bottom"
              dangerouslySetInnerHTML={{
                __html: DOMPurify.sanitize(post.postDetail.desc),
              }}
            ></div>
          </div>
        </div>
      </div>
      <div className="features">
        <div className="wrapper">
          <p className="title">General</p>
          <div className="listVertical">
            <div className="feature">
              <img src="/utility.png" alt="" />
              <div className="featureText">
                <span>Utilities</span>
                {post.postDetail.utilities === "owner" ? (
                  <p>Owner is responsible</p>
                ) : (
                  <p>Tenant is responsible</p>
                )}
              </div>
            </div>
            <div className="feature">
              <img src="/pet.png" alt="" />
              <div className="featureText">
                <span>Pet Policy</span>
                {post.postDetail.pet === "allowed" ? (
                  <p>Pets Allowed</p>
                ) : (
                  <p>Pets not Allowed</p>
                )}
              </div>
            </div>
            <div className="feature">
              <img src="/fee.png" alt="" />
              <div className="featureText">
                <span>Income Policy</span>
                <p>{post.postDetail.income}</p>
              </div>
            </div>
          </div>
          <p className="title">Sizes</p>
          <div className="sizes">
            <div className="size">
              <img src="/size.png" alt="" />
              <span>{post.postDetail.size} sqft</span>
            </div>
            <div className="size">
              <img src="/bed.png" alt="" />
              <span>{post.bedroom} beds</span>
            </div>
            <div className="size">
              <img src="/bath.png" alt="" />
              <span>{post.bathroom} bathroom</span>
            </div>
          </div>
          <p className="title">Nearby Places</p>
          <div className="listHorizontal">
            <div className="feature">
              <img src="/school.png" alt="" />
              <div className="featureText">
                <span>School</span>
                <p>
                  {post.postDetail.school > 999
                    ? post.postDetail.school / 1000 + "km"
                    : post.postDetail.school + "m"}{" "}
                  away
                </p>
              </div>
            </div>
            <div className="feature">
              <img src="/pet.png" alt="" />
              <div className="featureText">
                <span>Bus Stop</span>
                <p>{post.postDetail.bus}m away</p>
              </div>
            </div>
            <div className="feature">
              <img src="/fee.png" alt="" />
              <div className="featureText">
                <span>Restaurant</span>
                <p>{post.postDetail.restaurant}m away</p>
              </div>
            </div>
          </div>
          <p className="title">Location</p>
          <div className="mapContainer">
            <Map items={[post]} />
          </div>
          <div className="buttons">
            <button onClick={handleChat}>
              <img src="/chat.png" alt="" />
              Send a Message
            </button>
            <button
              onClick={handleSave}
              style={{
                backgroundColor: saved ? "#fece51" : "white",
              }}
            >
              <img src="/save.png" alt="" />
              {saved ? "Place Saved" : "Save the Place"}
            </button>
          </div>
        </div>
      </div>
      {chat && <Chat chats={[chat]} />}
    </div>
  );
}

export default SinglePage;

brother please share the code changes you have made in api > chat and message controllers?
I am getting error
image

@Satyam123kumar
Copy link

Hi, @aditya-mistri and @iceticshacker7 please help me out on this, are you able to implement it? As I am getting the same error

@EnesGjurgjiali
Copy link

EnesGjurgjiali commented Sep 25, 2024

Not the perfect solution, but this works!
chat component.txt
single page component.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants