@pubuduth-aplicy/chat-ui 2.1.77 → 2.1.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pubuduth-aplicy/chat-ui",
3
- "version": "2.1.77",
3
+ "version": "2.1.79",
4
4
  "description": "This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -1,7 +1,7 @@
1
1
  // config.ts
2
2
  export interface ChatConfig {
3
3
  apiUrl: string;
4
- role?: string;
4
+ role: string;
5
5
  cdnUrl?: string;
6
6
  webSocketUrl: string;
7
7
  }
@@ -5,7 +5,7 @@ import { Sidebar } from "./sidebar/Sidebar";
5
5
  import { useChatContext } from "../providers/ChatProvider";
6
6
 
7
7
  export const Chat = () => {
8
- const { setMessages, updateMessageStatus } = useChatUIStore();
8
+ const { setMessages, selectedConversation, updateMessageStatus } = useChatUIStore();
9
9
 
10
10
  const { socket, sendMessage } = useChatContext();
11
11
 
@@ -44,10 +44,14 @@ export const Chat = () => {
44
44
  return (
45
45
  <div className="container mx-auto mb-5">
46
46
  <div className="grid-container">
47
- <div className={`sidebarContainer dark:bg-gray-800`}>
47
+ <div className={`sidebarContainer dark:bg-gray-800 ${
48
+ selectedConversation ? "mobile-hidden" : "mobile-visible"
49
+ }`}>
48
50
  <Sidebar />
49
51
  </div>
50
- <div className="messageContainer">
52
+ <div className={`messageContainer ${
53
+ selectedConversation ? "mobile-visible" : "mobile-hidden"
54
+ }`}>
51
55
  <MessageContainer />
52
56
  </div>
53
57
  </div>
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { MessageSquare } from "lucide-react";
2
+ import { ChevronLeft, MessageSquare } from "lucide-react";
3
+ import { FiArrowLeft } from "react-icons/fi";
3
4
  import { useEffect } from "react";
4
5
  import MessageInput from "./MessageInput";
5
6
  import Messages from "./Messages";
@@ -22,7 +23,7 @@ const MessageContainer = () => {
22
23
  event: "joinChat",
23
24
  data: {
24
25
  chatId: selectedConversation._id,
25
- userId: userId
26
+ userId: userId,
26
27
  },
27
28
  })
28
29
  );
@@ -53,20 +54,18 @@ const MessageContainer = () => {
53
54
 
54
55
  // Listen for online users updates
55
56
 
56
-
57
-
58
- const participantDetails = Array.isArray(selectedConversation?.participantDetails)
57
+ const participantDetails = Array.isArray(
58
+ selectedConversation?.participantDetails
59
+ )
59
60
  ? selectedConversation?.participantDetails
60
61
  : [selectedConversation?.participantDetails].filter(Boolean);
61
62
 
62
- const participant = participantDetails.find(
63
- (p: any) => p._id !== userId
64
- );
63
+ const participant = participantDetails.find((p: any) => p._id !== userId);
65
64
 
66
65
  // const participant = selectedConversation?.participantDetails?.find(
67
66
  // (p: any) => p._id !== userId
68
67
  // );
69
-
68
+
70
69
  const isOnline = isUserOnline(participant?._id || "");
71
70
 
72
71
  // Cleanup on unmount
@@ -82,8 +81,11 @@ const MessageContainer = () => {
82
81
  <>
83
82
  <div className="chatMessageContainerInner">
84
83
  <div className="chatMessageContainerInnerDiv">
85
- <button className="chatMessageContainerInnerDiv_button">
86
- {/* <CaretLeft size={25} /> */}
84
+ <button
85
+ className="backButton"
86
+ onClick={() => setSelectedConversation(null)}
87
+ >
88
+ <ChevronLeft size={20} />
87
89
  </button>
88
90
  {selectedConversation.type === "service" ? (
89
91
  <div className="w-10 h-10 rounded-full bg-gray-200 flex items-center justify-center">
@@ -7,6 +7,7 @@ import { FilePreview, FileType } from "../common/FilePreview";
7
7
  import { getApiClient } from "../../lib/api/apiClient";
8
8
  import { MessageStatus } from "../../types/type";
9
9
  import { Path } from "../../lib/api/endpoint";
10
+ import { getChatConfig } from "../../Chat.config";
10
11
 
11
12
  const MAX_FILE_SIZE_MB = 5;
12
13
  const MAX_FILE_COUNT = 5;
@@ -37,6 +38,7 @@ interface Attachment {
37
38
 
38
39
  const MessageInput = () => {
39
40
  const apiClient = getApiClient();
41
+ const {role} = getChatConfig();
40
42
  const { socket, sendMessage, userId } = useChatContext();
41
43
  const { selectedConversation, setMessages } = useChatUIStore();
42
44
  const [message, setMessage] = useState("");
@@ -349,6 +351,8 @@ const MessageInput = () => {
349
351
  selectedConversation?.type === "service"
350
352
  ? selectedConversation?.serviceId
351
353
  : undefined,
354
+ senderRole: role,
355
+ receiverRole: role === 'customer' ? 'provider' : 'customer',
352
356
  },
353
357
  {
354
358
  onSuccess: (data) => {
@@ -116,7 +116,7 @@ const Conversation = ({ conversation }: ConversationProps) => {
116
116
  </p>
117
117
  <div className="flex items-center gap-2">
118
118
  {unreadCount > 0 && (
119
- <span className="bg-blue-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">
119
+ <span className="background text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">
120
120
  {unreadCount}
121
121
  </span>
122
122
  )}
@@ -22,6 +22,7 @@ declare module '@pubuduth-aplicy/chat-ui' {
22
22
  apiUrl: string;
23
23
  role?: string;
24
24
  webSocketUrl: string;
25
+ cdnUrl?: string;
25
26
  }
26
27
 
27
28
  interface ChatProviderProps {
@@ -41,7 +41,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
41
41
  const reconnectAttempts = useRef(0);
42
42
  const maxReconnectAttempts = 5;
43
43
  const reconnectInterval = 5000; // 5 seconds
44
- const { webSocketUrl } = getChatConfig();
44
+ const { webSocketUrl,role } = getChatConfig();
45
45
 
46
46
  const connectWebSocket = useCallback(() => {
47
47
  // console.log("🔌 Creating new WebSocket connection...");
@@ -49,7 +49,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
49
49
  // Convert HTTP URL to WebSocket URL
50
50
  const wsUrl = webSocketUrl.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
51
51
  const socketInstance = new WebSocket(
52
- `${wsUrl}?userId=${encodeURIComponent(userId)}`
52
+ `${wsUrl}?userId=${encodeURIComponent(userId)}&role=${encodeURIComponent(role)}`
53
53
  );
54
54
 
55
55
  socketInstance.onopen = () => {
@@ -62,6 +62,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
62
62
  JSON.stringify({
63
63
  event: "handshake",
64
64
  userId: userId,
65
+ role: role,
65
66
  })
66
67
  );
67
68
  };
@@ -86,7 +87,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
86
87
  console.error("❌ WebSocket error:", error);
87
88
  };
88
89
 
89
- socketInstance.onclose = (event) => {
90
+ socketInstance.onclose = () => {
90
91
  // console.log("🔌 WebSocket connection closed", event);
91
92
  // console.log("❌ WebSocket disconnected:", event.code, event.reason);
92
93
  setIsConnected(false);
@@ -12,6 +12,8 @@ export const sendMessage = async (params: {
12
12
  serviceTitle?: string;
13
13
  type?: "personal" | "service";
14
14
  serviceId?: string;
15
+ senderRole?: string;
16
+ receiverRole?: string;
15
17
  }) => {
16
18
  const {
17
19
  receiverId,
@@ -22,6 +24,8 @@ export const sendMessage = async (params: {
22
24
  serviceTitle,
23
25
  type,
24
26
  serviceId,
27
+ senderRole,
28
+ receiverRole,
25
29
  } = params;
26
30
  const apiClient = getApiClient();
27
31
 
@@ -34,7 +38,9 @@ export const sendMessage = async (params: {
34
38
  serviceTitle,
35
39
  type,
36
40
  serviceId,
37
- messageType: "user"
41
+ messageType: "user",
42
+ senderRole,
43
+ receiverRole
38
44
  }
39
45
  );
40
46
  return response.data;
@@ -12,7 +12,7 @@ export const getAllConversationData = async (userid: string) => {
12
12
 
13
13
  const endpoint = role === 'admin'
14
14
  ? `${Path.getConversationListByAdmin}`
15
- : `${Path.getconversation}/${userid}`;
15
+ : `${Path.getconversation}/${userid}/${role}`;
16
16
 
17
17
  const res = await apiClient.get<ApiResponse>(endpoint);
18
18
  if (res.data) {
@@ -9,12 +9,14 @@
9
9
  /* background-color: #9CA3AF; */
10
10
  --bg-opacity: 0;
11
11
  backdrop-blur: blur(16px);
12
+
13
+
12
14
  }
13
15
 
14
16
  .sidebarContainer {
15
17
  /* grid-column: span 3; */
16
18
  /* overflow-y: auto; */
17
- border: 1px solid #ddd;
19
+ /* border: 1px solid #ddd; */
18
20
  max-height: 100vh;
19
21
  }
20
22
 
@@ -23,6 +25,29 @@
23
25
  /* border: 1px solid; */
24
26
  max-height: 100vh;
25
27
  overflow-y: auto;
28
+
29
+ }
30
+
31
+ .sidebarContainer,
32
+ .messageContainer {
33
+ height: 100%;
34
+ }
35
+
36
+ .hide-on-mobile {
37
+ display: none;
38
+ }
39
+
40
+ .show {
41
+ display: block;
42
+ }
43
+
44
+ /* Back button visible only on mobile */
45
+ .back-button {
46
+ display: none;
47
+ }
48
+
49
+ .background {
50
+ background-color: #317490;
26
51
  }
27
52
 
28
53
  .chatSidebarMain {
@@ -58,7 +83,7 @@
58
83
  justify-content: flex-start;
59
84
  align-items: center;
60
85
  height: 2.5rem;
61
- background-color: rgb(248, 249, 249);
86
+ background-color: #FEFEFF;
62
87
  /* Move bg color here */
63
88
  }
64
89
 
@@ -167,6 +192,7 @@
167
192
  flex-direction: column;
168
193
  justify-content: center;
169
194
  height: 100%;
195
+ background-color: #FEFEFF;
170
196
  }
171
197
 
172
198
  .chatMessageContainerInner {
@@ -379,7 +405,7 @@
379
405
  }
380
406
 
381
407
  .chatMessageInputSubmit {
382
- background-color: #12bbb5;
408
+ background-color: #317490;
383
409
  border: none;
384
410
  width: 40px;
385
411
  height: 40px;
@@ -412,6 +438,8 @@
412
438
  width: 100%;
413
439
  font-family: Arial, sans-serif;
414
440
  margin-bottom: 8px;
441
+ margin: 0 auto;
442
+ max-width: 1200px;
415
443
  }
416
444
 
417
445
  .message-row {
@@ -468,14 +496,14 @@
468
496
  }
469
497
 
470
498
  .outgoing .chat-bubble {
471
- background-color: #aef7e883;
472
- color: #595c61;
499
+ background-color: #317490;
500
+ color: #DDE8ED;
473
501
 
474
502
  }
475
503
 
476
504
  .incoming .chat-bubble {
477
- background-color: #EBEDF0;
478
- color: #595c61;
505
+ background-color: #F4F3F6;
506
+ color: #476179;
479
507
  }
480
508
 
481
509
  .timestamp_incomeing {
@@ -551,15 +579,15 @@
551
579
  .sidebarContainer {
552
580
  /* display: grid; */
553
581
  grid-column: span 3;
554
- background-color: rgb(248, 249, 249);
555
- border-radius: 1%;
582
+ background-color: #FEFEFF;
583
+ border-radius: 2%;
556
584
  }
557
585
 
558
586
  .messageContainer {
559
587
  display: grid;
560
588
  grid-column: span 6;
561
- border: 1px solid #ddd;
562
- border-radius: 1%;
589
+ /* border: 1px solid #ddd; */
590
+ border-radius: 3%;
563
591
  }
564
592
 
565
593
  .chatMessageContainerInnerDiv_button {
@@ -1905,4 +1933,159 @@
1905
1933
 
1906
1934
  .message-option-btn.disabled:hover::before {
1907
1935
  background: #666;
1936
+ }
1937
+
1938
+ .backButton {
1939
+ display: none;
1940
+ align-items: center;
1941
+ gap: 4px;
1942
+ }
1943
+
1944
+
1945
+ @media (max-width: 768px) {
1946
+ .grid-container {
1947
+ display: flex;
1948
+ flex-direction: column;
1949
+ width: 100%;
1950
+ }
1951
+
1952
+ .sidebarContainer {
1953
+ max-height: auto;
1954
+ order: 1;
1955
+ }
1956
+
1957
+ .messageContainer {
1958
+ max-height: auto;
1959
+ order: 2;
1960
+ }
1961
+
1962
+ .chatSidebarSearchbar {
1963
+ padding: 1rem;
1964
+ flex-wrap: wrap;
1965
+ height: auto;
1966
+ }
1967
+
1968
+ .chatMessagesBubble_inner {
1969
+ max-width: 70%; /* allow wider bubbles on small screens */
1970
+ }
1971
+ }
1972
+
1973
+ /* Mobile Layout (≤ 480px) */
1974
+ @media (max-width: 480px) {
1975
+ .grid-container {
1976
+ flex-direction: column;
1977
+ width: 100%;
1978
+ }
1979
+
1980
+ .chatSidebarMain {
1981
+ flex-direction: column;
1982
+ padding: 0.5rem;
1983
+ }
1984
+
1985
+ .chatSidebarSearchbarContainer {
1986
+ padding: 0.5rem;
1987
+ font-size: 0.9rem;
1988
+ }
1989
+
1990
+ .chatMessageContainerInner {
1991
+ padding: 1rem;
1992
+ font-size: 0.8rem;
1993
+ }
1994
+
1995
+ .chatMessagesBubble_inner {
1996
+ max-width: 85%;
1997
+ font-size: 13px;
1998
+ }
1999
+
2000
+ .chatMessageInput {
2001
+ font-size: 0.9rem;
2002
+ padding: 6px 4px;
2003
+ }
2004
+
2005
+ .chatMessageInputSubmit {
2006
+ width: 35px;
2007
+ height: 35px;
2008
+ }
2009
+
2010
+ .chat-bubble {
2011
+ font-size: 13px;
2012
+ max-width: 90%;
2013
+ }
2014
+
2015
+ .timestamp_incomeing,
2016
+ .timestamp_outgoing {
2017
+ font-size: 10px;
2018
+ }
2019
+
2020
+ .attachments-preview {
2021
+ width: 100%;
2022
+ }
2023
+
2024
+ }
2025
+
2026
+ /* Mobile styles */
2027
+ @media (max-width: 768px) {
2028
+ .grid-container {
2029
+ display: block;
2030
+ }
2031
+
2032
+ .chatMessageContainer {
2033
+ display: flex;
2034
+ flex-direction: column;
2035
+ justify-content: center;
2036
+ height: 100%;
2037
+ background-color: #FEFEFF;
2038
+ width: 100%;
2039
+ }
2040
+
2041
+ .sidebarContainer,
2042
+ .messageContainer {
2043
+ width: 100%;
2044
+ }
2045
+
2046
+ .back-button {
2047
+ display: block;
2048
+ }
2049
+ .messageContainer.active {
2050
+ display: block;
2051
+ }
2052
+
2053
+ .sidebarContainer.hidden {
2054
+ display: none;
2055
+ }
2056
+
2057
+ .backButton {
2058
+ display: inline-block;
2059
+ margin-right: 10px;
2060
+ background: none;
2061
+ border: none;
2062
+ font-size: 14px;
2063
+ cursor: pointer;
2064
+ }
2065
+
2066
+ .mobile-hidden {
2067
+ display: none !important;
2068
+ }
2069
+ .mobile-visible {
2070
+ display: block !important;
2071
+ }
2072
+
2073
+ .chatMessageInputform{
2074
+ padding-left: 0rem;
2075
+ }
2076
+
2077
+ .message-input-container{
2078
+ padding: 0px;
2079
+ }
2080
+
2081
+ .media-item{
2082
+ width: 100%;
2083
+ }
2084
+
2085
+ .chatMessageInputSubmit {
2086
+ /* width: 25px; */
2087
+ height: 35px;
2088
+ }
2089
+
2090
+
1908
2091
  }