{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "course-content-page-shadcnui", "type": "registry:component", "title": "Course Content Page", "description": "Interactive course page with video player, instructor details, curriculum sections, and progress tracking", "registryDependencies": [ "button" ], "dependencies": [ "framer-motion", "react" ], "files": [ { "path": "@uitripled/react-shadcn/src/components/components/course-content/course-content-page.tsx", "content": "\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { motion, type Variants } from \"framer-motion\";\nimport {\n AlertTriangle,\n Award,\n BookOpen,\n CheckCircle2,\n ChevronRight,\n Clock,\n Download,\n FileText,\n Languages,\n Lock,\n Play,\n PlayCircle,\n Share2,\n Star,\n Timer,\n Users,\n Video,\n Zap,\n} from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\n// ============================================================================\n// TYPES & INTERFACES\n// ============================================================================\n\ninterface InstructorCardProps {\n name: string;\n title: string;\n bio: string;\n image: string;\n rating: number;\n students: string;\n courses: number;\n}\n\ninterface CourseStatsProps {\n label: string;\n value: string;\n icon: React.ReactNode;\n}\n\ninterface CurriculumSection {\n title: string;\n lessons: CurriculumLesson[];\n duration: string;\n}\n\ninterface CurriculumLesson {\n title: string;\n duration: string;\n isCompleted: boolean;\n isLocked: boolean;\n type: \"video\" | \"article\" | \"quiz\";\n}\n\n// ============================================================================\n// STATIC DATA\n// ============================================================================\n\nconst COURSE_DATA = {\n title: \"Advanced React Development & Performance Optimization\",\n description:\n \"Master modern React patterns, state management, and performance optimization techniques to build production-ready applications.\",\n rating: 4.8,\n totalRatings: \"12,543\",\n students: \"45,892\",\n lastUpdated: \"November 2024\",\n language: \"English\",\n duration: \"18.5 hours\",\n lectures: 156,\n};\n\nconst INSTRUCTOR_DATA = {\n name: \"shadcn\",\n title: \"Creator of shadcn/ui · Open Source Developer\",\n bio: \"Building beautiful, accessible component libraries for the web. Passionate about design systems, developer experience, and making UI development enjoyable.\",\n image: \"https://avatars.githubusercontent.com/u/139895814?v=4\",\n rating: 4.9,\n students: \"125,000\",\n courses: 12,\n};\n\nconst PROMO_DATA = {\n discount: 60,\n originalPrice: 299,\n discountedPrice: 119,\n spotsLeft: 12,\n deadline: new Date(Date.now() + 24 * 60 * 60 * 1000 + 5 * 60 * 60 * 1000), // 1 day 5 hours from now\n};\n\nconst CURRICULUM_DATA: CurriculumSection[] = [\n {\n title: \"Getting Started with React\",\n duration: \"1h 45m\",\n lessons: [\n {\n title: \"Introduction to Modern React\",\n duration: \"12:30\",\n isCompleted: true,\n isLocked: false,\n type: \"video\",\n },\n {\n title: \"Setting Up Your Development Environment\",\n duration: \"18:45\",\n isCompleted: true,\n isLocked: false,\n type: \"video\",\n },\n {\n title: \"Understanding Component Architecture\",\n duration: \"25:15\",\n isCompleted: false,\n isLocked: false,\n type: \"video\",\n },\n {\n title: \"Quick Quiz: React Basics\",\n duration: \"10:00\",\n isCompleted: false,\n isLocked: false,\n type: \"quiz\",\n },\n ],\n },\n {\n title: \"Advanced React Patterns\",\n duration: \"3h 20m\",\n lessons: [\n {\n title: \"Compound Components Pattern\",\n duration: \"28:30\",\n isCompleted: false,\n isLocked: false,\n type: \"video\",\n },\n {\n title: \"Render Props & Higher-Order Components\",\n duration: \"32:15\",\n isCompleted: false,\n isLocked: false,\n type: \"video\",\n },\n {\n title: \"Custom Hooks Deep Dive\",\n duration: \"40:20\",\n isCompleted: false,\n isLocked: false,\n type: \"video\",\n },\n {\n title: \"Best Practices Guide\",\n duration: \"15:00\",\n isCompleted: false,\n isLocked: false,\n type: \"article\",\n },\n ],\n },\n {\n title: \"State Management Mastery\",\n duration: \"4h 15m\",\n lessons: [\n {\n title: \"Context API vs Redux\",\n duration: \"22:45\",\n isCompleted: false,\n isLocked: true,\n type: \"video\",\n },\n {\n title: \"Zustand State Management\",\n duration: \"35:20\",\n isCompleted: false,\n isLocked: true,\n type: \"video\",\n },\n {\n title: \"Server State with React Query\",\n duration: \"42:10\",\n isCompleted: false,\n isLocked: true,\n type: \"video\",\n },\n ],\n },\n];\n\n// ============================================================================\n// ANIMATION VARIANTS\n// ============================================================================\n\nconst containerVariants: Variants = {\n hidden: { opacity: 0 },\n visible: {\n opacity: 1,\n transition: {\n staggerChildren: 0.1,\n delayChildren: 0.2,\n },\n },\n};\n\nconst itemVariants: Variants = {\n hidden: { opacity: 0, y: 20 },\n visible: {\n opacity: 1,\n y: 0,\n transition: { duration: 0.4 },\n },\n};\n\n// ============================================================================\n// COMPONENTS\n// ============================================================================\n\nfunction CountdownTimer({ deadline }: { deadline: Date }) {\n const [timeLeft, setTimeLeft] = useState({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0,\n });\n\n useEffect(() => {\n const calculateTimeLeft = () => {\n const difference = deadline.getTime() - Date.now();\n\n if (difference > 0) {\n setTimeLeft({\n days: Math.floor(difference / (1000 * 60 * 60 * 24)),\n hours: Math.floor((difference / (1000 * 60 * 60)) % 24),\n minutes: Math.floor((difference / 1000 / 60) % 60),\n seconds: Math.floor((difference / 1000) % 60),\n });\n }\n };\n\n calculateTimeLeft();\n const timer = setInterval(calculateTimeLeft, 1000);\n\n return () => clearInterval(timer);\n }, [deadline]);\n\n const TimeUnit = ({ value, label }: { value: number; label: string }) => (\n
\n \n \n {String(value).padStart(2, \"0\")}\n \n \n \n {label}\n \n
\n );\n\n return (\n
\n \n :\n \n :\n \n :\n \n
\n );\n}\n\nfunction CourseHeader() {\n return (\n \n {/* Promotional Offer Card */}\n \n {/* Animated background gradient */}\n
\n\n
\n {/* Header with badges */}\n
\n
\n \n \n {PROMO_DATA.discount}% OFF\n \n \n \n Only {PROMO_DATA.spotsLeft} Spots Left\n \n
\n \n \n Limited Time Offer\n \n
\n\n {/* Countdown Timer */}\n
\n
\n

\n Offer Ends In:\n

\n

\n Don't miss this opportunity to save $\n {PROMO_DATA.originalPrice - PROMO_DATA.discountedPrice}!\n

\n
\n
\n\n \n\n {/* Pricing */}\n
\n
\n

Original Price

\n

\n ${PROMO_DATA.originalPrice}\n

\n
\n
\n

Discounted Price

\n

\n ${PROMO_DATA.discountedPrice}\n

\n
\n
\n \n Enroll Now & Save $\n {PROMO_DATA.originalPrice - PROMO_DATA.discountedPrice}\n \n
\n
\n
\n \n\n {/* Original Header Content */}\n
\n
\n \n \n Online Course\n \n\n

\n {COURSE_DATA.title}\n

\n

\n {COURSE_DATA.description}\n

\n\n
\n
\n \n \n {COURSE_DATA.rating}\n \n \n ({COURSE_DATA.totalRatings} ratings)\n \n
\n
\n \n {COURSE_DATA.students} students\n
\n
\n
\n\n
\n \n \n \n \n Enroll Now\n \n
\n
\n \n );\n}\n\nfunction VideoPlayer() {\n const [isPlaying, setIsPlaying] = useState(false);\n\n return (\n \n
\n\n {/* Video Thumbnail/Player */}\n
\n
\n {!isPlaying ? (\n setIsPlaying(true)}\n className=\"flex h-20 w-20 items-center justify-center rounded-full border-2 border-primary/40 bg-background/80 backdrop-blur transition-all hover:border-primary hover:bg-background focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n aria-label=\"Play lesson: Introduction to Modern React\"\n >\n \n \n ) : (\n
\n

\n Video player would appear here\n

\n
\n )}\n
\n\n {/* Video Info Overlay */}\n
\n
\n
\n
\n
\n \n );\n}\n\nfunction CourseStats() {\n const stats: CourseStatsProps[] = [\n {\n label: \"Total Duration\",\n value: COURSE_DATA.duration,\n icon: ,\n },\n {\n label: \"Lectures\",\n value: COURSE_DATA.lectures.toString(),\n icon: ,\n },\n {\n label: \"Language\",\n value: COURSE_DATA.language,\n icon: ,\n },\n {\n label: \"Last Updated\",\n value: COURSE_DATA.lastUpdated,\n icon: ,\n },\n ];\n\n return (\n \n {stats.map((stat, index) => (\n \n
\n\n
\n \n {stat.icon}\n
\n
\n

\n {stat.label}\n

\n

\n {stat.value}\n

\n
\n
\n \n ))}\n \n );\n}\n\nfunction InstructorCard({\n name,\n title,\n bio,\n image,\n rating,\n students,\n courses,\n}: InstructorCardProps) {\n return (\n \n {/* Gradient overlay on hover */}\n
\n\n {/* Top gradient accent */}\n
\n\n
\n
\n

\n Your Instructor\n

\n \n \n Verified\n \n
\n\n
\n {/* Profile Header */}\n
\n {/* Avatar with gradient border */}\n
\n
\n
\n \n
\n
\n\n {/* Name and Title */}\n
\n

\n {name}\n

\n

\n {title}\n

\n
\n
\n\n {/* Bio */}\n

\n {bio}\n

\n\n {/* Stats Grid */}\n \n \n
\n
\n
\n \n \n Rating\n \n
\n

\n {rating}\n

\n

Instructor Score

\n
\n \n\n \n
\n
\n
\n \n \n Students\n \n
\n

\n {students}\n

\n

Total Enrolled

\n
\n \n\n \n
\n
\n
\n \n \n Courses\n \n
\n

\n {courses}\n

\n

Published

\n
\n \n
\n
\n
\n \n );\n}\n\nfunction CourseCurriculum() {\n return (\n \n
\n\n
\n
\n

\n Course Curriculum\n

\n \n {CURRICULUM_DATA.length} Sections\n \n
\n\n
\n {CURRICULUM_DATA.map((section, sectionIndex) => (\n \n {/* Section Header */}\n \n
\n
\n

\n {section.title}\n

\n

\n {section.lessons.length} lessons · {section.duration}\n

\n
\n \n
\n \n\n {/* Lessons List */}\n
\n {section.lessons.map((lesson, lessonIndex) => {\n const Icon =\n lesson.type === \"video\"\n ? PlayCircle\n : lesson.type === \"article\"\n ? FileText\n : CheckCircle2;\n\n return (\n \n
\n \n {lesson.isLocked ? (\n \n ) : lesson.isCompleted ? (\n \n ) : (\n \n )}\n
\n
\n

\n {lesson.title}\n

\n

\n {lesson.type} · {lesson.duration}\n

\n
\n
\n {!lesson.isLocked && (\n \n )}\n \n );\n })}\n
\n
\n ))}\n
\n
\n \n );\n}\n\n// ============================================================================\n// MAIN PAGE COMPONENT\n// ============================================================================\n\nexport function CourseContentPage() {\n return (\n
\n {/* Glassmorphism background blobs */}\n
\n
\n
\n
\n
\n\n
\n
\n \n\n \n {/* Video Player */}\n \n\n {/* Course Stats */}\n \n\n {/* Two Column Layout */}\n
\n {/* Curriculum - Takes 2 columns */}\n
\n \n
\n\n {/* Instructor - Takes 1 column */}\n
\n \n
\n
\n \n
\n
\n
\n );\n}\n", "type": "registry:component", "target": "components/uitripled/course-content-page-shadcnui.tsx" } ] }