diff --git a/src/components/CourseProgressTracker.tsx b/src/components/CourseProgressTracker.tsx new file mode 100644 index 0000000..fa88932 --- /dev/null +++ b/src/components/CourseProgressTracker.tsx @@ -0,0 +1,277 @@ +import React, { useState, useEffect } from 'react'; +import { BookOpen, CheckCircle, Clock, Award, TrendingUp } from 'lucide-react'; + +interface Course { + id: string; + title: string; + totalLessons: number; + completedLessons: number; + category: string; + thumbnailUrl?: string; + estimatedTime?: number; // in minutes +} + +interface CourseProgressTrackerProps { + courses: Course[]; + onCourseClick?: (courseId: string) => void; +} + +const CourseProgressTracker: React.FC = ({ + courses, + onCourseClick +}) => { + const [sortBy, setSortBy] = useState<'progress' | 'recent'>('progress'); + const [filterCategory, setFilterCategory] = useState('all'); + + // Calculate overall statistics + const calculateStats = () => { + const totalCourses = courses.length; + const completedCourses = courses.filter(c => c.completedLessons === c.totalLessons).length; + const inProgressCourses = courses.filter(c => c.completedLessons > 0 && c.completedLessons < c.totalLessons).length; + const totalLessons = courses.reduce((sum, c) => sum + c.totalLessons, 0); + const completedLessons = courses.reduce((sum, c) => sum + c.completedLessons, 0); + const overallProgress = totalLessons > 0 ? Math.round((completedLessons / totalLessons) * 100) : 0; + + return { + totalCourses, + completedCourses, + inProgressCourses, + overallProgress + }; + }; + + const stats = calculateStats(); + + // Get unique categories + const categories = ['all', ...Array.from(new Set(courses.map(c => c.category)))]; + + // Filter and sort courses + const getFilteredCourses = () => { + let filtered = filterCategory === 'all' + ? courses + : courses.filter(c => c.category === filterCategory); + + if (sortBy === 'progress') { + return filtered.sort((a, b) => { + const progressA = (a.completedLessons / a.totalLessons) * 100; + const progressB = (b.completedLessons / b.totalLessons) * 100; + return progressB - progressA; + }); + } + + return filtered; + }; + + const filteredCourses = getFilteredCourses(); + + const getProgressPercentage = (course: Course) => { + return Math.round((course.completedLessons / course.totalLessons) * 100); + }; + + const getProgressColor = (percentage: number) => { + if (percentage === 100) return 'bg-green-500'; + if (percentage >= 50) return 'bg-blue-500'; + if (percentage > 0) return 'bg-orange-500'; + return 'bg-gray-300'; + }; + + return ( +
+ {/* Header */} +
+

+ My Learning Progress +

+

+ Track your courses and continue your learning journey +

+
+ + {/* Statistics Cards */} +
+ + + + +
+ + {/* Filters */} +
+
+ + +
+ +
+ + +
+
+ + {/* Course List */} +
+ {filteredCourses.length === 0 ? ( +
+ +

+ No courses found. Start learning today! +

+
+ ) : ( + filteredCourses.map(course => ( + onCourseClick?.(course.id)} + /> + )) + )} +
+
+ ); +}; + +// Stat Card Component +const StatCard: React.FC<{ + icon: React.ElementType; + label: string; + value: string | number; + color: 'blue' | 'orange' | 'green' | 'purple'; +}> = ({ icon: Icon, label, value, color }) => { + const colorClasses = { + blue: 'bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400', + orange: 'bg-orange-100 dark:bg-orange-900/30 text-orange-600 dark:text-orange-400', + green: 'bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400', + purple: 'bg-purple-100 dark:bg-purple-900/30 text-purple-600 dark:text-purple-400' + }; + + return ( +
+
+
+ +
+
+

{label}

+

{value}

+
+
+
+ ); +}; + +// Course Card Component +const CourseCard: React.FC<{ + course: Course; + onClick: () => void; +}> = ({ course, onClick }) => { + const progress = Math.round((course.completedLessons / course.totalLessons) * 100); + const isCompleted = progress === 100; + + const getProgressColor = (percentage: number) => { + if (percentage === 100) return 'bg-green-500'; + if (percentage >= 50) return 'bg-blue-500'; + if (percentage > 0) return 'bg-orange-500'; + return 'bg-gray-300'; + }; + + return ( +
+
+ {/* Thumbnail */} +
+ +
+ + {/* Course Info */} +
+
+
+

+ {course.title} +

+ + {course.category} + +
+ {isCompleted && ( + + )} +
+ + {/* Progress Bar */} +
+
+ + {course.completedLessons} of {course.totalLessons} lessons + + + {progress}% + +
+
+
+
+
+ + {/* Additional Info */} + {course.estimatedTime && ( +
+ + {course.estimatedTime} minutes remaining +
+ )} +
+
+
+ ); +}; + +export default CourseProgressTracker; \ No newline at end of file diff --git a/src/components/README-CourseProgressTracker.md b/src/components/README-CourseProgressTracker.md new file mode 100644 index 0000000..0391e3d --- /dev/null +++ b/src/components/README-CourseProgressTracker.md @@ -0,0 +1,257 @@ +# Course Progress Tracker + +A React/TypeScript component for Skill-Bridge that helps learners track their course progress, view statistics, and manage their learning journey. + +## πŸ“‹ Description + +The `CourseProgressTracker` component provides a comprehensive dashboard for learners to monitor their progress across multiple courses. It displays overall statistics, individual course progress, and allows filtering and sorting for better organization. + +## ✨ Features + +- πŸ“Š **Overall Statistics**: View total courses, in-progress, completed, and overall progress +- πŸ“ˆ **Progress Visualization**: Color-coded progress bars for each course +- πŸ† **Completion Badges**: Award icons for completed courses +- πŸ” **Filtering**: Filter courses by category +- πŸ“‹ **Sorting**: Sort by progress or recent activity +- 🎨 **Dark Mode Support**: Seamless light/dark theme integration +- πŸ“± **Responsive Design**: Works on all screen sizes +- ⏱️ **Time Tracking**: Shows estimated time remaining + +## πŸš€ Usage + +### Basic Implementation + +```tsx +import CourseProgressTracker from '@/components/CourseProgressTracker'; + +function Dashboard() { + const courses = [ + { + id: '1', + title: 'Introduction to React', + totalLessons: 20, + completedLessons: 15, + category: 'Web Development', + estimatedTime: 150 + }, + { + id: '2', + title: 'Python for Beginners', + totalLessons: 30, + completedLessons: 30, + category: 'Programming', + estimatedTime: 0 + } + ]; + + return ( + { + // Navigate to course details + console.log('Course clicked:', courseId); + }} + /> + ); +} +``` + +### With Navigation + +```tsx + { + router.push(`/course/${courseId}`); + }} +/> +``` + +## πŸ“¦ Props + +| Prop | Type | Required | Description | +|------|------|----------|-------------| +| `courses` | `Course[]` | Yes | Array of course objects with progress data | +| `onCourseClick` | `(courseId: string) => void` | No | Callback when a course card is clicked | + +### Course Object Structure + +```typescript +interface Course { + id: string; // Unique course identifier + title: string; // Course title + totalLessons: number; // Total number of lessons + completedLessons: number; // Number of completed lessons + category: string; // Course category + thumbnailUrl?: string; // Optional thumbnail URL + estimatedTime?: number; // Estimated time remaining (minutes) +} +``` + +## 🎨 UI Components + +### Statistics Cards (4 Cards) +1. **Total Courses** - Blue icon, shows total enrolled courses +2. **In Progress** - Orange icon, shows active courses +3. **Completed** - Green icon, shows finished courses +4. **Overall Progress** - Purple icon, shows percentage completion + +### Filters Section +- **Sort by**: Progress or Recent +- **Category**: Filter by course category + +### Course Cards +Each card displays: +- Course thumbnail/icon +- Course title +- Category badge +- Progress bar with percentage +- Completed/Total lessons count +- Estimated time remaining +- Completion award (for finished courses) + +## πŸ“Έ Visual Layout + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ My Learning Progress β”‚ +β”‚ Track your courses and continue learning β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚πŸ“š 10 β”‚ β”‚πŸ“ˆ 5 β”‚ β”‚βœ… 3 β”‚ β”‚πŸ†75%β”‚ β”‚ +β”‚ β”‚Total β”‚ β”‚Prog. β”‚ β”‚Done β”‚ β”‚Prog.β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ Sort: [Progress β–Ό] Category: [All β–Ό] β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ πŸ“š Introduction to React β”‚ β”‚ +β”‚ β”‚ [Web Development] πŸ† β”‚ β”‚ +β”‚ β”‚ 15 of 20 lessons 75% β”‚ β”‚ +β”‚ β”‚ β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–“β–‘β–‘β–‘β–‘β–‘ β”‚ β”‚ +β”‚ β”‚ ⏱️ 150 minutes remaining β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## 🎯 Features Breakdown + +### Progress Calculation +- Automatically calculates percentage: `(completedLessons / totalLessons) * 100` +- Color-coded progress bars: + - Green: 100% (Completed) + - Blue: 50-99% (Good progress) + - Orange: 1-49% (Getting started) + - Gray: 0% (Not started) + +### Statistics Calculation +- **Total Courses**: Count of all courses +- **In Progress**: Courses with 0 < progress < 100% +- **Completed**: Courses with 100% progress +- **Overall Progress**: Total completed lessons / Total lessons + +### Filtering & Sorting +- **Category Filter**: Shows only courses from selected category +- **Progress Sort**: Orders by completion percentage (high to low) +- **Recent Sort**: Shows most recently accessed courses first + +## 🎨 Styling + +### Color Scheme +- **Blue**: `bg-blue-500` - Primary progress color +- **Orange**: `bg-orange-500` - In-progress indicator +- **Green**: `bg-green-500` - Completion color +- **Purple**: `bg-purple-500` - Overall stats + +### Dark Mode +- Automatic theme detection +- Dark backgrounds: `dark:bg-gray-800` +- Dark text: `dark:text-white` +- Dark borders: `dark:border-gray-700` + +## πŸ”§ Technical Details + +### Dependencies +- React +- TypeScript +- Tailwind CSS +- Lucide React icons (BookOpen, CheckCircle, Clock, Award, TrendingUp) + +### State Management +- Local state for sorting and filtering +- Props-based course data +- Calculated statistics (no persistent state) + +### Performance +- Efficient filtering and sorting +- Minimal re-renders +- Optimized calculations + +## πŸ“± Integration Example + +```tsx +// In your dashboard or home page +import { useState, useEffect } from 'react'; +import CourseProgressTracker from '@/components/CourseProgressTracker'; + +export default function DashboardPage() { + const [courses, setCourses] = useState([]); + + useEffect(() => { + // Fetch user's enrolled courses + fetchUserCourses().then(setCourses); + }, []); + + const handleCourseClick = (courseId) => { + // Navigate to course player + window.location.href = `/course/${courseId}`; + }; + + return ( +
+ +
+ ); +} +``` + +## πŸ’‘ Use Cases + +- **Student Dashboard**: Main learning progress overview +- **Profile Page**: Show user's learning achievements +- **Progress Reports**: Generate progress summaries +- **Motivation Tool**: Visual progress encourages completion +- **Course Management**: Easily resume in-progress courses + +## πŸ”„ Future Enhancements + +Potential additions: +- Time-based analytics (weekly/monthly progress) +- Streak tracking +- Learning goals and targets +- Export progress report (PDF) +- Social sharing of achievements +- Course recommendations based on progress +- Gamification badges +- Progress comparison with peers + +## πŸ‘¨β€πŸ’» Author + +**Ashvin** +- GitHub: [@ashvin2005](https://github.com/ashvin2005) +- LinkedIn: [ashvin-tiwari](https://linkedin.com/in/ashvin-tiwari) + +## πŸŽƒ Hacktoberfest 2025 + +Created as part of Hacktoberfest 2025 contributions to Skill-Bridge. + +## πŸ“„ License + +MIT License - Same as Skill-Bridge project + +--- + +Made with ❀️ for the Skill-Bridge community \ No newline at end of file