@axos-web-dev/shared-components 2.0.0-dev.1 → 2.0.0-dev.11

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.
Files changed (214) hide show
  1. package/README.md +111 -111
  2. package/dist/ATMLocator/ATMLocator.js +6 -11
  3. package/dist/Article/Article.d.ts +2 -2
  4. package/dist/Article/Article.js +13 -2
  5. package/dist/Auth/ErrorAlert.js +7 -12
  6. package/dist/Auth/SignInPassword.js +0 -1
  7. package/dist/Avatar/Avatar.module.js +7 -7
  8. package/dist/Blockquote/Blockquote.module.js +3 -3
  9. package/dist/BulletItem/BulletItem.js +0 -1
  10. package/dist/Button/Button.js +7 -13
  11. package/dist/Calculators/AnnualFeeCalculator/index.js +0 -1
  12. package/dist/Calculators/ApyCalculator/index.js +3 -1
  13. package/dist/Calculators/AxosOneCalculator/index.js +16 -9
  14. package/dist/Calculators/BalanceAPYCalculator/index.js +0 -1
  15. package/dist/Calculators/BuyDownCalculator/index.js +0 -1
  16. package/dist/Calculators/Calculator.js +4 -9
  17. package/dist/Calculators/MarginTradingCalculator/index.js +119 -2
  18. package/dist/Calculators/MarineLoanMonthlyPaymentCalculator/index.js +0 -1
  19. package/dist/Calculators/MaxLoanCalculator/index.js +0 -1
  20. package/dist/Calculators/MonthlyPaymentCalculator/index.js +0 -1
  21. package/dist/Calculators/MonthlyPaymentLVFCalculator/index.js +0 -1
  22. package/dist/Calculators/SummitApyCalculator/index.js +3 -2
  23. package/dist/Carousel/index.js +6 -11
  24. package/dist/Chatbot/AnimatedGradientBorder.css.d.ts +2 -0
  25. package/dist/Chatbot/AnimatedGradientBorder.css.js +7 -3
  26. package/dist/Chatbot/Bubble.css.js +2 -1
  27. package/dist/Chatbot/Bubble.d.ts +2 -1
  28. package/dist/Chatbot/Bubble.js +102 -92
  29. package/dist/Chatbot/Chat.js +0 -7
  30. package/dist/Chatbot/ChatWindow.css.d.ts +4 -0
  31. package/dist/Chatbot/ChatWindow.css.js +8 -0
  32. package/dist/Chatbot/ChatWindow.d.ts +2 -0
  33. package/dist/Chatbot/ChatWindow.js +34 -15
  34. package/dist/Chatbot/Chatbot.d.ts +2 -2
  35. package/dist/Chatbot/Chatbot.js +164 -33
  36. package/dist/Chatbot/ChatbotMessage.d.ts +2 -0
  37. package/dist/Chatbot/ChatbotMessage.js +88 -25
  38. package/dist/Chatbot/index.js +5 -1
  39. package/dist/Chatbot/store/chat.d.ts +6 -0
  40. package/dist/Chatbot/store/chat.js +14 -2
  41. package/dist/Chatbot/store/messages.d.ts +1 -0
  42. package/dist/Chatbot/store/messages.js +5 -2
  43. package/dist/Chevron/index.js +6 -12
  44. package/dist/Comparison/Comparison.js +6 -11
  45. package/dist/ExecutiveBio/ExecutiveBio.css.d.ts +51 -1
  46. package/dist/ExecutiveBio/ExecutiveBio.css.js +48 -46
  47. package/dist/ExecutiveBio/ExecutiveBio.d.ts +1 -1
  48. package/dist/ExecutiveBio/ExecutiveBio.interface.d.ts +3 -1
  49. package/dist/ExecutiveBio/ExecutiveBio.js +146 -155
  50. package/dist/ExecutiveBio/ExecutiveBioSet.d.ts +1 -2
  51. package/dist/ExecutiveBio/ExecutiveBioSet.js +29 -16
  52. package/dist/ExecutiveBio/index.js +2 -1
  53. package/dist/FaqAccordion/index.js +6 -11
  54. package/dist/FdicCallout/FdicCallout.module.js +2 -2
  55. package/dist/FooterSiteMap/AxosBank/FooterSiteMap.js +87 -188
  56. package/dist/Forms/ApplicationStart.js +0 -1
  57. package/dist/Forms/ApplyNow.js +5 -10
  58. package/dist/Forms/BoatMooringLocation.d.ts +2 -0
  59. package/dist/Forms/BoatMooringLocation.js +56 -1
  60. package/dist/Forms/ClearingForm.js +0 -1
  61. package/dist/Forms/CommercialDeposits.js +0 -1
  62. package/dist/Forms/CommercialDepositsNoLendingOption.js +0 -1
  63. package/dist/Forms/CommercialLending.js +0 -1
  64. package/dist/Forms/CommercialPremiumFinance.js +0 -1
  65. package/dist/Forms/ConstructionLendingDynamic.d.ts +12 -0
  66. package/dist/Forms/ConstructionLendingDynamic.js +324 -0
  67. package/dist/Forms/ContactCompany.js +0 -1
  68. package/dist/Forms/ContactCompanyTitle.js +0 -1
  69. package/dist/Forms/ContactUs.js +0 -1
  70. package/dist/Forms/ContactUsAAS.js +0 -1
  71. package/dist/Forms/ContactUsBusiness.js +6 -11
  72. package/dist/Forms/ContactUsBusinessNameEmail.js +6 -11
  73. package/dist/Forms/ContactUsLVF.js +0 -1
  74. package/dist/Forms/ContactUsNMLSId.js +6 -11
  75. package/dist/Forms/CpraRequest.js +100 -3
  76. package/dist/Forms/CraPublicFile.js +6 -11
  77. package/dist/Forms/DealerServices.js +0 -1
  78. package/dist/Forms/EmailOnly.js +13 -13
  79. package/dist/Forms/EmailUs.js +40 -35
  80. package/dist/Forms/FormEnums.js +1 -3
  81. package/dist/Forms/Forms.css.d.ts +4 -1
  82. package/dist/Forms/Forms.css.js +42 -42
  83. package/dist/Forms/HoneyPot/index.js +0 -1
  84. package/dist/Forms/MortgageRate/MortgageRateForm.js +7 -12
  85. package/dist/Forms/MortgageRate/MortgageRateWatch.js +6 -11
  86. package/dist/Forms/MortgageWarehouseLending.js +6 -11
  87. package/dist/Forms/QuickPricer/QuickPricerForm.js +0 -1
  88. package/dist/Forms/ScheduleCall.js +0 -1
  89. package/dist/Forms/ScheduleCallPremier.js +0 -1
  90. package/dist/Forms/SuccesForm.js +7 -12
  91. package/dist/Forms/VendorQuestionnaire.js +0 -1
  92. package/dist/Forms/index.d.ts +1 -0
  93. package/dist/Forms/index.js +2 -1
  94. package/dist/HeroBanner/HeroBanner.css.d.ts +1 -0
  95. package/dist/HeroBanner/HeroBanner.css.js +19 -16
  96. package/dist/HeroBanner/HeroBanner.d.ts +1 -1
  97. package/dist/HeroBanner/HeroBanner.interface.d.ts +4 -1
  98. package/dist/HeroBanner/HeroBanner.js +26 -160
  99. package/dist/HeroBanner/HeroVideoPoster.d.ts +5 -0
  100. package/dist/HeroBanner/HeroVideoPoster.js +24 -0
  101. package/dist/HeroBanner/LargeBanner.css.d.ts +110 -0
  102. package/dist/HeroBanner/LargeBanner.css.js +22 -8
  103. package/dist/HeroBanner/LargeHeroBanner.d.ts +5 -0
  104. package/dist/HeroBanner/LargeHeroBanner.js +228 -0
  105. package/dist/HeroBanner/index.js +3 -2
  106. package/dist/Hyperlink/index.js +10 -14
  107. package/dist/IconBillboard/IconBillboard.css.d.ts +1 -0
  108. package/dist/IconBillboard/IconBillboard.css.js +11 -9
  109. package/dist/IconBillboard/index.js +2 -1
  110. package/dist/ImageBillboard/ImageBillboardSet.js +14 -8
  111. package/dist/ImageLink/ImageLink.js +5 -10
  112. package/dist/ImageLink/ImageLinkSet.js +5 -10
  113. package/dist/ImageLink/index.js +5 -10
  114. package/dist/Insight/Featured/CategorySelector.js +5 -10
  115. package/dist/Insight/Featured/Featured.js +6 -11
  116. package/dist/Insight/Featured/Header.js +6 -11
  117. package/dist/Interstitial/Interstitial.module.js +10 -10
  118. package/dist/LandingPageHeader/LandingPageHeader.css.d.ts +19 -1
  119. package/dist/LandingPageHeader/LandingPageHeader.css.js +6 -6
  120. package/dist/LandingPageHeader/LandingPageHeader.d.ts +3 -1
  121. package/dist/LandingPageHeader/LandingPageHeader.js +42 -16
  122. package/dist/LoadingIndicator/index.js +0 -1
  123. package/dist/Modal/Modal.js +5 -10
  124. package/dist/Modal/contextApi/store.d.ts +16 -2
  125. package/dist/Modal/contextApi/store.js +37 -6
  126. package/dist/NavigationMenu/AxosALTS/NavBar.module.js +23 -23
  127. package/dist/NavigationMenu/AxosALTS/NavData.d.ts +7 -1
  128. package/dist/NavigationMenu/AxosALTS/NavData.js +6 -137
  129. package/dist/NavigationMenu/AxosALTS/index.js +14 -16
  130. package/dist/NavigationMenu/AxosAdvisor/NavBar.module.js +52 -52
  131. package/dist/NavigationMenu/AxosAdvisor/SubNavBar.js +0 -1
  132. package/dist/NavigationMenu/AxosAdvisor/index.js +0 -1
  133. package/dist/NavigationMenu/AxosAdvisorServices/NavBar.module.js +53 -53
  134. package/dist/NavigationMenu/AxosAdvisorServices/SubNavBar.js +0 -1
  135. package/dist/NavigationMenu/AxosAdvisorServices/index.js +0 -1
  136. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.js +341 -73
  137. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.module.js +50 -17
  138. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileNavData.d.ts +26 -12
  139. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileNavData.js +216 -366
  140. package/dist/NavigationMenu/AxosBank/NavBar.module.js +39 -39
  141. package/dist/NavigationMenu/AxosBank/NavData.d.ts +39 -2
  142. package/dist/NavigationMenu/AxosBank/NavData.js +34 -166
  143. package/dist/NavigationMenu/AxosBank/SubNavBar.js +229 -254
  144. package/dist/NavigationMenu/AxosBank/index.js +19 -54
  145. package/dist/NavigationMenu/AxosClearing/NavBar.module.js +37 -37
  146. package/dist/NavigationMenu/AxosClearing/index.js +0 -1
  147. package/dist/NavigationMenu/AxosFiduciary/NavBar.module.js +41 -41
  148. package/dist/NavigationMenu/LaVictoire/NavBar.module.js +37 -37
  149. package/dist/NavigationMenu/LaVictoire/NavData.d.ts +13 -2
  150. package/dist/NavigationMenu/LaVictoire/NavData.js +14 -146
  151. package/dist/NavigationMenu/LaVictoire/SubNavBar.js +4 -1
  152. package/dist/NavigationMenu/LaVictoire/index.js +19 -44
  153. package/dist/NavigationMenu/Navbar.js +8 -9
  154. package/dist/NavigationMenu/SignInNavButton.js +19 -27
  155. package/dist/SetContainer/SetContainer.js +6 -11
  156. package/dist/SocialMediaBar/iconsRepository.d.ts +44 -14
  157. package/dist/SocialMediaBar/iconsRepository.js +32 -41
  158. package/dist/SocialMediaBar/index.js +3 -1
  159. package/dist/Tab/Tab.js +0 -1
  160. package/dist/Table/Table.js +0 -1
  161. package/dist/VideoTile/VideoTile.js +4 -9
  162. package/dist/VideoWrapper/index.js +4 -9
  163. package/dist/WalnutIframe/wrapper.module.js +3 -3
  164. package/dist/assets/Avatar/Avatar.css +59 -59
  165. package/dist/assets/Blockquote/Blockquote.css +72 -72
  166. package/dist/assets/Calculators/ApyCalculator/ApyCalculator.css +1 -1
  167. package/dist/assets/Calculators/MarginTradingCalculator/MarginTradingCalculator.css +2 -2
  168. package/dist/assets/Calculators/SummitApyCalculator/BalanceAPYCalculator.css +1 -1
  169. package/dist/assets/Carousel/Carousel.css +1 -1
  170. package/dist/assets/Chatbot/AnimatedGradientBorder.css +65 -8
  171. package/dist/assets/Chatbot/Bubble.css +19 -6
  172. package/dist/assets/Chatbot/ChatWindow.css +44 -10
  173. package/dist/assets/DownloadTile/DownloadTile.css +2 -2
  174. package/dist/assets/ExecutiveBio/ExecutiveBio.css +280 -172
  175. package/dist/assets/FdicCallout/FdicCallout.css +48 -48
  176. package/dist/assets/Forms/Forms.css +122 -115
  177. package/dist/assets/HelpArticle/HelpArticle.css +2 -2
  178. package/dist/assets/HeroBanner/HeroBanner.css +82 -65
  179. package/dist/assets/HeroBanner/LargeBanner.css +126 -59
  180. package/dist/assets/IconBillboard/IconBillboard.css +35 -28
  181. package/dist/assets/Inputs/Input.css +1 -1
  182. package/dist/assets/Insight/Featured/CategorySelector.css +1 -1
  183. package/dist/assets/Insight/Insight.css +4 -4
  184. package/dist/assets/Interstitial/Interstitial.css +142 -142
  185. package/dist/assets/LandingPageHeader/LandingPageHeader.css +28 -15
  186. package/dist/assets/NavigationMenu/AxosALTS/NavBar.css +264 -264
  187. package/dist/assets/NavigationMenu/AxosAdvisor/NavBar.css +609 -609
  188. package/dist/assets/NavigationMenu/AxosAdvisorServices/NavBar.css +630 -630
  189. package/dist/assets/NavigationMenu/AxosBank/MobileMenu/MobileMenu.css +353 -192
  190. package/dist/assets/NavigationMenu/AxosBank/NavBar.css +445 -445
  191. package/dist/assets/NavigationMenu/AxosClearing/NavBar.css +484 -484
  192. package/dist/assets/NavigationMenu/AxosFiduciary/NavBar.css +427 -427
  193. package/dist/assets/NavigationMenu/LaVictoire/NavBar.css +429 -429
  194. package/dist/assets/Topic/Topic.css +1 -1
  195. package/dist/assets/Typography/Typography.css +1 -1
  196. package/dist/assets/VideoTile/VideoTile.css +1 -1
  197. package/dist/assets/WalnutIframe/wrapper.css +48 -48
  198. package/dist/assets/globals.css +28 -18
  199. package/dist/assets/notification.mp3.js +4 -0
  200. package/dist/assets/utils/optimizeImage/optimizeImage.css +47 -47
  201. package/dist/main.js +16 -6
  202. package/dist/utils/allowedAxosDomains.d.ts +5 -2
  203. package/dist/utils/allowedAxosDomains.js +50 -47
  204. package/dist/utils/appendQueryParams.js +36 -5
  205. package/dist/utils/getPosition.d.ts +1 -0
  206. package/dist/utils/getPosition.js +17 -0
  207. package/dist/utils/index.js +2 -1
  208. package/dist/utils/optimizeImage/optimizeImage.module.js +3 -3
  209. package/dist/utils/validateExternalLinks.d.ts +1 -1
  210. package/dist/utils/validateExternalLinks.js +4 -6
  211. package/dist/utils/variant.types.d.ts +1 -0
  212. package/package.json +148 -148
  213. package/dist/NavigationMenu/NavDataJson.d.ts +0 -2
  214. package/dist/NavigationMenu/NavDataJson.js +0 -317
@@ -1,20 +1,42 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from "react/jsx-runtime";
3
+ import { useRef, useState, useEffect } from "react";
4
+ import { useMount, useUnmount } from "react-use";
5
+ import notificationSound from "../assets/notification.mp3.js";
3
6
  import { authenticate } from "./authenticate.js";
4
7
  import { Bubble } from "./Bubble.js";
5
- import { chatbotUFB, chatbotAXB } from "./Chatbot.css.js";
8
+ import { chatbotAXB, chatbotUFB } from "./Chatbot.css.js";
6
9
  import { ChatWindow } from "./ChatWindow.js";
7
10
  import { useOpenChat } from "./store/chat.js";
8
11
  import { useMessages } from "./store/messages.js";
9
- import { useRef, useState, useEffect } from "react";
10
- import { useMount, useUnmount } from "react-use";
12
+ const __vite_import_meta_env__ = {};
13
+ const env = __vite_import_meta_env__ || process.env;
14
+ if (typeof window !== "undefined") {
15
+ const OriginalAudio = window.Audio;
16
+ class PatchedAudio extends OriginalAudio {
17
+ constructor(src) {
18
+ const newSrc = src === "https://websdk.ujet.co/v3/ping.mp3" ? notificationSound : src;
19
+ super(newSrc);
20
+ }
21
+ }
22
+ window.Audio = PatchedAudio;
23
+ }
11
24
  const Chatbot = ({
12
25
  project = "axos",
13
26
  projectEnv = "dev",
14
27
  menuOption = "Support Virtual Agent",
15
28
  debug = false
16
29
  }) => {
17
- const { hasOpenedOnce, toggle, reset } = useOpenChat();
30
+ const {
31
+ hasOpenedOnce,
32
+ toggle,
33
+ reset,
34
+ startEscalation,
35
+ hasEscalated,
36
+ endEscalation,
37
+ unblockInput,
38
+ blockInput
39
+ } = useOpenChat();
18
40
  const { addMessage, addMessages, clearMessages, messages } = useMessages();
19
41
  const clientRef = useRef(null);
20
42
  const menuRef = useRef(null);
@@ -26,6 +48,20 @@ const Chatbot = ({
26
48
  const [hasStarted, setHasStarted] = useState(false);
27
49
  const [menusLoaded, setMenusLoaded] = useState(false);
28
50
  const [pendingStart, setPendingStart] = useState(false);
51
+ const [isTyping, setIsTyping] = useState(false);
52
+ const [scalationStarted, setScalationStarted] = useState(false);
53
+ useEffect(() => {
54
+ if (messages.length === 0) return;
55
+ const hasScalation = messages.some(
56
+ (msg) => msg.$userType === "user" || ["escalationAccepted", "escalationStarted"].includes(
57
+ msg.event
58
+ )
59
+ );
60
+ setScalationStarted(hasScalation);
61
+ return () => {
62
+ setScalationStarted(false);
63
+ };
64
+ }, [messages]);
29
65
  const brandMap = /* @__PURE__ */ new Map([
30
66
  ["axos", 1],
31
67
  ["ufb", 3]
@@ -33,8 +69,7 @@ const Chatbot = ({
33
69
  const typingMessage = {
34
70
  $sid: "typing-1",
35
71
  type: "system",
36
- // or a custom type like "typing"
37
- text: "AI is typing...",
72
+ text: scalationStarted ? "Typing" : "AI is typing...",
38
73
  sender: { id: "system", type: "system" },
39
74
  $timestamp: /* @__PURE__ */ new Date(),
40
75
  $userType: "system",
@@ -77,13 +112,44 @@ const Chatbot = ({
77
112
  };
78
113
  const onChatMessageHandler = async (message) => {
79
114
  console.log("Received message:", message);
80
- addMessage(message);
81
- if (!["virtual_agent", "system"].includes(message.$userType)) {
82
- addMessage(typingMessage);
115
+ const { event, $userType } = message;
116
+ if (["system", "virtual_agent", "user"].includes($userType) && event === void 0) {
117
+ addMessage(message);
118
+ if (!hasEscalated) {
119
+ unblockInput?.();
120
+ }
121
+ return;
122
+ }
123
+ switch (event) {
124
+ case "escalationAccepted":
125
+ case "escalationStarted":
126
+ setScalationStarted(true);
127
+ startEscalation?.();
128
+ addMessage(message);
129
+ return;
130
+ case "escalationEnded":
131
+ case "escalationFailed": {
132
+ endEscalation?.();
133
+ addMessage(message);
134
+ return;
135
+ }
136
+ default:
137
+ addMessage(message);
138
+ if (["end_user"].includes(message.$userType)) {
139
+ if (!hasEscalated) {
140
+ addMessage(typingMessage);
141
+ }
142
+ }
143
+ return;
83
144
  }
84
145
  };
85
146
  const onChatTypingStartedHandler = async (identity) => {
86
147
  console.log("Typing started by:", identity);
148
+ setIsTyping(true);
149
+ };
150
+ const onChatTypingEndedHandler = async (identity) => {
151
+ console.log("Typing ended by:", identity);
152
+ setIsTyping(false);
87
153
  };
88
154
  const onChatDisconnectedHandler = async () => {
89
155
  console.log("Chat disconnected");
@@ -105,23 +171,47 @@ const Chatbot = ({
105
171
  const onChatMemberLeftHandler = async (identity) => {
106
172
  console.log("Chat member left:", identity);
107
173
  };
174
+ const onChatMemberJoinedHandler = async (identity) => {
175
+ console.log("Chat member joined:", identity);
176
+ };
108
177
  const onChatConnectedHandler = async () => {
109
178
  setStatus("connected");
110
179
  console.log("connected");
111
- const messages2 = await clientRef.current?.fetchMessages();
112
- if (messages2) {
113
- addMessages(messages2);
180
+ try {
181
+ if (!clientRef.current) {
182
+ console.error("Client not initialized on chat connected");
183
+ return;
184
+ }
185
+ const messages2 = await clientRef.current?.fetchMessages();
186
+ console.log("Fetched messages on chat connected:", messages2);
187
+ if (messages2) {
188
+ addMessages(messages2);
189
+ const hasEscalation = messages2.some(
190
+ (msg) => msg.$userType === "user" || ["escalationAccepted", "escalationStarted"].includes(
191
+ msg.event
192
+ )
193
+ );
194
+ console.log(hasEscalation);
195
+ if (hasEscalation) {
196
+ setScalationStarted(true);
197
+ startEscalation?.();
198
+ }
199
+ }
200
+ } catch (error) {
201
+ console.error("Error fetching messages on chat connected:", error);
114
202
  }
115
203
  };
116
204
  const registerEventHandlers = () => {
117
205
  clientRef.current?.on("chat.ongoing", onChatOngoingHandler);
118
206
  clientRef.current?.on("chat.message", onChatMessageHandler);
119
207
  clientRef.current?.on("chat.typingStarted", onChatTypingStartedHandler);
208
+ clientRef.current?.on("chat.typingEnded", onChatTypingEndedHandler);
120
209
  clientRef.current?.on("chat.disconnected", onChatDisconnectedHandler);
121
210
  clientRef.current?.on("chat.dismissed", onDismissedHandler);
122
211
  clientRef.current?.on("chat.timeout", onTimeoutHandler);
123
212
  clientRef.current?.on("chat.ended", onEndedHandler);
124
213
  clientRef.current?.on("chat.destroyed", onDestroyedHandler);
214
+ clientRef.current?.on("chat.memberJoined", onChatMemberJoinedHandler);
125
215
  clientRef.current?.on("chat.memberLeft", onChatMemberLeftHandler);
126
216
  clientRef?.current?.on("chat.connected", onChatConnectedHandler);
127
217
  };
@@ -131,12 +221,14 @@ const Chatbot = ({
131
221
  clientRef.current?.off("chat.ongoing", onDismissedHandler);
132
222
  clientRef.current?.off("chat.message", onChatMessageHandler);
133
223
  clientRef.current?.off("chat.typingStarted", onChatTypingStartedHandler);
224
+ clientRef.current?.off("chat.typingEnded", onChatTypingEndedHandler);
134
225
  clientRef.current?.off("chat.disconnected", onChatDisconnectedHandler);
135
226
  clientRef.current?.off("chat.dismissed", onDismissedHandler);
136
227
  clientRef.current?.off("chat.timeout", onTimeoutHandler);
137
228
  clientRef.current?.off("chat.ended", onEndedHandler);
138
229
  clientRef.current?.off("chat.destroyed", onDestroyedHandler);
139
230
  clientRef.current?.off("chat.memberLeft", onChatMemberLeftHandler);
231
+ clientRef.current?.off("chat.memberJoined", onChatMemberJoinedHandler);
140
232
  clientRef.current?.off("chat.connected", onChatConnectedHandler);
141
233
  };
142
234
  const createClient = async () => {
@@ -146,10 +238,9 @@ const Chatbot = ({
146
238
  }
147
239
  if (clientRef.current) return;
148
240
  const client = new Client({
149
- companyId: process.env.CCAI_COMPANY_ID || "",
150
- tenant: process.env.CCAI_TENANT_NAME || "",
151
- host: process.env.CCAI_HOST || "",
152
- // or your region
241
+ companyId: env.VITE_COMPANY_ID || env.CCAI_COMPANY_ID || "",
242
+ tenant: env.VITE_TENANT_NAME || env.CCAI_TENANT_NAME || "",
243
+ host: env.VITE_HOST || env.CCAI_HOST || "",
153
244
  authenticate
154
245
  });
155
246
  client?.on("ready", onReadyHandler);
@@ -196,6 +287,17 @@ const Chatbot = ({
196
287
  }
197
288
  } catch (err) {
198
289
  console.error("Error creating chat:", err);
290
+ } finally {
291
+ if (clientRef?.current?.chat?.state?.status == "va_assigned") {
292
+ const OriginalAudio = window.Audio;
293
+ class PatchedAudio extends OriginalAudio {
294
+ constructor(src) {
295
+ const newSrc = src === "https://websdk.ujet.co/v3/ping.mp3" ? notificationSound : src;
296
+ super(newSrc);
297
+ }
298
+ }
299
+ window.Audio = PatchedAudio;
300
+ }
199
301
  }
200
302
  };
201
303
  const handleClick = async () => {
@@ -210,9 +312,17 @@ const Chatbot = ({
210
312
  setHasStarted(true);
211
313
  }
212
314
  };
213
- const onSendMessage = (msg) => {
315
+ const onSendMessage = async (msg) => {
214
316
  console.log("Sending message:", msg);
215
- clientRef.current?.sendTextMessage(msg);
317
+ try {
318
+ await clientRef.current?.sendTextMessage(msg);
319
+ } catch (error) {
320
+ console.log(error);
321
+ } finally {
322
+ if (!hasEscalated) {
323
+ blockInput?.();
324
+ }
325
+ }
216
326
  };
217
327
  const onEndChat = async () => {
218
328
  console.log("Ending chat");
@@ -223,6 +333,7 @@ const Chatbot = ({
223
333
  chatRef.current = null;
224
334
  console.log("Chat ended");
225
335
  setHasStarted(false);
336
+ endEscalation?.();
226
337
  }
227
338
  };
228
339
  const onEndAndStartNewChat = async () => {
@@ -251,6 +362,7 @@ const Chatbot = ({
251
362
  setHasStarted(false);
252
363
  setStatus("idle");
253
364
  clearMessages();
365
+ endEscalation?.();
254
366
  clientRef.current?.destroy();
255
367
  clientRef.current?.destroyChat();
256
368
  clientRef.current = null;
@@ -262,22 +374,41 @@ const Chatbot = ({
262
374
  reset();
263
375
  setHasStarted(false);
264
376
  };
265
- return /* @__PURE__ */ jsxs("div", { className: project === "ufb" ? chatbotUFB : chatbotAXB, children: [
266
- /* @__PURE__ */ jsx(Bubble, { onClick: handleClick }),
267
- /* @__PURE__ */ jsx(
268
- ChatWindow,
269
- {
270
- status,
271
- virtualAgent: agent_virtual.current,
272
- messages,
273
- onSend: onSendMessage,
274
- endChat: onEndChat,
275
- onClose,
276
- onNewChat: onEndAndStartNewChat,
277
- onCloseAfterThankYou
377
+ const onPreviewTyping = async (msg) => {
378
+ console.log("Preview typing message:", msg);
379
+ try {
380
+ if (clientRef.current) {
381
+ chatRef.current?.startTyping();
382
+ await clientRef.current?.sendPreviewMessage(msg);
278
383
  }
279
- )
280
- ] });
384
+ } catch (error) {
385
+ console.error("Error sending preview message:", error);
386
+ }
387
+ };
388
+ return menusLoaded && /* @__PURE__ */ jsxs(
389
+ "div",
390
+ {
391
+ className: ["axos", "Axos"].includes(project) ? chatbotAXB : chatbotUFB,
392
+ children: [
393
+ /* @__PURE__ */ jsx(Bubble, { onClick: handleClick, project }),
394
+ /* @__PURE__ */ jsx(
395
+ ChatWindow,
396
+ {
397
+ status,
398
+ virtualAgent: agent_virtual.current,
399
+ messages,
400
+ onSend: onSendMessage,
401
+ endChat: onEndChat,
402
+ onClose,
403
+ onNewChat: onEndAndStartNewChat,
404
+ onCloseAfterThankYou,
405
+ previewTyping: onPreviewTyping,
406
+ isTyping
407
+ }
408
+ )
409
+ ]
410
+ }
411
+ );
281
412
  };
282
413
  export {
283
414
  Chatbot
@@ -11,6 +11,8 @@ interface ChatbotMessageProps {
11
11
  virtualAgent?: VirtualAgent | null;
12
12
  onCancelEndChat?: () => void;
13
13
  onSend?: (content: string) => void;
14
+ onEndChat?: () => void;
15
+ inputRef: React.RefObject<HTMLTextAreaElement | null>;
14
16
  }
15
17
  export declare const ChatbotMessage: FC<ChatbotMessageProps>;
16
18
  export {};
@@ -9,7 +9,8 @@ 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, trMortgageTable, tableCell, tableHead, tableMsg, messageStyle, user_msg, agent_msg, inline_button_wrapper, inline_button, endChatButtonStyle } from "./ChatWindow.css.js";
13
+ import { useOpenChat } from "./store/chat.js";
13
14
  function timeAgo(date) {
14
15
  const seconds = Math.floor(((/* @__PURE__ */ new Date()).getTime() - date.getTime()) / 1e3);
15
16
  if (seconds < 60) return "Just now";
@@ -18,14 +19,41 @@ function timeAgo(date) {
18
19
  minute: "2-digit"
19
20
  });
20
21
  }
22
+ function convertBulletsToTable(text) {
23
+ const lines = text.split("\n");
24
+ const header = lines[0];
25
+ const bulletLines = lines.filter((line) => line.trim().startsWith("•"));
26
+ if (bulletLines.length === 0) return text;
27
+ const fields = bulletLines.map((line) => {
28
+ const [field] = line.split(":");
29
+ const cleanField = field.replace(/•\s*\*\*|\*\*/g, "").trim();
30
+ return cleanField;
31
+ });
32
+ const values = bulletLines.map((line) => {
33
+ const [, value] = line.split(":");
34
+ return value.trim();
35
+ });
36
+ const headerRow = `| ${fields.join(" | ")} |`;
37
+ const separatorRow = `| ${fields.map(() => "-------").join(" | ")} |`;
38
+ const valueRow = `| ${values.join(" | ")} |`;
39
+ return `
40
+ ### ${header}
41
+
42
+ ${headerRow}
43
+ ${separatorRow}
44
+ ${valueRow}
45
+ `;
46
+ }
21
47
  const ChatbotMessage = ({
22
48
  msg,
23
49
  showAvatar,
24
50
  showName,
25
51
  virtualAgent,
26
- onCancelEndChat,
27
- onSend
52
+ onEndChat,
53
+ onSend,
54
+ inputRef
28
55
  }) => {
56
+ const { hasEscalated } = useOpenChat();
29
57
  const [timeText, setTimeText] = useState(timeAgo(msg.$timestamp));
30
58
  useEffect(() => {
31
59
  const interval = setInterval(() => {
@@ -33,7 +61,10 @@ const ChatbotMessage = ({
33
61
  }, 3e4);
34
62
  return () => clearInterval(interval);
35
63
  }, [msg.$timestamp]);
36
- if (msg.$sid === "typing-1") {
64
+ if (msg.$sid === "typing-1" && !hasEscalated) {
65
+ if (inputRef?.current) {
66
+ inputRef?.current.focus();
67
+ }
37
68
  return /* @__PURE__ */ jsx(
38
69
  "div",
39
70
  {
@@ -62,6 +93,7 @@ const ChatbotMessage = ({
62
93
  }
63
94
  );
64
95
  }
96
+ const checkInformationMortgage = typeof msg.content == "string" ? convertBulletsToTable(msg.content) : "";
65
97
  return /* @__PURE__ */ jsxs(Fragment, { children: [
66
98
  msg.type == "noti" && msg.$userType == "system" && msg.event == "escalationStarted" && /* @__PURE__ */ jsx("div", { className: notificationStyle, children: "We are connecting you with a human agent..." }, msg.$index),
67
99
  msg.type == "noti" && msg.$userType == "system" && msg.event == "memberLeft" && /* @__PURE__ */ jsxs("div", { className: notificationStyle, children: [
@@ -73,23 +105,20 @@ const ChatbotMessage = ({
73
105
  " ",
74
106
  msg.to_agent ? /* @__PURE__ */ jsx("strong", { children: msg?.to_agent?.name }) : "an agent"
75
107
  ] }, msg.$index),
76
- msg.type == "noti" && msg.$userType == "virtual_agent" && msg.event == "escalationDeflected" && /* @__PURE__ */ jsxs(Fragment, { children: [
77
- /* @__PURE__ */ jsxs(
78
- "div",
79
- {
80
- className: notificationStyle,
81
- style: { fontSize: 12 },
82
- children: [
83
- "Our chat team is available weekdays, 8am-5pm, except federal bank holidays. For immediate assistance you can reach out to us at",
84
- " ",
85
- /* @__PURE__ */ jsx("a", { href: "tel:1-888-502-2967", children: "1-888-502-2967" }),
86
- "."
87
- ]
88
- },
89
- msg.$index
90
- ),
91
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: 12 }, children: /* @__PURE__ */ jsx("button", { className: endChatButtonStyle, onClick: onCancelEndChat, children: "End Chat" }) })
92
- ] }),
108
+ msg.type == "noti" && msg.$userType == "virtual_agent" && msg.event == "escalationDeflected" && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
109
+ "div",
110
+ {
111
+ className: notificationStyle,
112
+ style: { fontSize: 12 },
113
+ children: [
114
+ "Our chat team is available weekdays, 8am-5pm, except federal bank holidays. For immediate assistance you can reach out to us at",
115
+ " ",
116
+ /* @__PURE__ */ jsx("a", { href: "tel:1-888-502-2967", children: "1-888-502-2967" }),
117
+ "."
118
+ ]
119
+ },
120
+ msg.$index
121
+ ) }),
93
122
  ["text", "markdown_template", "markdown"].includes(msg.type) && /* @__PURE__ */ jsx(
94
123
  "div",
95
124
  {
@@ -145,9 +174,22 @@ const ChatbotMessage = ({
145
174
  ...props
146
175
  }
147
176
  ),
148
- a: ({ ...props }) => /* @__PURE__ */ jsx("a", { style: { wordBreak: "break-word" }, ...props })
177
+ a: ({ ...props }) => /* @__PURE__ */ jsx("a", { style: { wordBreak: "break-word" }, ...props }),
178
+ table: ({ node, ...props }) => /* @__PURE__ */ jsx("div", { style: { overflowX: "auto", marginTop: 4 }, children: /* @__PURE__ */ jsx(
179
+ "table",
180
+ {
181
+ ...props,
182
+ className: clsx(tableMsg),
183
+ style: { tableLayout: "fixed" }
184
+ }
185
+ ) }),
186
+ th: ({ node, ...props }) => /* @__PURE__ */ jsx("th", { ...props, className: clsx(tableHead) }),
187
+ td: ({ node, ...props }) => /* @__PURE__ */ jsx("td", { ...props, className: clsx(tableCell) }),
188
+ tr: ({ node, ...props }) => {
189
+ return /* @__PURE__ */ jsx("tr", { className: clsx(trMortgageTable), ...props });
190
+ }
149
191
  },
150
- children: msg.content
192
+ children: msg?.content?.includes("Does this information look correct?") ? checkInformationMortgage : msg.content
151
193
  }
152
194
  ) }) : /* @__PURE__ */ jsx(
153
195
  "div",
@@ -178,7 +220,28 @@ const ChatbotMessage = ({
178
220
  index
179
221
  );
180
222
  }) }),
181
- msg.event == "chatEnded" && /* @__PURE__ */ jsxs(Fragment, { children: [
223
+ " ",
224
+ msg.event == "chatEnded" && msg.status == "failed" && /* @__PURE__ */ jsxs(Fragment, { children: [
225
+ /* @__PURE__ */ jsxs(
226
+ "div",
227
+ {
228
+ title: (/* @__PURE__ */ new Date()).toLocaleString(),
229
+ style: {
230
+ fontSize: 12,
231
+ color: "#888",
232
+ marginBottom: 4,
233
+ textAlign: "center"
234
+ },
235
+ children: [
236
+ "No team members are online at the moment.",
237
+ /* @__PURE__ */ jsx("br", {}),
238
+ " Please try again later."
239
+ ]
240
+ }
241
+ ),
242
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: 12 }, children: /* @__PURE__ */ jsx("button", { className: endChatButtonStyle, onClick: onEndChat, children: "End Chat" }) })
243
+ ] }),
244
+ msg.event == "chatEnded" && msg.status != "failed" && /* @__PURE__ */ jsxs(Fragment, { children: [
182
245
  /* @__PURE__ */ jsxs(
183
246
  "div",
184
247
  {
@@ -196,7 +259,7 @@ const ChatbotMessage = ({
196
259
  ]
197
260
  }
198
261
  ),
199
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: 12 }, children: /* @__PURE__ */ jsx("button", { className: endChatButtonStyle, onClick: onCancelEndChat, children: "End Chat" }) })
262
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: 12 }, children: /* @__PURE__ */ jsx("button", { className: endChatButtonStyle, onClick: onEndChat, children: "End Chat" }) })
200
263
  ] }),
201
264
  msg.type == "text" && /* @__PURE__ */ jsx(
202
265
  "div",
@@ -4,7 +4,7 @@ import { borderHoverGradient, bubbleButton, bubbleText, bubbleWrapper, inner, sv
4
4
  import { Chatbot } from "./Chatbot.js";
5
5
  import { chatbotAXB, chatbotUFB } from "./Chatbot.css.js";
6
6
  import { ChatWindow } from "./ChatWindow.js";
7
- import { agent_msg, arrowFill, autoResize, button_bar, button_reset, buttonss_section, chatEndCircle, chatEndDialogOverlay, chatFinishDialog, chatNetworkStatus, chat_title, chatbotMenu, chatbotMenuItem, endChatButtonStyle, inline_button, inline_button_wrapper, inputStyle, left_bar_section, messageStyle, messagesContainerStyle, noAnswerButton, notificationStyle, sendButtonStyle, shimmerText, thankyou_image, thankyou_message, thankyou_overlay, user_msg, windowBarStyle, windowOpenStyle, windowStyle } from "./ChatWindow.css.js";
7
+ import { agent_msg, arrowFill, autoResize, button_bar, button_reset, buttonss_section, chatEndCircle, chatEndDialogOverlay, chatFinishDialog, chatNetworkStatus, chat_title, chatbotMenu, chatbotMenuItem, endChatButtonStyle, inline_button, inline_button_wrapper, inputStyle, left_bar_section, messageStyle, messagesContainerStyle, noAnswerButton, notificationStyle, sendButtonStyle, shimmerText, tableCell, tableHead, tableMsg, thankyou_image, thankyou_message, thankyou_overlay, trMortgageTable, user_msg, windowBarStyle, windowOpenStyle, windowStyle } from "./ChatWindow.css.js";
8
8
  import { useOpenChat } from "./store/chat.js";
9
9
  import { useMessages } from "./store/messages.js";
10
10
  export {
@@ -43,9 +43,13 @@ export {
43
43
  sendButtonStyle,
44
44
  shimmerText,
45
45
  svgFill,
46
+ tableCell,
47
+ tableHead,
48
+ tableMsg,
46
49
  thankyou_image,
47
50
  thankyou_message,
48
51
  thankyou_overlay,
52
+ trMortgageTable,
49
53
  useMessages,
50
54
  useOpenChat,
51
55
  user_msg,
@@ -8,6 +8,12 @@ interface OpenChatState {
8
8
  showThankyouMessage: boolean;
9
9
  displayThankyouMessage: () => void;
10
10
  toggleThankyouMessage?: () => void;
11
+ hasEscalated?: boolean;
12
+ startEscalation?: () => void;
13
+ endEscalation?: () => void;
14
+ isBlockedInput?: boolean;
15
+ blockInput?: () => void;
16
+ unblockInput?: () => void;
11
17
  }
12
18
  export declare const useOpenChat: import('zustand').UseBoundStore<import('zustand').StoreApi<OpenChatState>>;
13
19
  export {};
@@ -3,6 +3,7 @@ const useOpenChat = create((set, get) => ({
3
3
  isOpen: false,
4
4
  hasOpenedOnce: false,
5
5
  showThankyouMessage: false,
6
+ hasEscalated: false,
6
7
  toggle: () => set((state) => ({ isOpen: !state.isOpen, hasOpenedOnce: true })),
7
8
  open: () => {
8
9
  const alreadyOpened = get().hasOpenedOnce;
@@ -12,9 +13,20 @@ const useOpenChat = create((set, get) => ({
12
13
  });
13
14
  },
14
15
  close: () => set({ isOpen: false }),
15
- reset: () => set({ hasOpenedOnce: false, isOpen: false, showThankyouMessage: false }),
16
+ reset: () => set({
17
+ hasOpenedOnce: false,
18
+ isOpen: false,
19
+ showThankyouMessage: false,
20
+ hasEscalated: false,
21
+ isBlockedInput: false
22
+ }),
16
23
  displayThankyouMessage: () => set({ showThankyouMessage: true }),
17
- toggleThankyouMessage: () => set((state) => ({ showThankyouMessage: !state.showThankyouMessage }))
24
+ toggleThankyouMessage: () => set((state) => ({ showThankyouMessage: !state.showThankyouMessage })),
25
+ startEscalation: () => set({ hasEscalated: true }),
26
+ endEscalation: () => set({ hasEscalated: false }),
27
+ isBlockedInput: false,
28
+ blockInput: () => set({ isBlockedInput: true }),
29
+ unblockInput: () => set({ isBlockedInput: false })
18
30
  }));
19
31
  export {
20
32
  useOpenChat
@@ -6,6 +6,7 @@ interface MessageStore {
6
6
  removeMessage: (id: string) => void;
7
7
  addMessages: (newMessages: MessageResponse[]) => void;
8
8
  clearMessages: () => void;
9
+ isEscalated: boolean;
9
10
  }
10
11
  export interface Message {
11
12
  id: string;
@@ -1,5 +1,5 @@
1
1
  import { create } from "zustand";
2
- const useMessages = create((set) => ({
2
+ const useMessages = create((set, get) => ({
3
3
  messages: [],
4
4
  addMessage: (message) => set((state) => {
5
5
  const cleaned = state.messages.filter((m) => m.$sid !== "typing-1");
@@ -11,7 +11,10 @@ const useMessages = create((set) => ({
11
11
  )
12
12
  })),
13
13
  addMessages: (newMessages) => set((state) => ({ messages: [...state.messages, ...newMessages] })),
14
- clearMessages: () => set({ messages: [] })
14
+ clearMessages: () => set({ messages: [] }),
15
+ isEscalated: get()?.messages?.some(
16
+ (msg) => ["escalationAccepted", "escalationStarted"].includes(msg.event)
17
+ )
15
18
  }));
16
19
  export {
17
20
  useMessages