import { useQuery } from '@tanstack/react-query'; import { BookOpenCheck, ChevronLeft, Loader2, Menu, X, CircleAlert, } from 'lucide-react'; import { useState } from 'react'; import { type AiCourse } from '../../lib/ai'; import { cn } from '../../lib/classname'; import { slugify } from '../../lib/slugger'; import { getAiCourseProgressOptions } from '../../queries/ai-course'; import { queryClient } from '../../stores/query-client'; import { CheckIcon } from '../ReactIcons/CheckIcon'; import { ErrorIcon } from '../ReactIcons/ErrorIcon'; import { AICourseLimit } from './AICourseLimit'; import { AICourseModuleList } from './AICourseModuleList'; import { AICourseModuleView } from './AICourseModuleView'; import { UpgradeAccountModal } from '../Billing/UpgradeAccountModal'; import { AILimitsPopup } from './AILimitsPopup'; type AICourseContentProps = { courseSlug?: string; course: AiCourse; isLoading: boolean; error?: string; }; export function AICourseContent(props: AICourseContentProps) { const { course, courseSlug, isLoading, error } = props; const [showUpgradeModal, setShowUpgradeModal] = useState(false); const [showAILimitsPopup, setShowAILimitsPopup] = useState(false); const [activeModuleIndex, setActiveModuleIndex] = useState(0); const [activeLessonIndex, setActiveLessonIndex] = useState(0); const [sidebarOpen, setSidebarOpen] = useState(false); const [viewMode, setViewMode] = useState<'module' | 'full'>('full'); const { data: aiCourseProgress } = useQuery( getAiCourseProgressOptions({ aiCourseSlug: courseSlug || '' }), queryClient, ); const [expandedModules, setExpandedModules] = useState< Record >({}); const goToNextModule = () => { if (activeModuleIndex < course.modules.length - 1) { const nextModuleIndex = activeModuleIndex + 1; setActiveModuleIndex(nextModuleIndex); setActiveLessonIndex(0); setExpandedModules((prev) => { const newState: Record = {}; course.modules.forEach((_, idx) => { newState[idx] = false; }); newState[nextModuleIndex] = true; return newState; }); } }; const goToNextLesson = () => { const currentModule = course.modules[activeModuleIndex]; if (currentModule && activeLessonIndex < currentModule.lessons.length - 1) { setActiveLessonIndex(activeLessonIndex + 1); } else { goToNextModule(); } }; const goToPrevLesson = () => { if (activeLessonIndex > 0) { setActiveLessonIndex(activeLessonIndex - 1); } else { const prevModule = course.modules[activeModuleIndex - 1]; if (prevModule) { const prevModuleIndex = activeModuleIndex - 1; setActiveModuleIndex(prevModuleIndex); setActiveLessonIndex(prevModule.lessons.length - 1); // Expand the previous module in the sidebar setExpandedModules((prev) => { const newState: Record = {}; // Set all modules to collapsed course.modules.forEach((_, idx) => { newState[idx] = false; }); // Expand only the previous module newState[prevModuleIndex] = true; return newState; }); } } }; const currentModule = course.modules[activeModuleIndex]; const currentLesson = currentModule?.lessons[activeLessonIndex]; const totalModules = course.modules.length; const totalLessons = currentModule?.lessons.length || 0; const totalCourseLessons = course.modules.reduce( (total, module) => total + module.lessons.length, 0, ); const totalDoneLessons = aiCourseProgress?.done?.length || 0; const finishedPercentage = Math.round( (totalDoneLessons / totalCourseLessons) * 100, ); const modals = ( <> {showUpgradeModal && ( setShowUpgradeModal(false)} /> )} {showAILimitsPopup && ( setShowAILimitsPopup(false)} onUpgrade={() => { setShowAILimitsPopup(false); setShowUpgradeModal(true); }} /> )} ); if (error && !isLoading) { const isLimitReached = error.includes('limit'); const icon = isLimitReached ? ( ) : ( ); const title = isLimitReached ? 'Limit Reached' : 'Error Generating Course'; const message = isLimitReached ? 'You have reached the daily AI usage limit. Please upgrade your account to continue.' : error; return ( <> {modals}
{icon}

{title}

{message}

{isLimitReached && (

Back to AI Tutor

)}
); } return (
{modals}
Back to Generator
setShowUpgradeModal(true)} onShowLimits={() => setShowAILimitsPopup(true)} />

{course.title || 'Loading Course...'}

{totalModules} modules {totalCourseLessons} lessons {viewMode === 'module' && ( )} {finishedPercentage > 0 && ( <> {finishedPercentage}% complete )}
setShowUpgradeModal(true)} onShowLimits={() => setShowAILimitsPopup(true)} />
{viewMode === 'module' && ( )}
{viewMode === 'module' && ( setShowUpgradeModal(true)} /> )} {viewMode === 'full' && (

{course.title || 'Loading course ..'}

{course.title ? course.difficulty : 'Please wait ..'}

{course.title ? (
{course.modules.map((courseModule, moduleIdx) => { return (

{courseModule.title}

{courseModule.lessons.map((lesson, lessonIdx) => { const key = `${slugify(courseModule.title)}__${slugify(lesson)}`; const isCompleted = aiCourseProgress?.done.includes(key); return (
{ setActiveModuleIndex(moduleIdx); setActiveLessonIndex(lessonIdx); setExpandedModules((prev) => { const newState: Record = {}; course.modules.forEach((_, idx) => { newState[idx] = false; }); newState[moduleIdx] = true; return newState; }); setSidebarOpen(false); setViewMode('module'); }} > {!isCompleted && ( {lessonIdx + 1} )} {isCompleted && ( )}

{lesson.replace(/^Lesson\s*?\d+[\.:]\s*/, '')}

{isCompleted ? 'View' : 'Start'} →
); })}
); })}
) : (
)}
)}
{sidebarOpen && (
setSidebarOpen(false)} >
)}
); }