Add course upgrade button

feat/ai-courses
Kamran Ahmed 1 month ago
parent cee09328c4
commit e876b10f4d
  1. 20
      src/components/GenerateCourse/AICourseFollowUp.tsx
  2. 29
      src/components/GenerateCourse/AICourseFollowUpPopover.tsx
  3. 2
      src/components/GenerateCourse/AICourseLimit.tsx

@ -4,6 +4,7 @@ import {
AICourseFollowUpPopover, AICourseFollowUpPopover,
type AIChatHistoryType, type AIChatHistoryType,
} from './AICourseFollowUpPopover'; } from './AICourseFollowUpPopover';
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal';
type AICourseFollowUpProps = { type AICourseFollowUpProps = {
courseSlug: string; courseSlug: string;
@ -15,6 +16,8 @@ export function AICourseFollowUp(props: AICourseFollowUpProps) {
const { courseSlug, moduleTitle, lessonTitle } = props; const { courseSlug, moduleTitle, lessonTitle } = props;
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [showUpgradeModal, setShowUpgradeModal] = useState(false);
const [courseAIChatHistory, setCourseAIChatHistory] = useState< const [courseAIChatHistory, setCourseAIChatHistory] = useState<
AIChatHistoryType[] AIChatHistoryType[]
>([ >([
@ -29,15 +32,22 @@ export function AICourseFollowUp(props: AICourseFollowUpProps) {
return ( return (
<div className="relative"> <div className="relative">
<button <button
className="mt-4 flex w-full items-center gap-2 rounded-lg border border-yellow-300 bg-yellow-100 p-4 hover:bg-yellow-200" className="mt-4 flex w-full items-center gap-2 rounded-lg border border-yellow-300 bg-yellow-100 p-4 hover:bg-yellow-200 max-lg:mt-3 max-lg:text-sm"
onClick={() => setIsOpen(true)} onClick={() => setIsOpen(true)}
> >
<BotIcon className="h-4 w-4" /> <BotIcon className="h-4 w-4" />
<span>Still confused? Ask AI some follow up questions.</span> <span>
<span className="max-sm:hidden">Still confused?&nbsp;</span>
Ask AI some follow up questions
</span>
<ArrowRightIcon className="ml-auto h-4 w-4" /> <ArrowRightIcon className="ml-auto h-4 w-4 max-sm:hidden" />
</button> </button>
{showUpgradeModal && (
<UpgradeAccountModal onClose={() => setShowUpgradeModal(false)} />
)}
{isOpen && ( {isOpen && (
<AICourseFollowUpPopover <AICourseFollowUpPopover
courseSlug={courseSlug} courseSlug={courseSlug}
@ -45,6 +55,10 @@ export function AICourseFollowUp(props: AICourseFollowUpProps) {
lessonTitle={lessonTitle} lessonTitle={lessonTitle}
courseAIChatHistory={courseAIChatHistory} courseAIChatHistory={courseAIChatHistory}
setCourseAIChatHistory={setCourseAIChatHistory} setCourseAIChatHistory={setCourseAIChatHistory}
onUpgradeClick={() => {
setIsOpen(false);
setShowUpgradeModal(true);
}}
onOutsideClick={() => { onOutsideClick={() => {
if (!isOpen) { if (!isOpen) {
return; return;

@ -1,14 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { import { BookOpen, Bot, Code, HelpCircle, LockIcon, Send } from 'lucide-react';
BookOpen,
Bot,
Code,
GitCompare,
HelpCircle,
LockIcon,
MessageCircle,
Send,
} from 'lucide-react';
import { useEffect, useMemo, useRef, useState, type FormEvent } from 'react'; import { useEffect, useMemo, useRef, useState, type FormEvent } from 'react';
import { flushSync } from 'react-dom'; import { flushSync } from 'react-dom';
import { useOutsideClick } from '../../hooks/use-outside-click'; import { useOutsideClick } from '../../hooks/use-outside-click';
@ -41,6 +32,7 @@ type AICourseFollowUpPopoverProps = {
setCourseAIChatHistory: (value: AIChatHistoryType[]) => void; setCourseAIChatHistory: (value: AIChatHistoryType[]) => void;
onOutsideClick?: () => void; onOutsideClick?: () => void;
onUpgradeClick: () => void;
}; };
export function AICourseFollowUpPopover(props: AICourseFollowUpPopoverProps) { export function AICourseFollowUpPopover(props: AICourseFollowUpPopoverProps) {
@ -49,6 +41,7 @@ export function AICourseFollowUpPopover(props: AICourseFollowUpPopoverProps) {
moduleTitle, moduleTitle,
lessonTitle, lessonTitle,
onOutsideClick, onOutsideClick,
onUpgradeClick,
courseAIChatHistory, courseAIChatHistory,
setCourseAIChatHistory, setCourseAIChatHistory,
@ -205,7 +198,7 @@ export function AICourseFollowUpPopover(props: AICourseFollowUpPopoverProps) {
return ( return (
<> <>
<AIChatCard <AIChatCard
key={index} key={`chat-${index}`}
role={chat.role} role={chat.role}
content={chat.content} content={chat.content}
html={chat.html} html={chat.html}
@ -244,9 +237,17 @@ export function AICourseFollowUpPopover(props: AICourseFollowUpPopoverProps) {
onSubmit={handleChatSubmit} onSubmit={handleChatSubmit}
> >
{isLimitExceeded && ( {isLimitExceeded && (
<div className="absolute inset-0 flex items-center justify-center bg-black text-white"> <div className="absolute inset-0 flex items-center justify-center gap-2 bg-black text-white">
<LockIcon className="size-4" strokeWidth={2.5} /> <LockIcon className="size-4 cursor-not-allowed" strokeWidth={2.5} />
<p>You have reached the AI usage limit for today.</p> <p className="cursor-not-allowed">Limit reached for today</p>
<button
onClick={() => {
onUpgradeClick();
}}
className="rounded-md bg-white px-2 py-1 text-xs font-medium text-black hover:bg-gray-300"
>
Upgrade for more
</button>
</div> </div>
)} )}
<TextareaAutosize <TextareaAutosize

@ -32,7 +32,7 @@ export function AICourseLimit() {
<> <>
<button className="mr-1 flex items-center gap-1 text-sm font-medium lg:hidden underline underline-offset-2"> <button className="mr-1 flex items-center gap-1 text-sm font-medium lg:hidden underline underline-offset-2">
<Info className="size-4" /> <Info className="size-4" />
{totalPercentage}% of limit used {totalPercentage}% limit used
</button> </button>
<button className="relative hidden h-full min-h-[38px] cursor-pointer items-center overflow-hidden rounded-lg border border-gray-300 px-3 py-1.5 text-sm hover:bg-gray-50 lg:flex"> <button className="relative hidden h-full min-h-[38px] cursor-pointer items-center overflow-hidden rounded-lg border border-gray-300 px-3 py-1.5 text-sm hover:bg-gray-50 lg:flex">

Loading…
Cancel
Save