diff --git a/app/page.tsx b/app/page.tsx index c9b450f1..c8a3be41 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -15,7 +15,7 @@ import ScrollToTop from '@/components/page/home/featured/scroll-to-top'; import { getFeaturedData } from '@/services/featured.service'; export default async function Home() { - const { featuredData, discoverData, isLoggedIn, isError, userInfo, authToken, focusAreas } = await getPageData(); + const { featuredData, discoverData, isLoggedIn, isError, userInfo, focusAreas } = await getPageData(); if (isError) { return ; @@ -39,8 +39,8 @@ export default async function Home() { - - + + } @@ -80,7 +80,6 @@ const getPageData = async () => { isError, userInfo, isLoggedIn, - authToken, focusAreas: { teamFocusAreas , projectFocusAreas diff --git a/components/core/husky/husky-ai.tsx b/components/core/husky/husky-ai.tsx index f5fcf5d2..da008f6a 100644 --- a/components/core/husky/husky-ai.tsx +++ b/components/core/husky/husky-ai.tsx @@ -26,7 +26,6 @@ interface HuskyAiProps { isLoggedIn: boolean; blogId?: string; onClose?: () => void; - authToken: string; } interface Chat { @@ -42,7 +41,7 @@ const DEFAULT_TAB_ITEMS = [ // This component represents the Husky AI interface, allowing users to interact with the AI in chat or blog modes. -function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose, authToken }: HuskyAiProps) { +function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose }: HuskyAiProps) { const [activeTab, setActiveTab] = useState(DEFAULT_TAB_ITEMS[0].key); const [chats, setChats] = useState(initialChats); const [isLoading, setLoadingStatus] = useState(false); @@ -56,6 +55,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose const chatCnRef = useRef(null); const router = useRouter(); const { trackTabSelection, trackUserPrompt, trackAnswerCopy, trackFollowupQuestionClick, trackQuestionEdit, trackRegenerate, trackCopyUrl, trackFeedbackClick, trackAiResponse } = useHuskyAnalytics(); + const [authToken, setAuthToken] = useState(null); // Handles the selection of a tab in the UI const onTabSelected = (item: string) => { @@ -81,6 +81,24 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose trackAnswerCopy(answer); }; + // update auth token + const updateToken = async () => { + try { + if (!isLoggedIn) { + setAuthToken(null); + return; + } + const { isLoginRequired, newAuthToken } = await getUserCredentialsInfo(); + if (isLoginRequired) { + setAuthToken(null); + return; + } + setAuthToken(newAuthToken); // Update token state + } catch (error) { + console.error('Failed to update token:', error); + } + }; + // Fetches user credentials and handles login state const getUserCredentials = async () => { if (!isLoggedIn) { @@ -133,7 +151,6 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose .optional(), }), onFinish: (data) => { - console.log(data); }, onError: (error) => { console.error(error); @@ -151,6 +168,10 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose return chatUid; }; + const onInitialPromptClicked = (quesObj: any) => { + setChats([{ ...quesObj, isError: false }]); + } + // Handles the event when a prompt is clicked const onPromptClicked = async (question: string) => { try { @@ -158,13 +179,14 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose if (!authToken) { return; } + await updateToken(); const chatUid = checkAndSetPromptId(); setAskingQuestion(question); setAnswerLoadingStatus(true); setActiveTab(DEFAULT_TAB_ITEMS[0].key); setChats((prev:any) => [...prev, { question, - content: "", + answer: "", followupQuestions: [], sources: [], actions: [], @@ -222,10 +244,10 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose setLoginBoxStatus(true); return; } - + await updateToken(); setChats((prev:any) => [...prev, { question, - content: "", + answer: "", followupQuestions: [], sources: [], actions: [], @@ -302,13 +324,14 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose setLoginBoxStatus(true); return; } + await updateToken(); if (activeTab === 'supported-scope') { setChats([]); setActiveTab(DEFAULT_TAB_ITEMS[0].key); } setChats((prev:any) => [...prev, { question:query, - content: "", + answer: "", followupQuestions: [], sources: [], actions: [], @@ -341,6 +364,21 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose }; useEffect(() => { + if(error) { + setChats((prev:any) => { + const newMessages = [...prev]; + + // Update the last item in the array + const lastIndex = newMessages.length - 1; + newMessages[lastIndex] = { + ...newMessages[lastIndex], + answer: "", + isError: true + }; + return newMessages; + }) + } + if (object?.content && isLoadingObject) { setAnswerLoadingStatus(false); setChats((prev:any) => { @@ -373,7 +411,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose }); } - }, [object, isLoadingObject]); + }, [object, isLoadingObject, error]); // Handles the login click event const onLoginClick = () => { @@ -395,6 +433,11 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose } }, [isAnswerLoading]); + useEffect(() => { + updateToken(); // Fetch token on initial render + }, []); + + return ( <> {mode === 'chat' && ( @@ -411,12 +454,14 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose onRegenerate={onRegenerate} onQuestionEdit={onQuestionEdit} onPromptClicked={onPromptClicked} + onInitialPromptClicked={onInitialPromptClicked} isAnswerLoading={isAnswerLoading} chats={chats} blogId={blogId} onFollowupClicked={onFollowupClicked} mode="chat" onCopyAnswer={onCopyAnswer} + isLoadingObject={isLoadingObject} /> {isAnswerLoading && } @@ -434,6 +479,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose onRegenerate={onHuskyInput} onQuestionEdit={onQuestionEdit} onPromptClicked={onPromptClicked} + onInitialPromptClicked={onInitialPromptClicked} onShareClicked={onShareClicked} isAnswerLoading={isAnswerLoading} chats={chats} @@ -441,6 +487,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose onFollowupClicked={onFollowupClicked} mode="blog" onCopyAnswer={onCopyAnswer} + isLoadingObject={isLoadingObject} /> {isAnswerLoading && } diff --git a/components/core/husky/husky-chat-suggestion.tsx b/components/core/husky/husky-chat-suggestion.tsx index 81d7b1c2..c0cfb5d8 100644 --- a/components/core/husky/husky-chat-suggestion.tsx +++ b/components/core/husky/husky-chat-suggestion.tsx @@ -6,13 +6,14 @@ interface HuskyChatSuggestionsProps { onFollowupClicked?: (question: string) => Promise; chatIndex?: number; isAnswerLoading: boolean; + isLoadingObject: boolean; } -function HuskyChatSuggestions({ followupQuestions = [], chatIndex = 0, onFollowupClicked, isAnswerLoading }: HuskyChatSuggestionsProps) { +function HuskyChatSuggestions({ followupQuestions = [], chatIndex = 0, onFollowupClicked, isAnswerLoading, isLoadingObject }: HuskyChatSuggestionsProps) { // Handles the click event for a follow-up question. // If an answer is loading, it prevents further actions. const onQuestionClicked = (question: string) => { - if(isAnswerLoading) { + if(isAnswerLoading || isLoadingObject) { return; } if (onFollowupClicked) { diff --git a/components/core/husky/husky-chat.tsx b/components/core/husky/husky-chat.tsx index 52a525d3..c898cf80 100644 --- a/components/core/husky/husky-chat.tsx +++ b/components/core/husky/husky-chat.tsx @@ -18,8 +18,10 @@ interface HuskyChatProps { onCopyAnswer: (answer: string) => Promise; blogId?: string; isAnswerLoading: boolean; + isLoadingObject: boolean; + onInitialPromptClicked: (quesObj: any) => void; } -function HuskyChat({ mode, chats, onFollowupClicked, isAnswerLoading, onQuestionEdit, onShareClicked, onPromptClicked, onCopyAnswer, onRegenerate, onFeedback, blogId }: HuskyChatProps) { +function HuskyChat({ mode, chats, onInitialPromptClicked, onFollowupClicked, isAnswerLoading, onQuestionEdit, onShareClicked, onPromptClicked, onCopyAnswer, onRegenerate, onFeedback, blogId, isLoadingObject }: HuskyChatProps) { return ( <>
@@ -46,7 +48,7 @@ function HuskyChat({ mode, chats, onFollowupClicked, isAnswerLoading, onQuestion mode={mode} answer={chat?.answer} />} - {chat?.followupQuestions?.length > 0 && } + {chat?.followupQuestions?.length > 0 && } {mode !== 'blog' && chat?.actions?.length > 0 && } )} @@ -69,7 +71,7 @@ function HuskyChat({ mode, chats, onFollowupClicked, isAnswerLoading, onQuestion
))} } - {chats.length === 0 && !isAnswerLoading && } + {chats.length === 0 && !isAnswerLoading && }