import React, { startTransition, useDeferredValue, useEffect, useMemo, useRef, useState } from 'react' import { createPortal } from 'react-dom' import { Head, Link, router, useForm } from '@inertiajs/react' import { marked } from 'marked' import AdminLayout from '../../../Layouts/AdminLayout' import RichTextEditor from '../../../components/forum/RichTextEditor' import WorldMediaUploadField from '../../../components/worlds/editor/WorldMediaUploadField' import DateTimePicker from '../../../components/ui/DateTimePicker' import NovaSelect from '../../../components/ui/NovaSelect' let lessonMarkdownTurndown = null let lessonMarkdownTurndownPromise = null async function loadLessonMarkdownTurndown() { if (lessonMarkdownTurndown) { return lessonMarkdownTurndown } if (typeof window === 'undefined') { return null } if (!lessonMarkdownTurndownPromise) { lessonMarkdownTurndownPromise = import('turndown') .then(({ default: TurndownService }) => new TurndownService({ headingStyle: 'atx', codeBlockStyle: 'fenced', bulletListMarker: '-', emDelimiter: '*', })) .then((service) => { lessonMarkdownTurndown = service return service }) .catch(() => null) } return lessonMarkdownTurndownPromise } function getField(fields, name) { return fields.find((field) => field.name === name) || null } const LESSON_EDITOR_TABS = [ { id: 'write', label: 'Write', description: 'Headline, summary, and the full lesson article.', icon: 'fa-pen-nib', sections: ['lesson-story-setup', 'lesson-body-editor'], }, { id: 'blocks', label: 'Blocks', description: 'Reusable AI comparison modules and structured lesson inserts.', icon: 'fa-layer-group', sections: ['lesson-ai-comparisons'], }, { id: 'courses', label: 'Courses', description: 'Attach this lesson to courses, manage its public numbering, and reorder it inside guided paths.', icon: 'fa-diagram-project', sections: ['lesson-course-numbering', 'lesson-course-manager'], }, { id: 'publish', label: 'Publish', description: 'Visibility, discovery settings, scheduling, and search surfaces.', icon: 'fa-rocket-launch', sections: ['lesson-publishing', 'lesson-seo'], }, { id: 'assets', label: 'Assets', description: 'Categories, hero media, and article imagery.', icon: 'fa-images', sections: ['lesson-categories', 'lesson-cover', 'lesson-article-cover'], }, { id: 'revisions', label: 'Revisions', description: 'Review saved lesson snapshots and restore the full lesson or a single field.', icon: 'fa-clock-rotate-left', sections: ['lesson-revisions'], }, { id: 'preview', label: 'Preview', description: 'Preview the lesson card, article imagery, and rendered body.', icon: 'fa-eye', sections: ['lesson-preview'], }, ] const LESSON_FIELD_TAB_MAP = { title: 'write', slug: 'write', excerpt: 'write', content: 'write', content_markdown: 'write', lesson_type: 'publish', difficulty: 'publish', access_level: 'publish', reading_minutes: 'publish', tags: 'publish', series_name: 'publish', lesson_number: 'courses', course_order: 'courses', course_ids: 'courses', category_id: 'assets', published_at: 'publish', featured: 'publish', active: 'publish', seo_title: 'publish', seo_description: 'publish', video_url: 'publish', cover_image: 'assets', article_cover_image: 'assets', } const LESSON_REVISION_FIELD_OPTIONS = [ { value: 'title', label: 'Title' }, { value: 'slug', label: 'Slug' }, { value: 'lesson_number', label: 'Lesson number' }, { value: 'course_order', label: 'Course order' }, { value: 'series_name', label: 'Series name' }, { value: 'excerpt', label: 'Excerpt' }, { value: 'content', label: 'Article body' }, { value: 'difficulty', label: 'Difficulty' }, { value: 'access_level', label: 'Access level' }, { value: 'lesson_type', label: 'Lesson type' }, { value: 'cover_image', label: 'Cover image' }, { value: 'article_cover_image', label: 'Article cover image' }, { value: 'tags', label: 'Microtags' }, { value: 'video_url', label: 'Video URL' }, { value: 'reading_minutes', label: 'Reading minutes' }, { value: 'featured', label: 'Featured toggle' }, { value: 'active', label: 'Active toggle' }, { value: 'published_at', label: 'Publish date' }, { value: 'seo_title', label: 'SEO title' }, { value: 'seo_description', label: 'SEO description' }, { value: 'course_ids', label: 'Course attachments' }, { value: 'blocks', label: 'AI comparison blocks' }, ] let comparisonEditorSequence = 0 function nextComparisonEditorKey(prefix) { comparisonEditorSequence += 1 return `${prefix}-${comparisonEditorSequence}` } function FieldError({ message }) { if (!message) return null return

{message}

} function SectionCard({ id, eyebrow, title, description, actions, children, tone = 'default', className = '', contentClassName = '' }) { const toneClass = tone === 'feature' ? 'bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.16),transparent_38%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.92))] shadow-[0_24px_70px_rgba(2,6,23,0.28)]' : 'bg-white/[0.03]' return (
{eyebrow ?

{eyebrow}

: null}

{title}

{description ?

{description}

: null}
{actions ?
{actions}
: null}
{children}
) } function EditorWorkspaceTabs({ tabs, activeTab, onChange, errorCounts }) { const activeMeta = tabs.find((tab) => tab.id === activeTab) || tabs[0] return (
{tabs.map((tab) => { const isActive = tab.id === activeTab const errorCount = Number(errorCounts?.[tab.id] || 0) return ( ) })}

{activeMeta.description}

{activeMeta.sections.map((section) => ( {section.replace('lesson-', '').replace(/-/g, ' ')} ))}
) } function firstLessonErrorTab(errors) { const firstKey = Object.keys(errors || {})[0] if (!firstKey) return null if (firstKey.startsWith('blocks.')) return 'blocks' return LESSON_FIELD_TAB_MAP[firstKey] || null } function lessonTabErrorCounts(errors) { const counts = {} Object.keys(errors || {}).forEach((key) => { const tabId = key.startsWith('blocks.') ? 'blocks' : LESSON_FIELD_TAB_MAP[key] if (!tabId) return counts[tabId] = Number(counts[tabId] || 0) + 1 }) return counts } function TextField({ label, value, onChange, error, hint, ...rest }) { return ( ) } function TextAreaField({ label, value, onChange, error, rows = 4, hint }) { return (