Comments, appointments adjustments, fixed some issues

This commit is contained in:
augmentedpotato
2026-04-20 19:19:30 -06:00
parent d3b9c51952
commit 2cb0a94bbb
34 changed files with 402 additions and 104 deletions

View File

@@ -4,15 +4,18 @@ import { createContext, useContext, useState, useRef, useCallback, useEffect } f
import { createStompClient } from "@/lib/chatSocket";
import { useAuth } from "@/context/AuthContext";
//Chat widget context
//Manages both the AI chat and the live support chat
const ChatWidgetContext = createContext(null);
const API_BASE = "";
//Provides chat state and actions for the floating chat widget
export function ChatWidgetProvider({ children }) {
const { user } = useAuth();
const [isOpen, setIsOpen] = useState(false);
const [view, setView] = useState("ai"); // "ai" | "history" | "live"
// AI chat
//AI chat messages, loaded from localStorage so they survive page refreshes
const [aiMessages, setAiMessages] = useState(() => {
try {
const saved = localStorage.getItem("fc_aiMessages");
@@ -22,15 +25,16 @@ export function ChatWidgetProvider({ children }) {
const [aiSending, setAiSending] = useState(false);
const [aiError, setAiError] = useState(null);
// Persist aiMessages to localStorage
//Save AI messages to localStorage whenever they change
useEffect(() => {
localStorage.setItem("fc_aiMessages", JSON.stringify(aiMessages));
}, [aiMessages]);
// Keep a ref so sendAiMessage stays stable (no stale-closure over messages)
//Ref to the latest messages so the send function always sees current state
const aiMessagesRef = useRef(aiMessages);
useEffect(() => { aiMessagesRef.current = aiMessages; }, [aiMessages]);
//Sends a message to the AI and appends the response to the chat
const sendAiMessage = useCallback(async (text, token) => {
if (!text.trim() || !token) return;
const userMsg = { role: "user", content: text, id: Date.now() };
@@ -54,7 +58,7 @@ export function ChatWidgetProvider({ children }) {
}
}, []);
// Live chat
//Live chat state
const [conversations, setConversations] = useState([]);
const [convsLoading, setConvsLoading] = useState(false);
const [activeConvId, setActiveConvId] = useState(null);
@@ -67,6 +71,7 @@ export function ChatWidgetProvider({ children }) {
const activeConvIdRef = useRef(null);
const tokenRef = useRef(null);
//Disconnects the WebSocket if it is active
const disconnectStomp = useCallback(() => {
if (stompRef.current) {
stompRef.current.deactivate();
@@ -74,6 +79,7 @@ export function ChatWidgetProvider({ children }) {
}
}, []);
//Clears all chat state when the user logs out or switches accounts
const prevUserIdRef = useRef(user?.id);
useEffect(() => {
const currentId = user?.id ?? null;
@@ -92,6 +98,7 @@ export function ChatWidgetProvider({ children }) {
}
}, [user?.id, disconnectStomp]);
//Subscribes to incoming messages and conversation updates for a given chat
const subscribeToConversation = useCallback((client, convId) => {
client.subscribe(`/topic/chat/conversations/${convId}`, (frame) => {
try {
@@ -172,6 +179,7 @@ export function ChatWidgetProvider({ children }) {
}
}, [liveSending]);
//Creates a new live chat conversation and requests a human agent
const startLiveChat = useCallback(async (token) => {
if (!token || switchingToHuman) return;
setSwitchingToHuman(true);
@@ -228,6 +236,7 @@ export function ChatWidgetProvider({ children }) {
);
}
//Hook to access chat widget state - must be used inside a ChatWidgetProvider
export function useChatWidget() {
const ctx = useContext(ChatWidgetContext);
if (!ctx) throw new Error("useChatWidget must be used within ChatWidgetProvider");