From 66e15a16f10af610765265ecfff21b6a4687a3e0 Mon Sep 17 00:00:00 2001 From: Arik Chakma Date: Fri, 2 May 2025 18:42:56 +0600 Subject: [PATCH] feat: predefined messages --- src/components/TopicDetail/TopicDetailAI.tsx | 82 ++++++++++++++++++-- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/src/components/TopicDetail/TopicDetailAI.tsx b/src/components/TopicDetail/TopicDetailAI.tsx index 32380fd7c..c177da6cc 100644 --- a/src/components/TopicDetail/TopicDetailAI.tsx +++ b/src/components/TopicDetail/TopicDetailAI.tsx @@ -7,6 +7,7 @@ import { Fragment, useCallback, useEffect, + useMemo, } from 'react'; import { billingDetailsOptions } from '../../queries/billing'; import { getAiCourseLimitOptions } from '../../queries/ai-course'; @@ -18,7 +19,7 @@ import { Loader2Icon, LockIcon, SendIcon, - Trash2 + Trash2, } from 'lucide-react'; import { showLoginPopup } from '../../lib/popup'; import { cn } from '../../lib/classname'; @@ -60,6 +61,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) { const textareaRef = useRef(null); const scrollareaRef = useRef(null); + const formRef = useRef(null); const sanitizedTopicId = topicId?.includes('@') ? topicId?.split('@')?.[1] @@ -95,10 +97,9 @@ export function TopicDetailAI(props: TopicDetailAIProps) { const isLimitExceeded = (tokenUsage?.used || 0) >= (tokenUsage?.limit || 0); const isPaidUser = userBillingDetails?.status === 'active'; - const handleChatSubmit = (e: FormEvent) => { - e.preventDefault(); + const handleChatSubmit = (overrideMessage?: string) => { + const trimmedMessage = (overrideMessage ?? message).trim(); - const trimmedMessage = message.trim(); if ( !trimmedMessage || isStreamingMessage || @@ -228,6 +229,22 @@ export function TopicDetailAI(props: TopicDetailAIProps) { roadmapTreeMapping?.subjects && roadmapTreeMapping?.subjects?.length > 0; const hasChatHistory = aiChatHistory.length > 1; + const testMyKnowledgePrompt = + 'Act as an interviewer and test my understanding of this topic'; + const predefinedMessages = useMemo( + () => [ + { + label: 'Explain this topic like I am a 5 years old', + message: 'Explain this topic like I am a 5 years old', + }, + { + label: 'Test my Knowledge', + message: testMyKnowledgePrompt, + }, + ], + [], + ); + return (
{isDataLoading && ( @@ -259,7 +276,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) { key={subject} target="_blank" href={`/ai/search?term=${subject}&difficulty=beginner&src=topic`} - className="flex items-center bg-gray-100 gap-1 gap-2 rounded-md border border-gray-300 px-2 py-1 hover:bg-gray-200 hover:text-black" + className="flex items-center gap-1 gap-2 rounded-md border border-gray-300 bg-gray-100 px-2 py-1 hover:bg-gray-200 hover:text-black" > {subject} @@ -331,6 +348,24 @@ export function TopicDetailAI(props: TopicDetailAIProps) { )}
+
+ {predefinedMessages.map((m) => ( + { + setMessage(m.message); + handleChatSubmit(m.message); + }} + /> + ))} +
+
{aiChatHistory.map((chat, index) => { + const isTextMyKnowledgePrompt = + chat.role === 'user' && + chat.content === testMyKnowledgePrompt; + return ( @@ -363,8 +406,12 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
{ + e.preventDefault(); + handleChatSubmit(); + }} > {isLimitExceeded && isLoggedIn() && (
@@ -415,7 +462,7 @@ export function TopicDetailAI(props: TopicDetailAIProps) { autoFocus={true} onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) { - handleChatSubmit(e as unknown as FormEvent); + handleChatSubmit(); } }} ref={textareaRef} @@ -431,3 +478,22 @@ export function TopicDetailAI(props: TopicDetailAIProps) {
); } + +type PredefinedMessageButtonProps = { + label: string; + message: string; + onClick: () => void; +}; + +function PredefinedMessageButton(props: PredefinedMessageButtonProps) { + const { label, message, onClick } = props; + + return ( + + ); +}