import { useState, useRef } from 'react'; import { Button } from '../../../components/ui/button'; import { Badge } from '../../../components/ui/badge'; import { HiOutlineBars3, HiOutlineVideoCamera, HiOutlineDocumentText, HiOutlineQuestionMarkCircle, HiOutlineCodeBracket, HiOutlineChevronUp, HiOutlineChevronDown, HiOutlineDocumentDuplicate, HiOutlineTrash, HiOutlinePlus, HiOutlineChevronDown as HiOutlineExpand, } from 'react-icons/hi2'; import VideoSection from './VideoSection'; import TextSection from './TextSection'; import QuizSection from './QuizSection'; import EmbedSection from './EmbedSection'; const SECTION_TYPES = { 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 sectionEditors = { video: VideoSection, text: TextSection, quiz: QuizSection, embed: EmbedSection, }; function SectionItem({ section, index, total, onUpdate, onRemove, onDuplicate, onMoveUp, onMoveDown }) { const [isExpanded, setIsExpanded] = useState(true); const typeConfig = SECTION_TYPES[section.type]; const Icon = typeConfig.icon; const Editor = sectionEditors[section.type]; const getMetaText = () => { switch (section.type) { case 'video': return section.duration || '00:00'; case 'text': return `~${Math.max(1, Math.ceil((section.content || '').split(/\s+/).length / 200))} min read`; case 'quiz': return `${section.timeLimit || 10}:00 \u2022 ${section.questionCount || 5} questions`; case 'embed': return 'iFrame'; default: return ''; } }; return (
{typeConfig.label} {section.title || `Section ${index + 1}`} {section.isFreePreview && ( Free Preview )}
{getMetaText()}
{isExpanded && Editor && ( onUpdate(index, updated)} /> )}
); } function SectionManager({ sections, onChange }) { const [showAddMenu, setShowAddMenu] = useState(false); const counterRef = useRef(0); const addSection = (type) => { counterRef.current += 1; const newSection = { id: `section_${counterRef.current}`, type, title: '', isFreePreview: false, ...(type === 'video' && { url: '', duration: '', thumbnail: '' }), ...(type === 'text' && { content: '' }), ...(type === 'quiz' && { questionCount: 5, timeLimit: 10, passScore: 80, maxAttempts: 3 }), ...(type === 'embed' && { embedUrl: '' }), }; onChange([...sections, newSection]); setShowAddMenu(false); }; const updateSection = (index, updated) => { const newSections = [...sections]; newSections[index] = updated; onChange(newSections); }; const removeSection = (index) => { onChange(sections.filter((_, i) => i !== index)); }; const duplicateSection = (index) => { counterRef.current += 1; const duplicate = { ...sections[index], id: `section_${counterRef.current}` }; const newSections = [...sections]; newSections.splice(index + 1, 0, duplicate); onChange(newSections); }; const moveSection = (from, to) => { if (to < 0 || to >= sections.length) return; const newSections = [...sections]; const [moved] = newSections.splice(from, 1); newSections.splice(to, 0, moved); onChange(newSections); }; return (

Sections

{sections.length} items

Drag to reorder. Each section supports different multimedia content types.

{showAddMenu && (
{Object.entries(SECTION_TYPES).map(([type, config]) => { const Icon = config.icon; return ( ); })}
)}
{sections.map((section, index) => ( removeSection(index)} onDuplicate={() => duplicateSection(index)} onMoveUp={() => moveSection(index, index - 1)} onMoveDown={() => moveSection(index, index + 1)} /> ))}
Quick add:
{Object.entries(SECTION_TYPES).map(([type, config]) => { const Icon = config.icon; return ( ); })}
); } export default SectionManager;