import React, { useEffect, useState, useRef } from 'react'; import { BlogSection as BlogSectionType, PaperStructure } from '../types'; import BlogSectionComponent from './BlogSection'; import Sidebar from './Sidebar'; import { Clock, BookOpen, FileText, Share2, Download, Sparkles, CheckCircle2, Loader2, AlertCircle, RefreshCw } from 'lucide-react'; // Loading placeholder for sections being generated const SectionLoadingPlaceholder: React.FC<{ title: string; index: number; isCurrentlyGenerating: boolean }> = ({ title, index, isCurrentlyGenerating }) => (
{isCurrentlyGenerating ? ( ) : ( index + 1 )}

{title}

{/* Loading skeleton */}
{isCurrentlyGenerating ? ( <>
Generating content...
) : (

Waiting to be generated...

)}
{/* Section Divider */}
); // Error state for failed sections const SectionErrorState: React.FC<{ title: string; error: string; index: number }> = ({ title, error, index }) => (

{title}

Failed to generate this section

{error}

); interface Props { sections: BlogSectionType[]; paperTitle: string; theme: 'light' | 'dark'; onExport: () => void; onShare: () => void; isLoading?: boolean; loadingStage?: 'idle' | 'analyzing' | 'generating'; currentSection?: number; paperStructure?: PaperStructure | null; } const BlogView: React.FC = ({ sections, paperTitle, theme, onExport, onShare, isLoading = false, loadingStage = 'idle', currentSection = -1, paperStructure = null }) => { const [activeSection, setActiveSection] = useState(sections[0]?.id || ''); const [readProgress, setReadProgress] = useState(0); const contentRef = useRef(null); // Calculate reading time (rough estimate: 200 words per minute) const completedSections = sections.filter(s => !s.isLoading && s.content); const totalWords = completedSections.reduce((acc, section) => { return acc + (section.content?.split(/\s+/).length || 0); }, 0); const readingTime = Math.max(1, Math.ceil(totalWords / 200)); // Count completed sections const completedCount = sections.filter(s => !s.isLoading && !s.error).length; // Intersection Observer for active section tracking useEffect(() => { const options = { root: null, rootMargin: '-20% 0px -60% 0px', threshold: 0 }; const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const id = entry.target.id.replace('section-', ''); setActiveSection(id); } }); }, options); sections.forEach((section) => { const element = document.getElementById(`section-${section.id}`); if (element) observer.observe(element); }); return () => observer.disconnect(); }, [sections]); // Scroll progress tracking useEffect(() => { const handleScroll = () => { const winScroll = document.documentElement.scrollTop; const height = document.documentElement.scrollHeight - document.documentElement.clientHeight; const scrolled = (winScroll / height) * 100; setReadProgress(scrolled); }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); return (
{/* Reading Progress Bar */}
{/* Sidebar Navigation */} {sections.length > 0 && ( )} {/* Main Content */}
{/* Loading State - Paper Analysis */} {loadingStage === 'analyzing' && (

Analyzing Paper Structure

Understanding the paper's key contributions, methodology, and findings to create the optimal narrative structure...

)} {/* Generation Progress Banner */} {loadingStage === 'generating' && (
Generating sections... {completedCount} / {sections.length}
{currentSection >= 0 && sections[currentSection] && (

Currently writing: {sections[currentSection].title}

)}
)} {/* Article Header */} {(sections.length > 0 || paperStructure) && (
{/* Paper Badge */}
Research Summary {loadingStage === 'generating' && ( Generating... )}
{/* Title */}

{(paperStructure?.paperTitle || paperTitle).replace('.pdf', '')}

{/* Abstract Preview */} {paperStructure?.paperAbstract && (

{paperStructure.paperAbstract}

)} {/* Meta Info */}
{readingTime} min read
{sections.length} sections
{completedCount === sections.length && sections.length > 0 && (
Complete
)}
{/* Decorative Line */}
)} {/* Key Contribution Highlight */} {paperStructure?.mainContribution && (
Key Contribution

{paperStructure.mainContribution}

)} {/* Sections */}
{sections.map((section, index) => (
{section.isLoading ? ( ) : section.error ? ( ) : ( )}
))}
{/* Footer */}
); }; export default BlogView;