• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atlp-rwanda / trojans-ec-fe / bdcd1d21-b4ae-4c8b-b981-d4cc5886c07c

pending completion
bdcd1d21-b4ae-4c8b-b981-d4cc5886c07c

push

circleci

GitHub
ft():Admin-disable-account-18470050 (#27)

289 of 407 branches covered (71.01%)

Branch coverage included in aggregate %.

35 of 35 new or added lines in 5 files covered. (100.0%)

797 of 961 relevant lines covered (82.93%)

16.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.1
/src/components/chatModel.js
1
/* eslint-disable react/jsx-key */
2
/* eslint-disable no-unused-vars */
3
import React from "react";
4

5
import { useEffect, useState,useRef } from "react";
6
import { useDispatch, useSelector } from "react-redux";
7
import { socket } from "../config/socket";
8
import chatIcon from "../assets/images/chat.svg";
9
import { ToastContainer } from "react-toastify";
10
import { setData,setSingle,setHasNewMessages } from "../redux/features/slices/chat";
11
import ChatMessage from "./chatMessage";
12

13
const chatModel = () => {
6✔
14

15
  const dispatch = useDispatch();
20✔
16

17

18

19
  const { loading, data,hasNewMessage, error, success } = useSelector((state) => state.chat);
22✔
20

21

22
  const [username, setUsername] = useState("");
18✔
23
  const [currentUser, setCurrentUser]=useState("");
18✔
24
  const [showNewMessages, setShowNewMessages] = useState(false);
18✔
25
  const [message, setMessage] = useState("");
18✔
26
  const [showChat, setShowChat] = useState(false);
18✔
27
  const messagesEndRef = useRef(null);
18✔
28
  const [connectedUser, setConnectedUser] = useState("");
18✔
29
  const [showConnectedUser, setShowConnectedUser] = useState(false);
18✔
30

31
  const currentUserLocal = localStorage.getItem("name");
18✔
32

33
  const scrollToBottom = () => {
18✔
34
      messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });
×
35
 
36
  };
37
    const handleScroll = (event) => {
18✔
38
    const { scrollTop, scrollHeight, clientHeight } = event.target;
×
39
     console.log(scrollTop+clientHeight)
×
40
     console.log(scrollHeight)
×
41

42
    if (((scrollTop + clientHeight)===scrollHeight-0.5) || ((scrollTop + clientHeight)===scrollHeight+0.5) || ((scrollTop + clientHeight)===scrollHeight)) {
×
43
      setShowNewMessages(false);
×
44
    } else {
45
      setShowNewMessages(true);
×
46
    }
47
  };
48
  useEffect(() => {
18✔
49
    setCurrentUser(currentUserLocal);
8✔
50
    socket.on("chat-message", (messageData) => {
8✔
51
    dispatch(setHasNewMessages(true))
×
52
     const msg={
×
53
      User: {
54
        email: "testBuyer@example.com",
55
        name: messageData.name,
56
        profilePic:
57
          "https://res.cloudinary.com/dmjxukx09/image/upload/v1675844692/profiles/Profile-Avatar-PNG-Free-Download_paqfrf.png",
58
        role: "buyer",
59
      },
60
      createdAt: new Date(),
61
      message: messageData.message,
62
    };
63

64
    dispatch(setSingle(msg))
×
65

66
    });
67

68
    socket.emit("new-user", username);
8✔
69

70
    socket.on("user-connected", (name) => {
8✔
71
      console.log(`${name} connected`, "");
×
72
      setConnectedUser(name);
×
73
      setShowConnectedUser(true);
×
74

75
      setTimeout(() => {
×
76
        setConnectedUser("");
×
77
        setShowConnectedUser(false);
×
78
      }, 4000);
79
    });
80

81
    socket.on("notifications", (message) => {
8✔
82
      console.log(message);
×
83
   
84
    });
85
    socket.on("all-messages", (message) => {
8✔
86
      console.log("here")
×
87
      console.log(message);
×
88
      dispatch(setData(message));
×
89
    });
90
    socket.on("connect_error", (err) => {
8✔
91
    });
92

93
    socket.on("username", (name) => {
8✔
94
      console.log(username)
×
95
      setUsername(name);
×
96
    });
97

98
  }, [setData]);
99

100

101
  const sendMessage = (e) => {
18✔
102
   e.preventDefault()
2✔
103
    const date = formatISODate(new Date());
2✔
104
    if(message!="" && data){
2!
105
    dispatch(setData([...data,{
2✔
106
      User: {
107
        email: "testBuyer@example.com",
108
        name: username,
109
        profilePic:
110
          "https://res.cloudinary.com/dmjxukx09/image/upload/v1675844692/profiles/Profile-Avatar-PNG-Free-Download_paqfrf.png",
111
        role: "buyer",
112
      },
113
      createdAt: new Date(),
114
      message: message,
115
    }])
116
    );
117

118
  
119
    socket.emit("send-chat-message", { username, message, date });
2✔
120
     setMessage('')
2✔
121
    }
122
    
123
  };
124

125
  function formatISODate(isoDate) {
126
    const date = new Date(isoDate);
2✔
127
    const options = {
2✔
128
      year: "numeric",
129
      month: "long",
130
      day: "numeric",
131
      hour: "numeric",
132
      minute: "numeric",
133
      hour12: false,
134
    };
135
    return date.toLocaleDateString(undefined, options);
2✔
136
  }
137

138
  const Show=()=>{
18✔
139
    setShowChat(!showChat)
×
140
    dispatch(setHasNewMessages(false))
×
141
  }
142

143
  return (
18✔
144
    <>
145
    <ToastContainer/>
146
   
147
      <div
148
        className={
149
          showChat
18!
150
            ? "fixed bottom-28 flex flex-col h-2/3 bg-white md:w-1/3 md:right-4 right-6 w-11/12"
151
            : "hidden"
152
        }
153
      >
154
        <header className="bg-purple-900 rounded-t-lg text-white p-4 px-6 flex justify-between ">
155
          <p className="text-white">Chat</p>
156

157
          <button onClick={() => setShowChat(false)}>x</button>
×
158
        </header>
159
        <div className="flex justify-center z-10">
160
         <p className="bg-gray-400 rounded-full px-2"> {showConnectedUser?connectedUser+" connected":""} </p>
18!
161
        </div>
162
        <div className="flex flex-col flex-1 overflow-y-auto px-4 py-6" onScroll={handleScroll}>
163
          
164
          {data &&
36✔
165
            data.map((message) => (  
166
    
167
           <ChatMessage message={message} currentUser={currentUser} isSelf={message.isSelf} />
12✔
168

169

170
            ))}
171

172
      <div ref={messagesEndRef}></div>
173
           
174

175
     
176
        </div>
177
        {showNewMessages && (
18!
178
        <div className="flex justify-center bg-white">
179
        <button className="bottom-4 right-4 bg-gray-500 text-white rounded-full p-4 " onClick={scrollToBottom}>
180
        <svg width="12" height="8" viewBox="0 0 12 8" fill="none" xmlns="http://www.w3.org/2000/svg">
181
<path d="M1.41 0L6 4.58L10.59 0L12 1.41L6 7.41L0 1.41L1.41 0Z" fill="white"/>
182
</svg>
183

184
        </button>
185
         </div>
186
      )}
187
      
188
      <div className="bg-white ">
189
          
190
            <form className="flex flex-row px-4 py-2" onSubmit={sendMessage}>
191
        <input type="text" value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Type a message..." className="flex-grow rounded-full bg-gray-200 py-2 px-4" />
2✔
192
         <button type="submit" data-testid="send message" className="ml-4 bg-purple-900 hover:bg-purple-800 text-white font-bold py-2 px-4 rounded-full">Send</button>
193
       </form>
194
       </div> 
195
      </div>
196
    
197
      <button
198
        onClick={() => Show()}
×
199
        title="Chat"
200
        className="fixed z-90 bottom-10 right-8  w-20 h-20 rounded-full drop-shadow-lg flex justify-center items-center text-white text-4xl  hover:animate-pulse duration-300"
201
      >
202
          <div style={{ position: "relative", display: "inline-block" }}>
203
      <img src={chatIcon} alt="Chat icon" />
204

205

206
      {hasNewMessage && (
18!
207
        <div
208
          style={{
209
            position: "absolute",
210
            top: "-5px",
211
            left: "-5px",
212
            backgroundColor: "red",
213
            width: "10px",
214
            height: "10px",
215
            borderRadius: "50%",
216
          }}
217
        />
218
      )}
219
    </div>
220
      </button>
221
    </>
222
  );
223
};
224

225
export default chatModel;
226

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc