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;