import React, { useState } from 'react'; import { X, ZoomIn, ZoomOut, Download, Loader2, RefreshCw, Target, Zap, Book, Users, Clock, ArrowRight, CheckCircle, BarChart, GitBranch, Layers, Layout, Share2, Award, Lightbulb } from 'lucide-react'; import { generateInfographic } from '../api'; import * as htmlToImage from 'html-to-image'; const iconMap = { 'Target': Target, 'Zap': Zap, 'Book': Book, 'Users': Users, 'Clock': Clock, 'ArrowRight': ArrowRight, 'CheckCircle': CheckCircle, 'BarChart': BarChart, 'GitBranch': GitBranch, 'Layers': Layers, 'Layout': Layout, 'Share2': Share2, 'Award': Award, 'Lightbulb': Lightbulb }; const InfographicModal = ({ isOpen, onClose, notebookId }) => { const [status, setStatus] = useState('idle'); // idle, loading, ready const [data, setData] = useState(null); const [scale, setScale] = useState(1); if (!isOpen) return null; const handleGenerate = async () => { setStatus('loading'); try { const result = await generateInfographic(notebookId); setData(result); setStatus('ready'); } catch (error) { console.error(error); setStatus('error'); } }; // Auto-generate on first open if no data React.useEffect(() => { if (isOpen && status === 'idle') { handleGenerate(); } }, [isOpen]); const handleDownload = async () => { const node = document.getElementById('infographic-canvas'); if (node) { const dataUrl = await htmlToImage.toPng(node); const link = document.createElement('a'); link.download = `infographic-${notebookId}.png`; link.href = dataUrl; link.click(); } }; const DynamicIcon = ({ name, size=24, className }) => { const Icon = iconMap[name] || Lightbulb; return ; }; // Render Logic based on Type const renderLayout = () => { if (!data) return null; const { type, title, summary, sections } = data; // Common Header const Header = () => (

{title}

{summary}

); // PROCESS / TIMELINE Layout if (type === 'PROCESS' || type === 'TIMELINE') { return (
{/* Vertical Line */}
{sections.map((section, idx) => (
{/* Content Card */}

{section.title}

    {section.points.map((pt, i) => (
  • {pt}
  • ))}
{/* Icon Marker */}
{/* Spacer */}
))}
{/* Branding */}
Generated by Vertical.ai
); } // DEFAULT: OVERVIEW Grid Layout return (
{sections.map((section, idx) => (

{section.title}

    {section.points.map((pt, i) => (
  • {pt}
  • ))}
))}
Research Summary • Vertical.ai
); }; return (
{/* Header */}

Infographic Generator

Visual Insights

{Math.round(scale * 100)}%
{/* Canvas Area */}
{status === 'loading' && (

Designing Layout...

Analyzing structure and composing visuals.

)} {status === 'error' && (

Failed to generate infographic.

)} {status === 'ready' && (
{renderLayout()}
)}
); }; export default InfographicModal;