@axos-web-dev/shared-components 1.0.77-patch.60 → 1.0.77-patch.61

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.
@@ -41,7 +41,9 @@ const ChatWindow = ({
41
41
  showThankyouMessage,
42
42
  displayThankyouMessage,
43
43
  toggleThankyouMessage,
44
- hasEscalated
44
+ hasEscalated,
45
+ isBlockedInput,
46
+ isOpen
45
47
  } = useOpenChat();
46
48
  const [mounted, setMounted] = React.useState(false);
47
49
  const [menuOpen, setMenuOpen] = React.useState(false);
@@ -50,14 +52,14 @@ const ChatWindow = ({
50
52
  const [input, setInput] = React.useState("");
51
53
  const messagesEndRef = useRef(null);
52
54
  const inputRef = useRef(null);
53
- const isOpen = useOpenChat((state2) => state2.isOpen);
54
55
  useEffect(() => {
55
56
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
56
57
  }, [messages]);
57
58
  const handleSend = (e) => {
58
59
  e.preventDefault();
59
60
  const cleaned = cleanInput(input);
60
- if (cleaned) {
61
+ if (isBlockedInput) return;
62
+ if (cleaned != "") {
61
63
  onSend(cleaned);
62
64
  setInput("");
63
65
  }
@@ -451,7 +453,7 @@ const ChatWindow = ({
451
453
  style: {
452
454
  display: "flex",
453
455
  padding: "12px 16px",
454
- background: "#ffffff",
456
+ background: isBlockedInput || inputDisabled || status !== "connected" || messages.length == 0 || escalationDeflected ? "light-dark(rgba(239, 239, 239, 0.3), rgba(59, 59, 59, 0.3))" : "#ffffff",
455
457
  borderRadius: 12
456
458
  },
457
459
  children: [
@@ -466,18 +468,13 @@ const ChatWindow = ({
466
468
  previewTyping(e.target?.value);
467
469
  }
468
470
  if (e.key === "Enter" && !e.shiftKey) {
469
- e.preventDefault();
470
- const cleaned = cleanInput(input);
471
- if (cleaned) {
472
- onSend(cleaned);
473
- setInput("");
474
- }
471
+ handleSend(e);
475
472
  }
476
473
  },
477
474
  placeholder: "Ask anything...",
478
475
  className: clsx(inputStyle, autoResize),
479
476
  autoFocus: true,
480
- disabled: inputDisabled || status !== "connected" || messages.length == 0 || escalationDeflected,
477
+ disabled: isBlockedInput || inputDisabled || status !== "connected" || messages.length == 0 || escalationDeflected,
481
478
  rows: 1
482
479
  }
483
480
  ),
@@ -490,7 +487,7 @@ const ChatWindow = ({
490
487
  ),
491
488
  type: "submit",
492
489
  title: "Send message",
493
- disabled: inputDisabled || status !== "connected" || !input.trim() || messages.length == 0 || escalationDeflected,
490
+ disabled: isBlockedInput || inputDisabled || status !== "connected" || !input.trim() || messages.length == 0 || escalationDeflected,
494
491
  children: /* @__PURE__ */ jsx(
495
492
  "svg",
496
493
  {
@@ -7,4 +7,4 @@ export declare const Chatbot: ({ project, projectEnv, menuOption, debug, }: {
7
7
  projectEnv?: "dev" | "qa" | "uat" | "stg" | "prod";
8
8
  menuOption?: "Support Virtual Agent" | string;
9
9
  debug?: boolean;
10
- }) => import("react/jsx-runtime").JSX.Element;
10
+ }) => false | import("react/jsx-runtime").JSX.Element;
@@ -20,7 +20,9 @@ const Chatbot = ({
20
20
  reset,
21
21
  startEscalation,
22
22
  hasEscalated,
23
- endEscalation
23
+ endEscalation,
24
+ unblockInput,
25
+ blockInput
24
26
  } = useOpenChat();
25
27
  const { addMessage, addMessages, clearMessages, messages } = useMessages();
26
28
  const clientRef = useRef(null);
@@ -97,22 +99,27 @@ const Chatbot = ({
97
99
  };
98
100
  const onChatMessageHandler = async (message) => {
99
101
  console.log("Received message:", message);
100
- if (["system", "virtual_agent", "user"].includes(message.$userType) && message.event === void 0) {
102
+ const { event, $userType } = message;
103
+ if (["system", "virtual_agent", "user"].includes($userType) && event === void 0) {
101
104
  addMessage(message);
105
+ if (!hasEscalated) {
106
+ unblockInput?.();
107
+ }
102
108
  return;
103
109
  }
104
- const eventName = message?.event;
105
- switch (eventName) {
110
+ switch (event) {
106
111
  case "escalationAccepted":
112
+ case "escalationStarted":
107
113
  setScalationStarted(true);
108
114
  startEscalation?.();
109
115
  addMessage(message);
110
116
  return;
111
- case "escalationStarted":
112
- setScalationStarted(true);
113
- startEscalation?.();
117
+ case "escalationEnded":
118
+ case "escalationFailed": {
119
+ endEscalation?.();
114
120
  addMessage(message);
115
121
  return;
122
+ }
116
123
  default:
117
124
  addMessage(message);
118
125
  if (["end_user"].includes(message.$userType)) {
@@ -157,19 +164,28 @@ const Chatbot = ({
157
164
  const onChatConnectedHandler = async () => {
158
165
  setStatus("connected");
159
166
  console.log("connected");
160
- const messages2 = await clientRef.current?.fetchMessages();
161
- if (messages2) {
162
- addMessages(messages2);
163
- const hasEscalation = messages2.some(
164
- (msg) => msg.$userType === "user" || ["escalationAccepted", "escalationStarted"].includes(
165
- msg.event
166
- )
167
- );
168
- console.log(hasEscalation);
169
- if (hasEscalation) {
170
- setScalationStarted(true);
171
- startEscalation?.();
167
+ try {
168
+ if (!clientRef.current) {
169
+ console.error("Client not initialized on chat connected");
170
+ return;
172
171
  }
172
+ const messages2 = await clientRef.current?.fetchMessages();
173
+ console.log("Fetched messages on chat connected:", messages2);
174
+ if (messages2) {
175
+ addMessages(messages2);
176
+ const hasEscalation = messages2.some(
177
+ (msg) => msg.$userType === "user" || ["escalationAccepted", "escalationStarted"].includes(
178
+ msg.event
179
+ )
180
+ );
181
+ console.log(hasEscalation);
182
+ if (hasEscalation) {
183
+ setScalationStarted(true);
184
+ startEscalation?.();
185
+ }
186
+ }
187
+ } catch (error) {
188
+ console.error("Error fetching messages on chat connected:", error);
173
189
  }
174
190
  };
175
191
  const registerEventHandlers = () => {
@@ -278,7 +294,15 @@ const Chatbot = ({
278
294
  };
279
295
  const onSendMessage = async (msg) => {
280
296
  console.log("Sending message:", msg);
281
- await clientRef.current?.sendTextMessage(msg);
297
+ try {
298
+ await clientRef.current?.sendTextMessage(msg);
299
+ } catch (error) {
300
+ console.log(error);
301
+ } finally {
302
+ if (!hasEscalated) {
303
+ blockInput?.();
304
+ }
305
+ }
282
306
  };
283
307
  const onEndChat = async () => {
284
308
  console.log("Ending chat");
@@ -341,7 +365,7 @@ const Chatbot = ({
341
365
  console.error("Error sending preview message:", error);
342
366
  }
343
367
  };
344
- return /* @__PURE__ */ jsxs("div", { className: project === "ufb" ? chatbotUFB : chatbotAXB, children: [
368
+ return menusLoaded && /* @__PURE__ */ jsxs("div", { className: project === "ufb" ? chatbotUFB : chatbotAXB, children: [
345
369
  /* @__PURE__ */ jsx(Bubble, { onClick: handleClick }),
346
370
  /* @__PURE__ */ jsx(
347
371
  ChatWindow,
@@ -9,7 +9,7 @@ import '../assets/themes/victorie.css';import '../assets/themes/ufb.css';import
9
9
  /* empty css */
10
10
  /* empty css */
11
11
  import clsx from "clsx";
12
- import { shimmerText, notificationStyle, endChatButtonStyle, messageStyle, user_msg, agent_msg, inline_button_wrapper, inline_button } from "./ChatWindow.css.js";
12
+ import { shimmerText, notificationStyle, messageStyle, user_msg, agent_msg, inline_button_wrapper, inline_button, endChatButtonStyle } from "./ChatWindow.css.js";
13
13
  import { useOpenChat } from "./store/chat.js";
14
14
  function timeAgo(date) {
15
15
  const seconds = Math.floor(((/* @__PURE__ */ new Date()).getTime() - date.getTime()) / 1e3);
@@ -24,7 +24,6 @@ const ChatbotMessage = ({
24
24
  showAvatar,
25
25
  showName,
26
26
  virtualAgent,
27
- onCancelEndChat,
28
27
  onEndChat,
29
28
  onSend
30
29
  }) => {
@@ -76,23 +75,20 @@ const ChatbotMessage = ({
76
75
  " ",
77
76
  msg.to_agent ? /* @__PURE__ */ jsx("strong", { children: msg?.to_agent?.name }) : "an agent"
78
77
  ] }, msg.$index),
79
- msg.type == "noti" && msg.$userType == "virtual_agent" && msg.event == "escalationDeflected" && /* @__PURE__ */ jsxs(Fragment, { children: [
80
- /* @__PURE__ */ jsxs(
81
- "div",
82
- {
83
- className: notificationStyle,
84
- style: { fontSize: 12 },
85
- children: [
86
- "Our chat team is available weekdays, 8am-5pm, except federal bank holidays. For immediate assistance you can reach out to us at",
87
- " ",
88
- /* @__PURE__ */ jsx("a", { href: "tel:1-888-502-2967", children: "1-888-502-2967" }),
89
- "."
90
- ]
91
- },
92
- msg.$index
93
- ),
94
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: 12 }, children: /* @__PURE__ */ jsx("button", { className: endChatButtonStyle, onClick: onCancelEndChat, children: "End Chat" }) })
95
- ] }),
78
+ msg.type == "noti" && msg.$userType == "virtual_agent" && msg.event == "escalationDeflected" && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
79
+ "div",
80
+ {
81
+ className: notificationStyle,
82
+ style: { fontSize: 12 },
83
+ children: [
84
+ "Our chat team is available weekdays, 8am-5pm, except federal bank holidays. For immediate assistance you can reach out to us at",
85
+ " ",
86
+ /* @__PURE__ */ jsx("a", { href: "tel:1-888-502-2967", children: "1-888-502-2967" }),
87
+ "."
88
+ ]
89
+ },
90
+ msg.$index
91
+ ) }),
96
92
  ["text", "markdown_template", "markdown"].includes(msg.type) && /* @__PURE__ */ jsx(
97
93
  "div",
98
94
  {
@@ -181,7 +177,28 @@ const ChatbotMessage = ({
181
177
  index
182
178
  );
183
179
  }) }),
184
- msg.event == "chatEnded" && /* @__PURE__ */ jsxs(Fragment, { children: [
180
+ " ",
181
+ msg.event == "chatEnded" && msg.status == "failed" && /* @__PURE__ */ jsxs(Fragment, { children: [
182
+ /* @__PURE__ */ jsxs(
183
+ "div",
184
+ {
185
+ title: (/* @__PURE__ */ new Date()).toLocaleString(),
186
+ style: {
187
+ fontSize: 12,
188
+ color: "#888",
189
+ marginBottom: 4,
190
+ textAlign: "center"
191
+ },
192
+ children: [
193
+ "No team members are online at the moment.",
194
+ /* @__PURE__ */ jsx("br", {}),
195
+ " Please try again later."
196
+ ]
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: 12 }, children: /* @__PURE__ */ jsx("button", { className: endChatButtonStyle, onClick: onEndChat, children: "End Chat" }) })
200
+ ] }),
201
+ msg.event == "chatEnded" && msg.status != "failed" && /* @__PURE__ */ jsxs(Fragment, { children: [
185
202
  /* @__PURE__ */ jsxs(
186
203
  "div",
187
204
  {
@@ -11,6 +11,9 @@ interface OpenChatState {
11
11
  hasEscalated?: boolean;
12
12
  startEscalation?: () => void;
13
13
  endEscalation?: () => void;
14
+ isBlockedInput?: boolean;
15
+ blockInput?: () => void;
16
+ unblockInput?: () => void;
14
17
  }
15
18
  export declare const useOpenChat: import('zustand').UseBoundStore<import('zustand').StoreApi<OpenChatState>>;
16
19
  export {};
@@ -17,12 +17,16 @@ const useOpenChat = create((set, get) => ({
17
17
  hasOpenedOnce: false,
18
18
  isOpen: false,
19
19
  showThankyouMessage: false,
20
- hasEscalated: false
20
+ hasEscalated: false,
21
+ isBlockedInput: false
21
22
  }),
22
23
  displayThankyouMessage: () => set({ showThankyouMessage: true }),
23
24
  toggleThankyouMessage: () => set((state) => ({ showThankyouMessage: !state.showThankyouMessage })),
24
25
  startEscalation: () => set({ hasEscalated: true }),
25
- endEscalation: () => set({ hasEscalated: false })
26
+ endEscalation: () => set({ hasEscalated: false }),
27
+ isBlockedInput: false,
28
+ blockInput: () => set({ isBlockedInput: true }),
29
+ unblockInput: () => set({ isBlockedInput: false })
26
30
  }));
27
31
  export {
28
32
  useOpenChat
@@ -1,9 +1,9 @@
1
1
  @keyframes _13n1jqku {
2
2
  0% {
3
- background-position: -200% 0;
3
+ background-position: 200% 0;
4
4
  }
5
5
  100% {
6
- background-position: 200% 0;
6
+ background-position: -200% 0;
7
7
  }
8
8
  }
9
9
  ._13n1jqk0 {
@@ -93,6 +93,7 @@ button:has(span:hover) ._13n1jqk6 {
93
93
  font-size: 16px;
94
94
  opacity: 0.7;
95
95
  outline: none;
96
+ background: transparent;
96
97
  resize: none;
97
98
  }
98
99
  ._13n1jqk9::placeholder {
@@ -101,21 +102,23 @@ button:has(span:hover) ._13n1jqk6 {
101
102
  ._1hpv6vm1 ._13n1jqk9::placeholder {
102
103
  color: rgba(31,31,31,.58);
103
104
  }
105
+ ._13n1jqk9:disabled {
106
+ cursor: not-allowed;
107
+ }
104
108
  ._13n1jqka {
105
109
  overflow-y: hidden;
106
110
  min-height: 20px;
107
111
  }
108
112
  ._13n1jqkb {
109
113
  padding-inline: 20px;
110
- background: #ffffff;
114
+ background: transparent;
111
115
  border: none;
112
116
  }
113
117
  ._13n1jqkb:hover {
114
- background: #ffffff;
115
118
  cursor: pointer;
116
119
  }
117
- ._1hpv6vm1 ._13n1jqkb:hover {
118
- background: #eae8e8;
120
+ ._13n1jqkb:disabled {
121
+ cursor: not-allowed;
119
122
  }
120
123
  ._13n1jqkb svg {
121
124
  fill: rgba(31,31,31,.38);
@@ -301,8 +304,13 @@ button:has(span:hover) ._13n1jqk6 {
301
304
  border-bottom-right-radius: 32px;
302
305
  }
303
306
  ._13n1jqkv {
304
- background: linear-gradient(90deg, var(--_1073cm819) 0%, rgba(255,255,255,0.8) 50%, var(--_1073cm819) 100%);
305
- background-size: 200% 100%;
307
+ background: linear-gradient(
308
+ 90deg,
309
+ var(--_1073cm819) 0%,
310
+ rgba(255,255,255,0.8) 50%,
311
+ var(--_1073cm819) 100%
312
+ );
313
+ background-size: 200% auto;
306
314
  background-clip: text;
307
315
  -webkit-background-clip: text;
308
316
  color: transparent;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@axos-web-dev/shared-components",
3
3
  "description": "Axos shared components library for web.",
4
- "version": "1.0.77-patch.60",
4
+ "version": "1.0.77-patch.61",
5
5
  "type": "module",
6
6
  "module": "dist/main.js",
7
7
  "types": "dist/main.d.ts",