'use client' import * as React from 'react' import { CourseCard } from '@/components/CourseCard' import { Header } from '@/components/Header' import { BookOpen, Plus, Search, Filter, Settings, Play, Clock, CheckCircle, BarChart3, Zap, ChevronLeft, ChevronRight, ChevronUp, ChevronDown } from 'lucide-react' import { Button } from '@/components/ui/button' import { Card, CardContent } from '@/components/ui/card' import { Progress } from '@/components/ui/progress' import { ScrollArea } from '@/components/ui/scroll-area' import { Input } from '@/components/ui/input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import Link from 'next/link' import { formatTime } from '@/lib/utils' import { useCourses } from '@/lib/hooks/useCourses' import { getCourseDisplayName } from '@/lib/course-display' export default function Dashboard() { const { courses, tags, loading, error, pagination, search, setSearch, filter, setFilter, sortBy, sortOrder, setSortBy, setSortOrder, nextPage, prevPage, changeLimit, goToPage, refetch, toggleSortOrder, } = useCourses({ initialLimit: 12 }) const [continueWatching, setContinueWatching] = React.useState([]) const [completedCourses, setCompletedCourses] = React.useState([]) const [cwLoading, setCwLoading] = React.useState(true) const [ccLoading, setCcLoading] = React.useState(true) const categoryTags = React.useMemo( () => tags.filter((tag: any) => tag.name.startsWith('category:')), [tags] ) const plainTags = React.useMemo( () => tags.filter((tag: any) => !tag.name.startsWith('category:')), [tags] ) React.useEffect(() => { const fetchContinueWatching = async () => { try { const res = await fetch('/api/progress?type=continue') const data = await res.json() setContinueWatching(data.items || data) } catch (e) { console.error('Failed to fetch continue watching:', e) } finally { setCwLoading(false) } } const fetchCompletedCourses = async () => { try { const res = await fetch('/api/progress?type=completed') const data = await res.json() setCompletedCourses(data.items || data) } catch (e) { console.error('Failed to fetch completed courses:', e) } finally { setCcLoading(false) } } fetchContinueWatching() fetchCompletedCourses() }, []) const getVideoThumb = (lessonType: string, courseName: string) => { const name = courseName.toLowerCase() if (name.includes('linux') || name.includes('terraform')) return 'video-thumb-linux' if (name.includes('code') || name.includes('program')) return 'video-thumb-code' if (name.includes('automat') || name.includes('workflow')) return 'video-thumb-flow' return 'video-thumb-presenter' } if (loading) { return (

Loading courses...

) } if (courses.length === 0) { return (

No courses found

Add course folders to your My_Courses/ directory, following the scan page folder structure, then scan to populate your library.

) } return (
{/* Stats Bar */}
{/* Search/Filter bar */}
setSearch(e.target.value)} className="pl-10 pr-4 py-2 bg-background border border-white/10 rounded-lg text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/50 w-full" />
{/* Sort dropdown */}
{/* Stats */}
{pagination.total} courses
{courses.reduce((sum, c) => sum + c._count.lessons, 0)} lessons
{courses.filter(c => c.progress.percentage === 100 && c._count.lessons > 0).length} completed
{courses.filter(c => c.progress.percentage > 0 && c.progress.percentage < 100).length} in progress
{error && (
{error}
)} {/* Continue Watching */} {!cwLoading && continueWatching.length > 0 && search.trim() === '' && (

Continue Watching

{continueWatching.slice(0, 1).map((item, index) => { const courseTitle = getCourseDisplayName(item.course) const thumbClass = getVideoThumb(item.lesson.type, courseTitle) return (
{item.progress.position && item.lesson.duration && (
)}

{courseTitle}

{item.lesson.title}

{item.lesson.duration ? formatTime(item.progress.position || 0) + ' / ' + formatTime(item.lesson.duration) : formatTime(item.progress.position || 0)} {item.lesson.duration && ( )}
) })}
)} {/* Completed Courses */} {!ccLoading && completedCourses.length > 0 && (

Completed Courses

{completedCourses.map((course) => { const courseTitle = getCourseDisplayName(course) return (
{courseTitle} 100%
) })}
)} {/* Your Library */}

Your Library

{courses.map((course) => ( ))}
{pagination.totalPages > 1 && (
{(() => { const pages = Array.from({ length: Math.min(5, pagination.totalPages) }, (_, i) => { let pageNum if (pagination.totalPages <= 5) { pageNum = i + 1 } else if (pagination.page <= 3) { pageNum = i + 1 } else if (pagination.page >= pagination.totalPages - 2) { pageNum = pagination.totalPages - 4 + i } else { pageNum = pagination.page - 2 + i } return ( ) }) return pages })()}
)}
Page {pagination.page} of {pagination.totalPages} — {pagination.total} courses total
) }