import { Check, Loader2, Play } from 'lucide-react'; import { cn } from '../../lib/classname'; import type { ChapterFileType, LessonFileType } from '../../lib/course'; import { useMemo, type CSSProperties } from 'react'; import { useCourseProgress } from '../../hooks/use-course'; import { CheckIcon } from '../ReactIcons/CheckIcon'; import { getPercentage } from '../../helper/number'; import { useIsMounted } from '../../hooks/use-is-mounted'; function LeftBorder({ hasCompleted }: { hasCompleted?: boolean }) { return ( ); } type ChapterProps = ChapterFileType & { index: number; isActive?: boolean; isCompleted?: boolean; activeCourseId: string; activeChapterId?: string; activeLessonId?: string; onChapterClick?: () => void; }; export function Chapter(props: ChapterProps) { const { id: chapterId, index, frontmatter, lessons, isActive = false, onChapterClick, activeCourseId, activeChapterId, activeLessonId, } = props; const { title } = frontmatter; const { data: courseProgress } = useCourseProgress(activeCourseId); const completeLessonSet = useMemo( () => new Set( (courseProgress?.completed || []) .filter((l) => l.chapterId === chapterId) .map((l) => `${l.chapterId}/${l.lessonId}`), ), [courseProgress], ); const isChapterCompleted = lessons.every((lesson) => completeLessonSet.has(`${chapterId}/${lesson.id}`), ); const completedPercentage = useMemo(() => { const completedCount = lessons.filter((lesson) => completeLessonSet.has(`${chapterId}/${lesson.id}`), ).length; return getPercentage(completedCount, lessons.length); }, [lessons, completeLessonSet]); const [filteredLessons, exercises] = useMemo(() => { const sortedLessons = lessons.sort( (a, b) => a.frontmatter.order - b.frontmatter.order, ); return [ sortedLessons.filter( (lesson) => !['quiz', 'challenge'].includes(lesson.frontmatter.type), ), sortedLessons.filter((lesson) => ['quiz', 'challenge'].includes(lesson.frontmatter.type), ), ]; }, [lessons]); return (