import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Card } from '../../components/ui/card'; import { Button } from '../../components/ui/button'; import { Badge } from '../../components/ui/badge'; import { Label } from '../../components/ui/label'; import { Input } from '../../components/ui/input'; import { Textarea } from '../../components/ui/textarea'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '../../components/ui/tabs'; import { Separator } from '../../components/ui/separator'; import { HiOutlinePlus, HiOutlinePencil, HiOutlineTrash, HiOutlineEye, HiOutlineChevronRight, HiOutlineBookOpen, HiOutlineVideoCamera, HiOutlineDocumentText, HiOutlineQuestionMarkCircle, HiOutlineCodeBracket, HiOutlineArrowUpTray, HiOutlineFunnel, } from 'react-icons/hi2'; import courseService from '@/services/courseService'; import lessonService from '@/services/lessonService'; import sectionService from '@/services/sectionService'; const typeConfig = { video: { label: 'Video', icon: HiOutlineVideoCamera, color: 'bg-blue-100 text-blue-700' }, text: { label: 'Text', icon: HiOutlineDocumentText, color: 'bg-purple-100 text-purple-700' }, quiz: { label: 'Quiz', icon: HiOutlineQuestionMarkCircle, color: 'bg-orange-100 text-orange-700' }, embed: { label: 'Embed', icon: HiOutlineCodeBracket, color: 'bg-gray-100 text-gray-700' }, }; const statusStyles = { Published: 'bg-app-success text-app-success-text', Draft: 'bg-app-neutral-badge text-app-neutral-badge-text', }; function formatDuration(seconds) { if (!seconds) return '00:00'; const m = Math.floor(seconds / 60); const s = seconds % 60; return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`; } function mapCourse(c) { return { id: c.id, code: c.courseCode, title: c.title, description: c.description, status: c.isPublished ? 'Active' : 'Inactive', lastUpdate: c.updatedAt, image: c.image, isPublished: c.isPublished, }; } function CourseDetail() { const { courseId } = useParams(); const navigate = useNavigate(); const [course, setCourse] = useState(null); const [lessons, setLessons] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [activeTab, setActiveTab] = useState('overview'); const handleTogglePublish = async () => { try { await courseService.update(courseId, { courseCode: course.code, title: course.title, description: course.description, image: course.image, isPublished: !course.isPublished, }); setCourse((prev) => ({ ...prev, isPublished: !prev.isPublished, status: prev.isPublished ? 'Inactive' : 'Active' })); } catch (err) { alert(err.message || 'Failed to update course'); } }; const handleDeleteLesson = async (lessonId) => { if (!window.confirm('Are you sure you want to delete this lesson?')) return; try { await lessonService.delete(lessonId); setLessons((prev) => prev.filter((l) => l.id !== lessonId)); } catch (err) { alert(err.message || 'Failed to delete lesson'); } }; useEffect(() => { const fetchData = async () => { try { const courseData = await courseService.getById(courseId); setCourse(mapCourse(courseData)); const allLessons = await lessonService.getAll(); const courseLessons = allLessons.filter((l) => l.courseId === Number(courseId)); const lessonsWithSections = await Promise.all( courseLessons.map(async (lesson) => { const sections = await sectionService.getByLessonId(lesson.id); const firstSection = sections[0]; return { id: lesson.id, title: lesson.title, position: lesson.position, type: firstSection?.type || 'text', duration: firstSection?.type === 'video' ? formatDuration(firstSection.durationSeconds) : firstSection?.type === 'text' ? `~${Math.max(1, Math.ceil((firstSection.content || '').split(/\s+/).length / 200))} min read` : firstSection?.type === 'quiz' ? `${firstSection.durationSeconds ? Math.floor(firstSection.durationSeconds / 60) : 10}:00` : firstSection?.type === 'embed' ? 'iFrame' : '00:00', status: lesson.isPublished ? 'Published' : 'Draft', isFreePreview: firstSection?.isFreePreview || false, updatedAt: lesson.updatedAt, }; }) ); setLessons(lessonsWithSections); } catch (err) { setError(err.message || 'Failed to load course'); } finally { setLoading(false); } }; fetchData(); }, [courseId]); if (loading) { return ( <>
Loading course...
); } if (error || !course) { return ( <>

{error || 'Course not found'}

); } const publishedCount = lessons.filter((l) => l.status === 'Published').length; const draftCount = lessons.filter((l) => l.status === 'Draft').length; return ( <> {/* Breadcrumb */}
{course.title}
{/* Header */}

{course.title}

{course.status}
{/* Tabs */} Overview Lessons {lessons.length} {/* Overview Tab */}

Course Details

{course.status}