feat: responsiveness of ai chat

feat/chat
Arik Chakma 3 weeks ago
parent 1323975b28
commit 27a08dba0f
  1. 24
      src/components/GenerateCourse/AICourseContent.tsx
  2. 26
      src/components/GenerateCourse/AICourseLesson.tsx
  3. 26
      src/components/GenerateCourse/AICourseLessonChat.tsx

@ -6,8 +6,11 @@ import {
Menu,
X,
Map,
MessageCircle,
MessageCircleOffIcon,
MessageCircleIcon,
} from 'lucide-react';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { type AiCourse } from '../../lib/ai';
import { cn } from '../../lib/classname';
import { useIsPaidUser } from '../../queries/billing';
@ -208,6 +211,12 @@ export function AICourseContent(props: AICourseContentProps) {
const isViewingLesson = viewMode === 'module';
useEffect(() => {
if (window && window?.innerWidth < 1024 && isAIChatsOpen) {
setIsAIChatsOpen(false);
}
}, []);
return (
<section className="flex h-screen flex-grow flex-col overflow-hidden bg-gray-50">
{modals}
@ -236,6 +245,19 @@ export function AICourseContent(props: AICourseContentProps) {
/>
</div>
{viewMode === 'module' && (
<button
onClick={() => setIsAIChatsOpen(!isAIChatsOpen)}
className="ml-1.5 flex items-center justify-center text-gray-400 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900 lg:hidden"
>
{isAIChatsOpen ? (
<MessageCircleOffIcon size={17} strokeWidth={3} />
) : (
<MessageCircleIcon size={17} strokeWidth={3} />
)}
</button>
)}
<button
onClick={() => setSidebarOpen(!sidebarOpen)}
className="flex items-center justify-center text-gray-400 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900 lg:hidden"

@ -243,6 +243,17 @@ export function AICourseLesson(props: AICourseLessonProps) {
{!isGenerating && !isLoading && (
<div className="absolute right-6 top-6 flex items-center justify-between gap-2">
<button
onClick={() => setIsAIChatsOpen(!isAIChatsOpen)}
className="rounded-full p-1 text-gray-400 hover:text-black max-lg:hidden"
>
{!isAIChatsOpen ? (
<MessageCircleIcon className="size-4 stroke-[2.5]" />
) : (
<MessageCircleOffIcon className="size-4 stroke-[2.5]" />
)}
</button>
<RegenerateLesson
onRegenerateLesson={(prompt) => {
generateAiCourseContent(true, prompt);
@ -283,17 +294,6 @@ export function AICourseLesson(props: AICourseLessonProps) {
</>
)}
</button>
<button
onClick={() => setIsAIChatsOpen(!isAIChatsOpen)}
className="rounded-full p-1 text-gray-400 hover:text-black max-lg:hidden"
>
{!isAIChatsOpen ? (
<MessageCircleIcon className="size-4 stroke-[2.5]" />
) : (
<MessageCircleOffIcon className="size-4 stroke-[2.5]" />
)}
</button>
</div>
)}
</div>
@ -419,7 +419,6 @@ export function AICourseLesson(props: AICourseLessonProps) {
</div>
</div>
{isAIChatsOpen && (
<AICourseLessonChat
courseSlug={courseSlug}
moduleTitle={currentModuleTitle}
@ -427,8 +426,9 @@ export function AICourseLesson(props: AICourseLessonProps) {
onUpgradeClick={onUpgrade}
isDisabled={isGenerating || isLoading || isTogglingDone}
onClose={() => setIsAIChatsOpen(false)}
isAIChatsOpen={isAIChatsOpen}
setIsAIChatsOpen={setIsAIChatsOpen}
/>
)}
</div>
);
}

@ -47,6 +47,9 @@ type AICourseLessonChatProps = {
isDisabled?: boolean;
onClose: () => void;
isAIChatsOpen: boolean;
setIsAIChatsOpen: (isAIChatsOpen: boolean) => void;
};
export function AICourseLessonChat(props: AICourseLessonChatProps) {
@ -57,10 +60,12 @@ export function AICourseLessonChat(props: AICourseLessonChatProps) {
onUpgradeClick,
isDisabled,
onClose,
isAIChatsOpen,
setIsAIChatsOpen,
} = props;
const toast = useToast();
const containerRef = useRef<HTMLDivElement | null>(null);
const scrollareaRef = useRef<HTMLDivElement | null>(null);
const [courseAIChatHistory, setCourseAIChatHistory] = useState<
@ -203,17 +208,19 @@ export function AICourseLessonChat(props: AICourseLessonChatProps) {
scrollToBottom();
}, []);
useOutsideClick(containerRef, () => {
onClose();
});
return (
<div className="relative col-span-2 h-full border-l border-gray-200 max-lg:fixed max-lg:inset-y-0 max-lg:right-0 max-lg:z-10 max-lg:w-[420px] max-lg:border-none">
<div className="fixed inset-0 z-10 bg-black/50 lg:hidden" />
<>
{isAIChatsOpen && (
<div
className="absolute inset-0 z-20 flex w-full flex-col overflow-hidden bg-white"
ref={containerRef}
className="fixed inset-0 z-10 bg-black/50 lg:hidden"
onClick={onClose}
/>
)}
<div
className="relative col-span-2 h-full border-l border-gray-200 transition-all data-[state=closed]:hidden max-lg:fixed max-lg:inset-y-0 max-lg:right-0 max-lg:z-10 max-lg:w-[420px] max-lg:border-none max-lg:data-[state=closed]:translate-x-full max-lg:data-[state=open]:translate-x-0"
data-state={isAIChatsOpen ? 'open' : 'closed'}
>
<div className="absolute inset-y-0 right-0 z-20 flex w-full flex-col overflow-hidden bg-white">
<button
onClick={onClose}
className="absolute right-2 top-2 hidden rounded-full p-1 text-gray-400 hover:text-black max-lg:block"
@ -321,6 +328,7 @@ export function AICourseLessonChat(props: AICourseLessonChatProps) {
</form>
</div>
</div>
</>
);
}

Loading…
Cancel
Save