diff --git a/public/fallback-JpVqoPYWhveAylwUcifjM.js b/public/fallback-OmvrmPbBuElFuC706TJi3.js similarity index 100% rename from public/fallback-JpVqoPYWhveAylwUcifjM.js rename to public/fallback-OmvrmPbBuElFuC706TJi3.js diff --git a/src/pages/api/lms/progress/index.ts b/src/pages/api/lms/progress/index.ts index 0cf031515..e12b0820f 100644 --- a/src/pages/api/lms/progress/index.ts +++ b/src/pages/api/lms/progress/index.ts @@ -193,19 +193,61 @@ export default requireAuth(async (req: AuthenticatedRequest, res: NextApiRespons }); } - // Update enrollment lastActivity timestamp + // Calculate and update course progress + const courseId = lesson.module.courseId; + + // Count total lessons in course + const totalLessons = await prisma.lesson.count({ + where: { + module: { + courseId, + }, + }, + }); + + // Count completed lessons for this user + const completedLessons = await prisma.progress.count({ + where: { + userId, + completed: true, + lesson: { + module: { + courseId, + }, + }, + }, + }); + + // Calculate progress percentage + const progressPercentage = totalLessons > 0 + ? Math.round((completedLessons / totalLessons) * 100) + : 0; + + // Check if course is complete + const isComplete = progressPercentage === 100; + + // Update enrollment with progress and completion status await prisma.enrollment.updateMany({ where: { userId, - courseId: lesson.module.courseId, + courseId, }, data: { + progress: progressPercentage, lastActivity: new Date(), + status: isComplete ? 'COMPLETED' : 'ACTIVE', + completedAt: isComplete ? new Date() : null, }, }); res.status(existingProgress ? 200 : 201).json({ progress: progressRecord, + courseProgress: { + completed: completedLessons, + total: totalLessons, + percentage: progressPercentage, + isComplete, + }, message: existingProgress ? 'Progress updated successfully' : 'Progress tracking started', diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx index 19762a858..5020f0554 100644 --- a/src/pages/dashboard.tsx +++ b/src/pages/dashboard.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import Link from "next/link"; import { useSession } from "next-auth/react"; import Layout01 from "@layout/layout-01"; @@ -6,6 +6,18 @@ import type { GetStaticProps, NextPage } from "next"; import SEO from "@components/seo/page-seo"; import Breadcrumb from "@components/breadcrumb"; +type Enrollment = { + id: string; + progress: number; + status: string; + completedAt: string | null; + course: { + id: string; + title: string; + estimatedHours: number | null; + }; +}; + type PageProps = { layout?: { headerShadow: boolean; @@ -20,8 +32,42 @@ type PageWithLayout = NextPage & { const Dashboard: PageWithLayout = () => { const { data: session, status } = useSession(); + const [enrollments, setEnrollments] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + if (status === "authenticated") { + fetchEnrollments(); + } + }, [status]); + + const fetchEnrollments = async () => { + try { + setLoading(true); + const response = await fetch("/api/enrollment/enroll"); + const data = await response.json(); + + if (response.ok) { + setEnrollments(data.enrollments); + } + } catch (error) { + console.error("Error fetching enrollments:", error); + } finally { + setLoading(false); + } + }; - if (status === "loading") { + // Calculate stats from enrollments + const stats = { + enrolled: enrollments.filter((e) => e.status === "ACTIVE" || e.status === "COMPLETED").length, + completed: enrollments.filter((e) => e.status === "COMPLETED").length, + totalHours: enrollments.reduce((sum, e) => sum + (e.course.estimatedHours || 0), 0), + averageProgress: enrollments.length > 0 + ? Math.round(enrollments.reduce((sum, e) => sum + e.progress, 0) / enrollments.length) + : 0, + }; + + if (status === "loading" || loading) { return (
@@ -76,22 +122,26 @@ const Dashboard: PageWithLayout = () => { {/* Quick Stats */}
-
1
+
+ {stats.enrolled} +
Courses Enrolled
-
0
+
+ {stats.completed} +
Courses Completed
- 12 + {stats.totalHours}
-
Hours Studied
+
Total Course Hours
- 85% + {stats.averageProgress}%
Average Progress
@@ -105,68 +155,127 @@ const Dashboard: PageWithLayout = () => {
- {/* Sample enrolled course */} -
-
-
-
-
- -
-
-

- Web Development -

-

- Build modern web applications -

-
-
- - Active - -
+ {enrollments.filter((e) => e.status === "ACTIVE" || e.status === "COMPLETED").length > 0 ? ( + <> + {enrollments + .filter((e) => e.status === "ACTIVE" || e.status === "COMPLETED") + .map((enrollment) => ( +
+
+
+
+
+ +
+
+

+ {enrollment.course.title} +

+ {enrollment.course.estimatedHours && ( +

+ {enrollment.course.estimatedHours} hours +

+ )} +
+
+ + {enrollment.status === "COMPLETED" + ? "Completed" + : "Active"} + +
-
-
- Progress - 15% -
-
-
-
-
+
+
+ Progress + {enrollment.progress}% +
+
+
+
+
-
-
- Next: CSS Styling & Layout -
- - Continue Learning - -
+ {enrollment.status !== "COMPLETED" && ( +
+ + Continue Learning + +
+ )} + + {enrollment.status === "COMPLETED" && enrollment.completedAt && ( +
+
+ Completed on{" "} + {new Date(enrollment.completedAt).toLocaleDateString()} +
+ + View Course + +
+ )} +
+
+ ))} + + ) : ( +
+ +

+ No Courses Yet +

+

+ Start your learning journey by enrolling in a course +

+ + Browse Courses +
-
+ )} - {/* Empty state for additional courses */} -
- -

- Enroll in More Courses -

-

- Expand your skills with additional courses -

- - Browse Courses - -
+ {/* Enroll in more courses CTA */} + {enrollments.filter((e) => e.status === "ACTIVE" || e.status === "COMPLETED").length > 0 && ( +
+ +

+ Enroll in More Courses +

+

+ Expand your skills with additional courses +

+ + Browse Courses + +
+ )}