diff --git a/src/components/CourseCard.tsx b/src/components/CourseCard.tsx index 254ec2237..33a2e3bd7 100644 --- a/src/components/CourseCard.tsx +++ b/src/components/CourseCard.tsx @@ -18,12 +18,14 @@ export const CourseCard = ({ onClick(); }} > +
{course.title} +
diff --git a/src/components/CourseView.tsx b/src/components/CourseView.tsx index 133be9974..6b35696ce 100644 --- a/src/components/CourseView.tsx +++ b/src/components/CourseView.tsx @@ -39,8 +39,7 @@ export const CourseView = ({ type: contentType || 'video', description: courseContent[0]?.description || '', markAsCompleted: - courseContent[0]?.videoProgress[0]?.markAsCompleted || - false, + courseContent[0]?.videoProgress?.markAsCompleted || false, }} /> ) : null} @@ -51,8 +50,7 @@ export const CourseView = ({ title: x?.title || '', image: x?.thumbnail || '', id: x?.id || 0, - markAsCompleted: - x?.videoProgress[0]?.markAsCompleted || false, + markAsCompleted: x?.videoProgress?.markAsCompleted || false, percentComplete: getFolderPercentCompleted(x?.children), }))} courseId={parseInt(course.id, 10)} diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 39067023b..55c1d3cd1 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -11,7 +11,8 @@ import { Button } from './ui/button'; import { BackArrow } from '@/icons/BackArrow'; import { useRecoilState } from 'recoil'; import { sidebarOpen as sidebarOpenAtom } from '@/store/atoms/sidebar'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; +import { handleMarkAsCompleted } from '@/lib/utils'; export function Sidebar({ courseId, @@ -65,10 +66,12 @@ export function Sidebar({ - {content.title} - + + {content.title} + + {/* Render the children of this folder */} {renderContent(content.children)} @@ -79,12 +82,25 @@ export function Sidebar({ return (
{ navigateToContent(content.id); }} > - {content.title} +
+
+
+ {content.type === 'video' ? : null} + {content.type === 'notion' ? : null} +
+
{content.title}
+
+ {content.type === 'video' ? ( +
+ +
+ ) : null} +
); }); @@ -95,8 +111,8 @@ export function Sidebar({ } return ( -
-
+
+
{/* { @@ -166,7 +182,7 @@ function GoBackButton() { }; return ( -
+
{/* Your component content */}
); } + +function VideoIcon() { + return ( + + + + ); +} + +function NotionIcon() { + return ( + + + + ); +} + +// Todo: Fix types here +function Check({ content }: { content: any }) { + const [completed, setCompleted] = useState( + content?.videoProgress?.markAsCompleted || false, + ); + return ( + <> + { + setCompleted(!completed); + handleMarkAsCompleted(!completed, content.id); + e.stopPropagation(); + }} + type="checkbox" + className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" + /> + + ); +} diff --git a/src/db/course.ts b/src/db/course.ts index 074d30974..9edb8efb6 100644 --- a/src/db/course.ts +++ b/src/db/course.ts @@ -1,5 +1,7 @@ import db from '@/db'; import { Cache } from '@/db/Cache'; +import { authOptions } from '@/lib/auth'; +import { getServerSession } from 'next-auth'; export interface Content { id: number @@ -10,6 +12,10 @@ export interface Content { parentId: number | null createdAt: string children: Content[] + videoProgress?: { + currentTimestamp: string + markAsCompleted?: boolean + } } export interface Folder extends Content { @@ -82,8 +88,8 @@ async function getAllContent() { return value; } const allContent = await db.content.findMany({ - include: { - videoProgress: true, + where: { + hidden: false, }, }); @@ -92,15 +98,13 @@ async function getAllContent() { return allContent; } -export const getFullCourseContent = async (courseId: number) => { - const value = Cache.getInstance().get('getFullCourseContent', [ +async function getRootCourseContent(courseId: number) { + const value = Cache.getInstance().get('getRootCourseContent', [ courseId.toString(), ]); if (value) { return value; } - - const contents = await getAllContent(); const courseContent = await db.courseContent.findMany({ orderBy: [ { @@ -112,9 +116,51 @@ export const getFullCourseContent = async (courseId: number) => { }, include: { content: true }, }); + Cache.getInstance().set( + 'getRootCourseContent', + [courseId.toString()], + courseContent, + ); + return courseContent; +} + +function getVideoProgressForUser(userId: string) { + return db.videoProgress.findMany({ + where: { + userId, + }, + }); +} +export const getFullCourseContent = async (courseId: number) => { + // const value = Cache.getInstance().get('getFullCourseContent', [ + // courseId.toString(), + // ]); + // if (value) { + // return value; + // } + const session = await getServerSession(authOptions); + const contents = await getAllContent(); + const courseContent = await getRootCourseContent(courseId); + const videoProgress = await getVideoProgressForUser(session?.user?.id); const contentMap = new Map( - contents.map((content: any) => [content.id, { ...content, children: [] }]), + contents.map((content: any) => [ + content.id, + { + ...content, + children: [], + videoProgress: + content.type === 'video' + ? { + duration: videoProgress.find((x) => x.contentId === content.id) + ?.currentTimestamp, + markAsCompleted: videoProgress.find( + (x) => x.contentId === content.id, + )?.markAsCompleted, + } + : null, + }, + ]), ); const rootContents: any[] = []; contents @@ -124,7 +170,7 @@ export const getFullCourseContent = async (courseId: number) => { contentMap .get(content.parentId) .children.push(contentMap.get(content.id)); - } else if (courseContent.find((x) => x.contentId === content.id)) { + } else if (courseContent.find((x: any) => x.contentId === content.id)) { rootContents.push(contentMap.get(content.id)); } }); diff --git a/src/lib/utils.ts b/src/lib/utils.ts index feb0c930f..0c5b9aa57 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -168,7 +168,7 @@ export const getFolderPercentCompleted = (childrenContent: any) => { ); const totalVideosWatched = videos.filter( ({ videoProgress }: any) => - videoProgress && videoProgress[0]?.markAsCompleted, + videoProgress && videoProgress?.markAsCompleted, ).length; return Math.ceil((totalVideosWatched / videos.length) * 100); }