import React, { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { FileText, Code, Eye, Download, Copy, Check } from 'lucide-react'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism'; import { marked } from 'marked'; import jsPDF from 'jspdf'; const ResultsPanel = ({ text, previewMode, onPreviewModeChange, fileName }) => { const [copied, setCopied] = useState(false); const [downloadFormat, setDownloadFormat] = useState('txt'); const previewModes = [ { id: 'text', label: 'Text', icon: }, { id: 'markdown', label: 'Markdown', icon: }, { id: 'preview', label: 'HTML', icon: }, { id: 'json', label: 'JSON', icon: } ]; const downloadFormats = [ { id: 'txt', label: '.txt', icon: '📄' }, { id: 'md', label: '.md', icon: '📝' }, { id: 'html', label: '.html', icon: '🌐' }, { id: 'json', label: '.json', icon: '🔧' }, { id: 'pdf', label: '.pdf', icon: '📋' } ]; const handleCopy = async () => { try { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { console.error('Failed to copy text:', err); } }; const handleDownload = (format = downloadFormat) => { const baseFileName = fileName ? fileName.split('.')[0] : 'extracted-text'; switch (format) { case 'txt': downloadFile(text, `${baseFileName}.txt`, 'text/plain'); break; case 'md': downloadFile(text, `${baseFileName}.md`, 'text/markdown'); break; case 'html': const htmlContent = ` ${baseFileName} - Luna OCR

${baseFileName}

Generated by Luna OCR • ${new Date().toLocaleDateString()}

${marked(text)}

Processed with Luna OCR • Glassmorphism Theme • ${new Date().toLocaleString()}

`; downloadFile(htmlContent, `${baseFileName}.html`, 'text/html'); break; case 'json': const jsonData = { metadata: { fileName: fileName || 'extracted-text', extractedAt: new Date().toISOString(), characterCount: text.length, lineCount: text.split('\n').length, wordCount: text.split(/\s+/).filter(word => word.length > 0).length }, content: { rawText: text, lines: text.split('\n'), paragraphs: text.split('\n\n').filter(p => p.trim().length > 0) } }; downloadFile(JSON.stringify(jsonData, null, 2), `${baseFileName}.json`, 'application/json'); break; case 'pdf': const pdf = new jsPDF(); // Set up styling pdf.setFont('helvetica', 'bold'); pdf.setFontSize(20); pdf.setTextColor(79, 172, 254); // Luna OCR blue // Add title pdf.text(baseFileName, 20, 30); // Add subtitle pdf.setFont('helvetica', 'normal'); pdf.setFontSize(10); pdf.setTextColor(128, 128, 128); pdf.text(`Generated by Luna OCR • ${new Date().toLocaleDateString()}`, 20, 40); // Add separator line pdf.setDrawColor(79, 172, 254); pdf.setLineWidth(0.5); pdf.line(20, 45, 190, 45); // Add content pdf.setFont('helvetica', 'normal'); pdf.setFontSize(11); pdf.setTextColor(0, 0, 0); const lines = pdf.splitTextToSize(text, 170); pdf.text(lines, 20, 55); // Add footer const pageCount = pdf.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { pdf.setPage(i); pdf.setFont('helvetica', 'normal'); pdf.setFontSize(8); pdf.setTextColor(128, 128, 128); pdf.text(`Luna OCR • Page ${i} of ${pageCount}`, 20, 285); } pdf.save(`${baseFileName}.pdf`); break; default: break; } }; const downloadFile = (content, filename, mimeType) => { const blob = new Blob([content], { type: mimeType }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; const renderContent = () => { switch (previewMode) { case 'text': // Always show raw text in text mode return (
{text}
); case 'markdown': marked.setOptions({ breaks: true, gfm: true, tables: true, headerIds: false, mangle: false }); return (
); case 'preview': marked.setOptions({ breaks: true, gfm: true, tables: true, headerIds: false, mangle: false }); return (
); case 'json': const jsonData = { metadata: { fileName: fileName || 'extracted-text', extractedAt: new Date().toISOString(), characterCount: text.length, lineCount: text.split('\n').length, wordCount: text.split(/\s+/).filter(word => word.length > 0).length }, content: { rawText: text, lines: text.split('\n'), paragraphs: text.split('\n\n').filter(p => p.trim().length > 0) } }; return ( {JSON.stringify(jsonData, null, 2)} ); default: return null; } }; return (
{/* Header Section */}

Download & Preview

{text.length} characters • {text.split('\n').length} lines • Ready to download
{copied ? ( ) : ( )} {copied ? 'Copied!' : 'Copy'}
{/* Unified Preview & Download Section */}
PREVIEW & DOWNLOAD
{[ { id: 'text', label: 'Text', icon: , previewId: 'text' }, { id: 'md', label: 'Markdown', icon: , previewId: 'markdown' }, { id: 'html', label: 'HTML', icon: , previewId: 'preview' }, { id: 'json', label: 'JSON', icon: , previewId: 'json' } ].map((format) => ( ))}
{/* Content Preview */}
{ const formatMap = { 'text': 'txt', 'markdown': 'md', 'preview': 'html', 'json': 'json' }; handleDownload(formatMap[previewMode] || 'txt'); }} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} title={`Download current preview as ${previewMode === 'text' ? 'TXT' : previewMode === 'markdown' ? 'MD' : previewMode === 'preview' ? 'HTML' : 'JSON'}`} > {renderContent()}
); }; export default ResultsPanel;