From e6440d453d970a3d883ebb2eea5bb8aded34c90e Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sat, 15 Nov 2025 09:28:08 +0000 Subject: [PATCH] Create CoursesWidget for FOUNDATION dashboard cgen-04b2deee7ba74729bcbb6d02d6246679 --- client/components/CoursesWidget.tsx | 181 ++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 client/components/CoursesWidget.tsx diff --git a/client/components/CoursesWidget.tsx b/client/components/CoursesWidget.tsx new file mode 100644 index 00000000..8c72ef8c --- /dev/null +++ b/client/components/CoursesWidget.tsx @@ -0,0 +1,181 @@ +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { BookOpen, CheckCircle, Clock, Lock, ArrowRight } from "lucide-react"; +import { Button } from "@/components/ui/button"; + +export interface Course { + id: string; + title: string; + description?: string; + category?: string; + progress?: number; + status: "not_started" | "in_progress" | "completed"; + duration?: string; + lessons_total?: number; + lessons_completed?: number; + instructor?: string; + thumbnail_url?: string; +} + +interface CoursesWidgetProps { + courses: Course[]; + title?: string; + description?: string; + onViewCourse?: (courseId: string) => void; + accentColor?: "red" | "blue" | "purple" | "green"; +} + +const colorMap = { + red: { + bg: "bg-gradient-to-br from-red-950/40 to-red-900/20", + border: "border-red-500/20", + }, + blue: { + bg: "bg-gradient-to-br from-blue-950/40 to-blue-900/20", + border: "border-blue-500/20", + }, + purple: { + bg: "bg-gradient-to-br from-purple-950/40 to-purple-900/20", + border: "border-purple-500/20", + }, + green: { + bg: "bg-gradient-to-br from-green-950/40 to-green-900/20", + border: "border-green-500/20", + }, +}; + +const statusMap = { + not_started: { label: "Not Started", color: "bg-gray-600/50 text-gray-100", icon: Lock }, + in_progress: { label: "In Progress", color: "bg-blue-600/50 text-blue-100", icon: Clock }, + completed: { label: "Completed", color: "bg-green-600/50 text-green-100", icon: CheckCircle }, +}; + +export function CoursesWidget({ + courses, + title = "My Courses & Curriculum", + description = "Track your learning progress", + onViewCourse, + accentColor = "red", +}: CoursesWidgetProps) { + const colors = colorMap[accentColor]; + const completedCount = courses.filter(c => c.status === "completed").length; + const inProgressCount = courses.filter(c => c.status === "in_progress").length; + + return ( + + + + + {title} + + {description} + + + {courses.length === 0 ? ( +
+ +

No courses yet

+

Start your learning journey today

+
+ ) : ( +
+ {/* Stats */} +
+
+

Total

+

{courses.length}

+
+
+

In Progress

+

{inProgressCount}

+
+
+

Completed

+

{completedCount}

+
+
+ + {/* Courses Grid */} +
+ {courses.map((course) => { + const statusInfo = statusMap[course.status]; + const StatusIcon = statusInfo.icon; + const progress = course.progress || 0; + + return ( +
onViewCourse?.(course.id)} + > + {/* Course Header */} +
+
+

{course.title}

+ + + {statusInfo.label} + +
+ {course.description && ( +

{course.description}

+ )} +
+ + {/* Course Meta */} +
+ {course.instructor && ( + {course.instructor} + )} + {course.duration && ( + {course.duration} + )} +
+ + {/* Progress */} + {course.lessons_total && ( +
+
+ Progress + + {course.lessons_completed || 0}/{course.lessons_total} + +
+
+
0 + ? `${(((course.lessons_completed || 0) / course.lessons_total) * 100)}%` + : "0%" + }} + /> +
+
+ )} + + {/* CTA */} + +
+ ); + })} +
+
+ )} + + + ); +} + +export default CoursesWidget;