@gobolt/genesis 0.3.3 → 0.3.5

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.
@@ -1,4 +1,3 @@
1
- import { FC } from 'react';
2
1
  import { default as Message } from './Message';
3
2
  type Message = {
4
3
  id: string;
@@ -6,6 +5,17 @@ type Message = {
6
5
  sender: string;
7
6
  isThinking?: boolean;
8
7
  timestamp: string;
8
+ respondedBy?: "ai" | "search";
9
+ };
10
+ export type ChatHistoryRecord = {
11
+ visitorId: string;
12
+ visitorEmail: string;
13
+ name: string;
14
+ question: string;
15
+ response: string;
16
+ timeToRespond: number;
17
+ createdAt: string;
18
+ responseBy: "search" | "ai";
9
19
  };
10
20
  export interface ChatProps {
11
21
  socketUrl: string;
@@ -13,6 +23,9 @@ export interface ChatProps {
13
23
  messageHistory: Array<Message>;
14
24
  title?: string;
15
25
  isSimulated?: boolean;
26
+ authToken?: string;
27
+ overrideStyle?: React.CSSProperties;
28
+ onChange?: (chatHistoryRecord: ChatHistoryRecord) => void;
16
29
  }
17
- declare const Chat: FC<ChatProps>;
30
+ declare const Chat: ({ socketUrl, isOpen, messageHistory, title, isSimulated, authToken, overrideStyle, onChange, }: ChatProps) => import("react/jsx-runtime").JSX.Element;
18
31
  export default Chat;
@@ -1,7 +1,7 @@
1
1
  import { StoryObj } from '@storybook/react';
2
2
  declare const meta: {
3
3
  title: string;
4
- component: import('react').FC<import('..').ChatProps>;
4
+ component: ({ socketUrl, isOpen, messageHistory, title, isSimulated, authToken, overrideStyle, onChange, }: import('..').ChatProps) => import("react/jsx-runtime").JSX.Element;
5
5
  parameters: {
6
6
  layout: string;
7
7
  docs: {
@@ -14,6 +14,8 @@ declare const meta: {
14
14
  };
15
15
  export default meta;
16
16
  type Story = StoryObj<typeof meta>;
17
- export declare const Default: Story;
17
+ export declare const local: Story;
18
+ export declare const remote: Story;
18
19
  export declare const WithMessageHistory: Story;
19
20
  export declare const WithTitle: Story;
21
+ export declare const Remote: Story;
package/dist/index.cjs CHANGED
@@ -75336,7 +75336,8 @@ const ChatContainer = styled.div`
75336
75336
  display: flex;
75337
75337
  flex-direction: column;
75338
75338
  position: relative;
75339
- width: 600px;
75339
+ width: "100%";
75340
+ max-width: "800px";
75340
75341
  overflow: hidden;
75341
75342
  `;
75342
75343
  const HeroContainer = styled.div`
@@ -75386,7 +75387,10 @@ const Chat = ({
75386
75387
  isOpen = false,
75387
75388
  messageHistory = [],
75388
75389
  title = null,
75389
- isSimulated = false
75390
+ isSimulated = false,
75391
+ authToken,
75392
+ overrideStyle,
75393
+ onChange
75390
75394
  }) => {
75391
75395
  const [isChatOpen, setIsChatOpen] = React.useState(isOpen);
75392
75396
  const [message2, setMessage] = React.useState("");
@@ -75398,108 +75402,137 @@ const Chat = ({
75398
75402
  const serverReadyRef = React.useRef(false);
75399
75403
  const handle = "user";
75400
75404
  const [isLocked, setIsLocked] = React.useState(false);
75405
+ const [messageStartTime, setMessageStartTime] = React.useState(null);
75406
+ const [currentQuestion, setCurrentQuestion] = React.useState("");
75401
75407
  React.useEffect(() => {
75402
75408
  if (isSimulated) return;
75403
75409
  const socketUrlToUse = window.location.hostname === "localhost" && window.location.port === "6006" ? "http://localhost:3000" : socketUrl;
75404
75410
  console.log("Connecting to socket server at:", socketUrlToUse);
75405
- socketRef.current = lookup(socketUrlToUse, {
75406
- transports: ["polling", "websocket"],
75407
- reconnection: true,
75408
- reconnectionAttempts: 5,
75409
- reconnectionDelay: 1e3,
75410
- withCredentials: true,
75411
- forceNew: true,
75412
- autoConnect: true,
75413
- timeout: 1e4
75414
- });
75415
- const socket = socketRef.current;
75416
- socket.on("connect", () => {
75417
- console.log("Socket connected successfully");
75418
- setServerError("");
75419
- setServerStatus("ready");
75420
- serverReadyRef.current = true;
75421
- });
75422
- socket.on("connect_error", (error2) => {
75423
- console.error("Socket connection error:", error2);
75424
- setServerError(`Connection error: ${error2.message}`);
75425
- setServerStatus("error");
75426
- serverReadyRef.current = false;
75427
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75428
- setIsLocked(false);
75429
- });
75430
- socket.on("disconnect", (reason) => {
75431
- console.log("Socket disconnected:", reason);
75432
- setServerError(`Disconnected: ${reason}`);
75433
- setServerStatus("error");
75434
- serverReadyRef.current = false;
75435
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75436
- setIsLocked(false);
75437
- });
75438
- socket.on("new connection", () => {
75439
- console.log("New connection established");
75440
- });
75441
- socket.on("server-ready", () => {
75442
- console.log("Server is ready");
75443
- setServerError("");
75444
- setServerStatus("ready");
75445
- serverReadyRef.current = true;
75446
- });
75447
- socket.on("message", (newMessage) => {
75448
- setMessages((prev2) => {
75449
- if (newMessage.sender === "bot") {
75450
- if (newMessage.content === "Processing your message...") {
75451
- const hasThinkingMessage = prev2.some((msg) => msg.isThinking);
75452
- if (hasThinkingMessage) {
75453
- return prev2;
75411
+ const validateToken = async () => {
75412
+ try {
75413
+ const response = await fetch(
75414
+ "https://www.googleapis.com/oauth2/v2/userinfo",
75415
+ {
75416
+ headers: {
75417
+ Authorization: `Bearer ${authToken}`
75454
75418
  }
75455
- return [...prev2, { ...newMessage, isThinking: true }];
75456
75419
  }
75457
- const thinkingMessage = prev2.find((msg) => msg.isThinking);
75458
- if (thinkingMessage) {
75459
- return prev2.map(
75460
- (msg) => msg.isThinking ? { ...newMessage, isThinking: false } : msg
75420
+ );
75421
+ if (!response.ok) {
75422
+ throw new Error("Invalid token");
75423
+ }
75424
+ socketRef.current = lookup(socketUrlToUse, {
75425
+ transports: ["polling", "websocket"],
75426
+ reconnection: true,
75427
+ reconnectionAttempts: 5,
75428
+ reconnectionDelay: 1e3,
75429
+ withCredentials: true,
75430
+ forceNew: true,
75431
+ autoConnect: true,
75432
+ timeout: 1e4,
75433
+ auth: {
75434
+ token: authToken,
75435
+ type: "Bearer"
75436
+ }
75437
+ });
75438
+ const socket = socketRef.current;
75439
+ socket.on("connect", () => {
75440
+ console.log("Socket connected successfully");
75441
+ setServerError("");
75442
+ setServerStatus("ready");
75443
+ serverReadyRef.current = true;
75444
+ });
75445
+ socket.on("connect_error", (error2) => {
75446
+ console.error("Socket connection error:", error2);
75447
+ setServerError(`Connection error: ${error2.message}`);
75448
+ setServerStatus("error");
75449
+ serverReadyRef.current = false;
75450
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75451
+ setIsLocked(false);
75452
+ });
75453
+ socket.on("disconnect", (reason) => {
75454
+ console.log("Socket disconnected:", reason);
75455
+ setServerError(`Disconnected: ${reason}`);
75456
+ setServerStatus("error");
75457
+ serverReadyRef.current = false;
75458
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75459
+ setIsLocked(false);
75460
+ });
75461
+ socket.on("new connection", () => {
75462
+ console.log("New connection established");
75463
+ });
75464
+ socket.on("server-ready", () => {
75465
+ console.log("Server is ready");
75466
+ setServerError("");
75467
+ setServerStatus("ready");
75468
+ serverReadyRef.current = true;
75469
+ });
75470
+ socket.on("message", (newMessage) => {
75471
+ setMessages((prev2) => {
75472
+ if (newMessage.sender === "bot") {
75473
+ if (newMessage.content === "Processing your message...") {
75474
+ const hasThinkingMessage = prev2.some((msg) => msg.isThinking);
75475
+ if (hasThinkingMessage) {
75476
+ return prev2;
75477
+ }
75478
+ return [...prev2, { ...newMessage, isThinking: true }];
75479
+ }
75480
+ const thinkingMessage = prev2.find((msg) => msg.isThinking);
75481
+ if (thinkingMessage) {
75482
+ return prev2.map(
75483
+ (msg) => msg.isThinking ? { ...newMessage, isThinking: false } : msg
75484
+ );
75485
+ }
75486
+ return [...prev2, { ...newMessage, isThinking: false }];
75487
+ }
75488
+ const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75489
+ if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75490
+ return prev2;
75491
+ }
75492
+ return [...prev2, newMessage];
75493
+ });
75494
+ setIsLocked(false);
75495
+ });
75496
+ socket.on("update-bot-message", (updatedData) => {
75497
+ console.log("Received bot message update:", updatedData);
75498
+ setMessages(
75499
+ (prev2) => prev2.map(
75500
+ (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75501
+ )
75502
+ );
75503
+ });
75504
+ socket.on("error", (error2) => {
75505
+ console.error("Socket error:", error2);
75506
+ setServerError("Server error occurred");
75507
+ });
75508
+ socket.onAny((eventName, ...args) => {
75509
+ console.log(`Socket event received: ${eventName}`, args);
75510
+ });
75511
+ const timeoutId = setTimeout(() => {
75512
+ if (!serverReadyRef.current) {
75513
+ console.log("Server status check failed");
75514
+ setServerError(
75515
+ "Server status check failed - please check the server"
75461
75516
  );
75517
+ setServerStatus("error");
75518
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75519
+ setIsLocked(false);
75462
75520
  }
75463
- return [...prev2, { ...newMessage, isThinking: false }];
75464
- }
75465
- const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75466
- if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75467
- return prev2;
75468
- }
75469
- return [...prev2, newMessage];
75470
- });
75471
- setIsLocked(false);
75472
- });
75473
- socket.on("update-bot-message", (updatedData) => {
75474
- console.log("Received bot message update:", updatedData);
75475
- setMessages(
75476
- (prev2) => prev2.map(
75477
- (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75478
- )
75479
- );
75480
- });
75481
- socket.on("error", (error2) => {
75482
- console.error("Socket error:", error2);
75483
- setServerError("Server error occurred");
75484
- });
75485
- socket.onAny((eventName, ...args) => {
75486
- console.log(`Socket event received: ${eventName}`, args);
75487
- });
75488
- const timeoutId = setTimeout(() => {
75489
- if (!serverReadyRef.current) {
75490
- console.log("Server status check failed");
75491
- setServerError("Server status check failed - please check the server");
75521
+ }, 2e3);
75522
+ return () => {
75523
+ console.log("Disconnecting socket");
75524
+ socket.disconnect();
75525
+ clearTimeout(timeoutId);
75526
+ };
75527
+ } catch (error2) {
75528
+ console.error("Token validation error:", error2);
75529
+ setServerError("Authentication error: Invalid token");
75492
75530
  setServerStatus("error");
75493
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75494
- setIsLocked(false);
75531
+ serverReadyRef.current = false;
75495
75532
  }
75496
- }, 2e3);
75497
- return () => {
75498
- console.log("Disconnecting socket");
75499
- socket.disconnect();
75500
- clearTimeout(timeoutId);
75501
75533
  };
75502
- }, [isSimulated, socketUrl]);
75534
+ validateToken();
75535
+ }, [isSimulated, socketUrl, authToken]);
75503
75536
  React.useEffect(() => {
75504
75537
  if (messageListRef.current) {
75505
75538
  messageListRef.current.scrollTo({
@@ -75528,6 +75561,8 @@ const Chat = ({
75528
75561
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
75529
75562
  };
75530
75563
  setIsLocked(true);
75564
+ setMessageStartTime(Date.now());
75565
+ setCurrentQuestion(message2);
75531
75566
  setMessages((prev2) => [...prev2, userMessage]);
75532
75567
  if ((_a = socketRef.current) == null ? void 0 : _a.connected) {
75533
75568
  const botMessageId = `bot_${timestamp}`;
@@ -75562,6 +75597,29 @@ const Chat = ({
75562
75597
  }
75563
75598
  setMessage("");
75564
75599
  };
75600
+ React.useEffect(() => {
75601
+ const lastMessage = messages2.at(-1);
75602
+ if (!lastMessage || !messageStartTime || !currentQuestion) return;
75603
+ if (lastMessage.sender === "bot" && !lastMessage.isThinking) {
75604
+ const timeToRespond = Date.now() - messageStartTime;
75605
+ const chatHistoryRecord = {
75606
+ visitorId: "user",
75607
+ // You might want to get this from props or context
75608
+ visitorEmail: "",
75609
+ // You might want to get this from props or context
75610
+ name: handle,
75611
+ question: currentQuestion,
75612
+ response: lastMessage.content,
75613
+ timeToRespond,
75614
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
75615
+ responseBy: lastMessage.respondedBy || "ai"
75616
+ // Use the respondedBy from the message, default to "ai"
75617
+ };
75618
+ onChange == null ? void 0 : onChange(chatHistoryRecord);
75619
+ setMessageStartTime(null);
75620
+ setCurrentQuestion("");
75621
+ }
75622
+ }, [messages2, messageStartTime, currentQuestion, onChange, handle]);
75565
75623
  const toggleChat = () => {
75566
75624
  setIsChatOpen(!isChatOpen);
75567
75625
  };
@@ -75575,9 +75633,9 @@ const Chat = ({
75575
75633
  (msg, index2, self2) => index2 === self2.findIndex((t2) => t2.id === msg.id)
75576
75634
  );
75577
75635
  console.log("uniqueMessages", uniqueMessages);
75578
- return /* @__PURE__ */ jsxRuntime.jsxs(ChatContainer, { children: [
75636
+ return /* @__PURE__ */ jsxRuntime.jsxs(ChatContainer, { style: overrideStyle || {}, children: [
75579
75637
  /* @__PURE__ */ jsxRuntime.jsx(HeroContainer, { $isVisible: !isChatOpen, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
75580
- title ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading3", children: title }) : null,
75638
+ title && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "heading3", children: title }),
75581
75639
  /* @__PURE__ */ jsxRuntime.jsx(Subtitle, { children: "Click the Chat Icon below to begin" }),
75582
75640
  serverError ? /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { children: serverError }) : null
75583
75641
  ] }) }),
package/dist/index.js CHANGED
@@ -75318,7 +75318,8 @@ const ChatContainer = styled.div`
75318
75318
  display: flex;
75319
75319
  flex-direction: column;
75320
75320
  position: relative;
75321
- width: 600px;
75321
+ width: "100%";
75322
+ max-width: "800px";
75322
75323
  overflow: hidden;
75323
75324
  `;
75324
75325
  const HeroContainer = styled.div`
@@ -75368,7 +75369,10 @@ const Chat = ({
75368
75369
  isOpen = false,
75369
75370
  messageHistory = [],
75370
75371
  title = null,
75371
- isSimulated = false
75372
+ isSimulated = false,
75373
+ authToken,
75374
+ overrideStyle,
75375
+ onChange
75372
75376
  }) => {
75373
75377
  const [isChatOpen, setIsChatOpen] = useState(isOpen);
75374
75378
  const [message2, setMessage] = useState("");
@@ -75380,108 +75384,137 @@ const Chat = ({
75380
75384
  const serverReadyRef = useRef(false);
75381
75385
  const handle = "user";
75382
75386
  const [isLocked, setIsLocked] = useState(false);
75387
+ const [messageStartTime, setMessageStartTime] = useState(null);
75388
+ const [currentQuestion, setCurrentQuestion] = useState("");
75383
75389
  useEffect(() => {
75384
75390
  if (isSimulated) return;
75385
75391
  const socketUrlToUse = window.location.hostname === "localhost" && window.location.port === "6006" ? "http://localhost:3000" : socketUrl;
75386
75392
  console.log("Connecting to socket server at:", socketUrlToUse);
75387
- socketRef.current = lookup(socketUrlToUse, {
75388
- transports: ["polling", "websocket"],
75389
- reconnection: true,
75390
- reconnectionAttempts: 5,
75391
- reconnectionDelay: 1e3,
75392
- withCredentials: true,
75393
- forceNew: true,
75394
- autoConnect: true,
75395
- timeout: 1e4
75396
- });
75397
- const socket = socketRef.current;
75398
- socket.on("connect", () => {
75399
- console.log("Socket connected successfully");
75400
- setServerError("");
75401
- setServerStatus("ready");
75402
- serverReadyRef.current = true;
75403
- });
75404
- socket.on("connect_error", (error2) => {
75405
- console.error("Socket connection error:", error2);
75406
- setServerError(`Connection error: ${error2.message}`);
75407
- setServerStatus("error");
75408
- serverReadyRef.current = false;
75409
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75410
- setIsLocked(false);
75411
- });
75412
- socket.on("disconnect", (reason) => {
75413
- console.log("Socket disconnected:", reason);
75414
- setServerError(`Disconnected: ${reason}`);
75415
- setServerStatus("error");
75416
- serverReadyRef.current = false;
75417
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75418
- setIsLocked(false);
75419
- });
75420
- socket.on("new connection", () => {
75421
- console.log("New connection established");
75422
- });
75423
- socket.on("server-ready", () => {
75424
- console.log("Server is ready");
75425
- setServerError("");
75426
- setServerStatus("ready");
75427
- serverReadyRef.current = true;
75428
- });
75429
- socket.on("message", (newMessage) => {
75430
- setMessages((prev2) => {
75431
- if (newMessage.sender === "bot") {
75432
- if (newMessage.content === "Processing your message...") {
75433
- const hasThinkingMessage = prev2.some((msg) => msg.isThinking);
75434
- if (hasThinkingMessage) {
75435
- return prev2;
75393
+ const validateToken = async () => {
75394
+ try {
75395
+ const response = await fetch(
75396
+ "https://www.googleapis.com/oauth2/v2/userinfo",
75397
+ {
75398
+ headers: {
75399
+ Authorization: `Bearer ${authToken}`
75436
75400
  }
75437
- return [...prev2, { ...newMessage, isThinking: true }];
75438
75401
  }
75439
- const thinkingMessage = prev2.find((msg) => msg.isThinking);
75440
- if (thinkingMessage) {
75441
- return prev2.map(
75442
- (msg) => msg.isThinking ? { ...newMessage, isThinking: false } : msg
75402
+ );
75403
+ if (!response.ok) {
75404
+ throw new Error("Invalid token");
75405
+ }
75406
+ socketRef.current = lookup(socketUrlToUse, {
75407
+ transports: ["polling", "websocket"],
75408
+ reconnection: true,
75409
+ reconnectionAttempts: 5,
75410
+ reconnectionDelay: 1e3,
75411
+ withCredentials: true,
75412
+ forceNew: true,
75413
+ autoConnect: true,
75414
+ timeout: 1e4,
75415
+ auth: {
75416
+ token: authToken,
75417
+ type: "Bearer"
75418
+ }
75419
+ });
75420
+ const socket = socketRef.current;
75421
+ socket.on("connect", () => {
75422
+ console.log("Socket connected successfully");
75423
+ setServerError("");
75424
+ setServerStatus("ready");
75425
+ serverReadyRef.current = true;
75426
+ });
75427
+ socket.on("connect_error", (error2) => {
75428
+ console.error("Socket connection error:", error2);
75429
+ setServerError(`Connection error: ${error2.message}`);
75430
+ setServerStatus("error");
75431
+ serverReadyRef.current = false;
75432
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75433
+ setIsLocked(false);
75434
+ });
75435
+ socket.on("disconnect", (reason) => {
75436
+ console.log("Socket disconnected:", reason);
75437
+ setServerError(`Disconnected: ${reason}`);
75438
+ setServerStatus("error");
75439
+ serverReadyRef.current = false;
75440
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75441
+ setIsLocked(false);
75442
+ });
75443
+ socket.on("new connection", () => {
75444
+ console.log("New connection established");
75445
+ });
75446
+ socket.on("server-ready", () => {
75447
+ console.log("Server is ready");
75448
+ setServerError("");
75449
+ setServerStatus("ready");
75450
+ serverReadyRef.current = true;
75451
+ });
75452
+ socket.on("message", (newMessage) => {
75453
+ setMessages((prev2) => {
75454
+ if (newMessage.sender === "bot") {
75455
+ if (newMessage.content === "Processing your message...") {
75456
+ const hasThinkingMessage = prev2.some((msg) => msg.isThinking);
75457
+ if (hasThinkingMessage) {
75458
+ return prev2;
75459
+ }
75460
+ return [...prev2, { ...newMessage, isThinking: true }];
75461
+ }
75462
+ const thinkingMessage = prev2.find((msg) => msg.isThinking);
75463
+ if (thinkingMessage) {
75464
+ return prev2.map(
75465
+ (msg) => msg.isThinking ? { ...newMessage, isThinking: false } : msg
75466
+ );
75467
+ }
75468
+ return [...prev2, { ...newMessage, isThinking: false }];
75469
+ }
75470
+ const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75471
+ if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75472
+ return prev2;
75473
+ }
75474
+ return [...prev2, newMessage];
75475
+ });
75476
+ setIsLocked(false);
75477
+ });
75478
+ socket.on("update-bot-message", (updatedData) => {
75479
+ console.log("Received bot message update:", updatedData);
75480
+ setMessages(
75481
+ (prev2) => prev2.map(
75482
+ (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75483
+ )
75484
+ );
75485
+ });
75486
+ socket.on("error", (error2) => {
75487
+ console.error("Socket error:", error2);
75488
+ setServerError("Server error occurred");
75489
+ });
75490
+ socket.onAny((eventName, ...args) => {
75491
+ console.log(`Socket event received: ${eventName}`, args);
75492
+ });
75493
+ const timeoutId = setTimeout(() => {
75494
+ if (!serverReadyRef.current) {
75495
+ console.log("Server status check failed");
75496
+ setServerError(
75497
+ "Server status check failed - please check the server"
75443
75498
  );
75499
+ setServerStatus("error");
75500
+ setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75501
+ setIsLocked(false);
75444
75502
  }
75445
- return [...prev2, { ...newMessage, isThinking: false }];
75446
- }
75447
- const lastUserMsg = [...prev2].reverse().find((msg) => msg.sender === "user");
75448
- if (lastUserMsg && lastUserMsg.content === newMessage.content) {
75449
- return prev2;
75450
- }
75451
- return [...prev2, newMessage];
75452
- });
75453
- setIsLocked(false);
75454
- });
75455
- socket.on("update-bot-message", (updatedData) => {
75456
- console.log("Received bot message update:", updatedData);
75457
- setMessages(
75458
- (prev2) => prev2.map(
75459
- (message22) => message22.id === updatedData.id ? { ...updatedData } : message22
75460
- )
75461
- );
75462
- });
75463
- socket.on("error", (error2) => {
75464
- console.error("Socket error:", error2);
75465
- setServerError("Server error occurred");
75466
- });
75467
- socket.onAny((eventName, ...args) => {
75468
- console.log(`Socket event received: ${eventName}`, args);
75469
- });
75470
- const timeoutId = setTimeout(() => {
75471
- if (!serverReadyRef.current) {
75472
- console.log("Server status check failed");
75473
- setServerError("Server status check failed - please check the server");
75503
+ }, 2e3);
75504
+ return () => {
75505
+ console.log("Disconnecting socket");
75506
+ socket.disconnect();
75507
+ clearTimeout(timeoutId);
75508
+ };
75509
+ } catch (error2) {
75510
+ console.error("Token validation error:", error2);
75511
+ setServerError("Authentication error: Invalid token");
75474
75512
  setServerStatus("error");
75475
- setMessages((prev2) => prev2.filter((msg) => !msg.isThinking));
75476
- setIsLocked(false);
75513
+ serverReadyRef.current = false;
75477
75514
  }
75478
- }, 2e3);
75479
- return () => {
75480
- console.log("Disconnecting socket");
75481
- socket.disconnect();
75482
- clearTimeout(timeoutId);
75483
75515
  };
75484
- }, [isSimulated, socketUrl]);
75516
+ validateToken();
75517
+ }, [isSimulated, socketUrl, authToken]);
75485
75518
  useEffect(() => {
75486
75519
  if (messageListRef.current) {
75487
75520
  messageListRef.current.scrollTo({
@@ -75510,6 +75543,8 @@ const Chat = ({
75510
75543
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
75511
75544
  };
75512
75545
  setIsLocked(true);
75546
+ setMessageStartTime(Date.now());
75547
+ setCurrentQuestion(message2);
75513
75548
  setMessages((prev2) => [...prev2, userMessage]);
75514
75549
  if ((_a = socketRef.current) == null ? void 0 : _a.connected) {
75515
75550
  const botMessageId = `bot_${timestamp}`;
@@ -75544,6 +75579,29 @@ const Chat = ({
75544
75579
  }
75545
75580
  setMessage("");
75546
75581
  };
75582
+ useEffect(() => {
75583
+ const lastMessage = messages2.at(-1);
75584
+ if (!lastMessage || !messageStartTime || !currentQuestion) return;
75585
+ if (lastMessage.sender === "bot" && !lastMessage.isThinking) {
75586
+ const timeToRespond = Date.now() - messageStartTime;
75587
+ const chatHistoryRecord = {
75588
+ visitorId: "user",
75589
+ // You might want to get this from props or context
75590
+ visitorEmail: "",
75591
+ // You might want to get this from props or context
75592
+ name: handle,
75593
+ question: currentQuestion,
75594
+ response: lastMessage.content,
75595
+ timeToRespond,
75596
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
75597
+ responseBy: lastMessage.respondedBy || "ai"
75598
+ // Use the respondedBy from the message, default to "ai"
75599
+ };
75600
+ onChange == null ? void 0 : onChange(chatHistoryRecord);
75601
+ setMessageStartTime(null);
75602
+ setCurrentQuestion("");
75603
+ }
75604
+ }, [messages2, messageStartTime, currentQuestion, onChange, handle]);
75547
75605
  const toggleChat = () => {
75548
75606
  setIsChatOpen(!isChatOpen);
75549
75607
  };
@@ -75557,9 +75615,9 @@ const Chat = ({
75557
75615
  (msg, index2, self2) => index2 === self2.findIndex((t2) => t2.id === msg.id)
75558
75616
  );
75559
75617
  console.log("uniqueMessages", uniqueMessages);
75560
- return /* @__PURE__ */ jsxs(ChatContainer, { children: [
75618
+ return /* @__PURE__ */ jsxs(ChatContainer, { style: overrideStyle || {}, children: [
75561
75619
  /* @__PURE__ */ jsx(HeroContainer, { $isVisible: !isChatOpen, children: /* @__PURE__ */ jsxs("div", { children: [
75562
- title ? /* @__PURE__ */ jsx(Typography, { variant: "heading3", children: title }) : null,
75620
+ title && /* @__PURE__ */ jsx(Typography, { variant: "heading3", children: title }),
75563
75621
  /* @__PURE__ */ jsx(Subtitle, { children: "Click the Chat Icon below to begin" }),
75564
75622
  serverError ? /* @__PURE__ */ jsx(ErrorMessage, { children: serverError }) : null
75565
75623
  ] }) }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobolt/genesis",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "genesis design system",
5
5
  "author": "gobolt",
6
6
  "license": "MIT",