From 9095ba8f3ae2347f8cc72a965aa725f9542d0697 Mon Sep 17 00:00:00 2001 From: hkirat Date: Sun, 4 Feb 2024 02:32:24 +0100 Subject: [PATCH 1/4] Fixed layout From 4c51d8ee71606556900eb86386106fefe6f9b2e3 Mon Sep 17 00:00:00 2001 From: hkirat Date: Sun, 4 Feb 2024 04:02:44 +0100 Subject: [PATCH 2/4] Fixed complete logic, added hidden logic --- src/components/CourseCard.tsx | 15 ++--- src/components/CourseView.tsx | 6 +- src/components/PercentageComplete.tsx | 4 +- src/components/Sidebar.tsx | 93 ++++++++++++++++++++++++--- src/db/course.ts | 60 +++++++++++++++-- src/lib/utils.ts | 2 +- 6 files changed, 150 insertions(+), 30 deletions(-) diff --git a/src/components/CourseCard.tsx b/src/components/CourseCard.tsx index f35a97a15..058ed0fa4 100644 --- a/src/components/CourseCard.tsx +++ b/src/components/CourseCard.tsx @@ -27,14 +27,13 @@ export const CourseCard = ({ )} /> )} - {course.title} - -
- {course.title} +
+ {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/PercentageComplete.tsx b/src/components/PercentageComplete.tsx index 30acf4f9d..af267691b 100644 --- a/src/components/PercentageComplete.tsx +++ b/src/components/PercentageComplete.tsx @@ -2,7 +2,9 @@ import React from 'react'; const PercentageComplete = ({ percent }: { percent: number }) => { return ( -
+
{`${percent}% completed`}
); diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 39067023b..8863f6293 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..deb740030 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 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); } From 182d52d39184d3f07c8adb8b6a727a9b96809553 Mon Sep 17 00:00:00 2001 From: hkirat Date: Sun, 4 Feb 2024 04:03:17 +0100 Subject: [PATCH 3/4] class => className --- src/components/Sidebar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 8863f6293..55c1d3cd1 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -199,7 +199,7 @@ function VideoIcon() { viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" - class="w-6 h-6" + className="w-6 h-6" > Date: Sun, 4 Feb 2024 04:03:54 +0100 Subject: [PATCH 4/4] fix build --- src/db/course.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/course.ts b/src/db/course.ts index deb740030..9edb8efb6 100644 --- a/src/db/course.ts +++ b/src/db/course.ts @@ -170,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)); } });