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
${marked(text)}
`;
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 (
);
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;