feat/ai-courses
Arik Chakma 2 months ago
parent 7854597935
commit cb5632160d
  1. 8
      src/components/Billing/UpgradeAccountModal.tsx
  2. 139
      src/components/GenerateCourse/AICourseLimit.tsx
  3. 23
      src/components/GenerateCourse/GetAICourse.tsx

@ -24,9 +24,13 @@ type CreateSubscriptionCheckoutSessionResponse = {
checkoutUrl: string;
};
type UpgradeAccountModalProps = {};
type UpgradeAccountModalProps = {
onClose: () => void;
};
export function UpgradeAccountModal(props: UpgradeAccountModalProps) {
const { onClose } = props;
const [selectedPlan, setSelectedPlan] =
useState<AllowedSubscriptionInterval>('month');
const [isUpdatingPlan, setIsUpdatingPlan] = useState(false);
@ -115,7 +119,7 @@ export function UpgradeAccountModal(props: UpgradeAccountModalProps) {
return (
<Modal
onClose={() => {}}
onClose={onClose}
wrapperClassName="rounded-xl max-w-3xl w-full min-h-[540px]"
bodyClassName="p-6"
>

@ -11,10 +11,12 @@ import { useState, useRef } from 'react';
import { getAiCourseLimitOptions } from '../../queries/ai-course';
import { queryClient } from '../../stores/query-client';
import { useOutsideClick } from '../../hooks/use-outside-click';
import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal';
export function AICourseLimit() {
const containerRef = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
const [showUpgradeModal, setShowUpgradeModal] = useState(false);
const { data: limits, isLoading } = useQuery(
getAiCourseLimitOptions(),
@ -45,80 +47,93 @@ export function AICourseLimit() {
const followUpPercentage = Math.round((followUpUsed / followUpLimit) * 100);
return (
<div className="relative z-10" ref={containerRef}>
<button
className="flex h-full cursor-pointer items-center rounded-lg border border-gray-200 px-2 py-1.5 text-sm hover:bg-gray-50"
onClick={() => setIsOpen(!isOpen)}
>
<div className="mr-3 flex items-center gap-1.5">
<BookIcon className="h-4 w-4" />
{coursePercentage}%
</div>
<div className="mr-3 flex items-center gap-1.5">
<BookOpenIcon className="h-4 w-4" />
{lessonPercentage}%
</div>
<div className="mr-3 flex items-center gap-1.5">
<BotIcon className="h-4 w-4" />
{followUpPercentage}%
</div>
<span className="mr-1">of daily limits</span>
<ChevronDownIcon className="h-4 w-4" />
</button>
<>
<div className="relative z-10" ref={containerRef}>
<button
className="flex h-full cursor-pointer items-center rounded-lg border border-gray-200 px-2 py-1.5 text-sm hover:bg-gray-50"
onClick={() => setIsOpen(!isOpen)}
>
<div className="mr-3 flex items-center gap-1.5">
<BookIcon className="h-4 w-4" />
{coursePercentage}%
</div>
<div className="mr-3 flex items-center gap-1.5">
<BookOpenIcon className="h-4 w-4" />
{lessonPercentage}%
</div>
<div className="mr-3 flex items-center gap-1.5">
<BotIcon className="h-4 w-4" />
{followUpPercentage}%
</div>
<span className="mr-1">of daily limits</span>
<ChevronDownIcon className="h-4 w-4" />
</button>
{isOpen && (
<div className="absolute right-0 top-full w-full translate-y-1 overflow-hidden rounded-lg border border-gray-200 bg-white p-2 pt-0 text-sm shadow-lg">
<div className="-mx-2">
<div className="relative overflow-hidden">
<div className="relative z-10 flex items-center gap-2 border-b border-b-gray-200 px-2 py-1">
<BookIcon className="size-3.5" />
{courseUsed} of {courseLimit} courses used
</div>
{isOpen && (
<div className="absolute right-0 top-full w-full translate-y-1 overflow-hidden rounded-lg border border-gray-200 bg-white p-2 pt-0 text-sm shadow-lg">
<div className="-mx-2">
<div className="relative overflow-hidden">
<div className="relative z-10 flex items-center gap-2 border-b border-b-gray-200 px-2 py-1">
<BookIcon className="size-3.5" />
{courseUsed} of {courseLimit} courses used
<div
className="absolute inset-0 bg-gray-100"
style={{
width: `${coursePercentage}%`,
}}
/>
</div>
<div
className="absolute inset-0 bg-gray-100"
style={{
width: `${coursePercentage}%`,
}}
/>
</div>
<div className="relative overflow-hidden">
<div className="relative z-10 flex items-center gap-2 border-b border-b-gray-200 px-2 py-1">
<BookOpenIcon className="size-3.5" />
{lessonUsed} of {lessonLimit} lessons used
</div>
<div className="relative overflow-hidden">
<div className="relative z-10 flex items-center gap-2 border-b border-b-gray-200 px-2 py-1">
<BookOpenIcon className="size-3.5" />
{lessonUsed} of {lessonLimit} lessons used
<div
className="absolute inset-0 bg-gray-100"
style={{
width: `${lessonPercentage}%`,
}}
/>
</div>
<div
className="absolute inset-0 bg-gray-100"
style={{
width: `${lessonPercentage}%`,
}}
/>
</div>
<div className="relative overflow-hidden">
<div className="relative z-10 flex items-center gap-2 border-b border-b-gray-200 px-2 py-1">
<BotIcon className="size-3.5" />
{followUpUsed} of {followUpLimit} follow-ups used
</div>
<div className="relative overflow-hidden">
<div className="relative z-10 flex items-center gap-2 border-b border-b-gray-200 px-2 py-1">
<BotIcon className="size-3.5" />
{followUpUsed} of {followUpLimit} follow-ups used
<div
className="absolute inset-0 bg-gray-100"
style={{
width: `${followUpPercentage}%`,
}}
/>
</div>
</div>
<div
className="absolute inset-0 bg-gray-100"
style={{
width: `${followUpPercentage}%`,
}}
/>
<div className="mt-2 flex items-center justify-center gap-2 text-gray-500">
<ClockIcon className="size-3.5" />
Limit resets every 24 hours
</div>
</div>
)}
</div>
<div className="mt-2 flex items-center justify-center gap-2 text-gray-500">
<ClockIcon className="size-3.5" />
Limit resets every 24 hours
</div>
</div>
<button
className="ml-2 rounded-md border border-gray-200 px-2 py-1 text-sm hover:bg-gray-50"
onClick={() => setShowUpgradeModal(true)}
>
Upgrade
</button>
{showUpgradeModal && (
<UpgradeAccountModal onClose={() => setShowUpgradeModal(false)} />
)}
</div>
</>
);
}

@ -45,18 +45,15 @@ export function GetAICourse(props: GetAICourseProps) {
}, [error]);
return (
<>
<UpgradeAccountModal />
<AICourseContent
course={{
title: aiCourse?.title || '',
modules: aiCourse?.course.modules || [],
difficulty: aiCourse?.difficulty || 'Easy',
}}
isLoading={isLoading}
courseSlug={courseSlug}
error={error?.message}
/>
</>
<AICourseContent
course={{
title: aiCourse?.title || '',
modules: aiCourse?.course.modules || [],
difficulty: aiCourse?.difficulty || 'Easy',
}}
isLoading={isLoading}
courseSlug={courseSlug}
error={error?.message}
/>
);
}

Loading…
Cancel
Save