import React, { useState, useEffect } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Loader2, AlertCircle, CheckCircle, Zap, FileText, Brain } from 'lucide-react';
import FileUpload from './components/FileUpload';
import ProcessingOptions from './components/ProcessingOptions';
import ResultsDisplay from './components/ResultsDisplay';
import apiService from './services/api';
import './App.css';
function App() {
const [selectedFile, setSelectedFile] = useState(null);
const [availableEngines, setAvailableEngines] = useState([]);
const [aiAvailable, setAiAvailable] = useState(false);
const [processing, setProcessing] = useState(false);
const [results, setResults] = useState(null);
const [error, setError] = useState('');
const [systemStatus, setSystemStatus] = useState('loading');
const [processingOptions, setProcessingOptions] = useState({
engines: ['tesseract'],
language: 'eng+ara',
aiCorrection: true,
combinationMethod: 'best_confidence',
context: '',
externalEngine: 'ABBYY FineReader',
confidence: 85,
fileType: null
});
// Initialize system and check available engines
useEffect(() => {
initializeSystem();
}, []);
// Update file type when file is selected
useEffect(() => {
if (selectedFile) {
const fileExtension = selectedFile.name.split('.').pop().toLowerCase();
setProcessingOptions(prev => ({
...prev,
fileType: fileExtension
}));
}
}, [selectedFile]);
const initializeSystem = async () => {
try {
setSystemStatus('loading');
const response = await apiService.getEngines();
if (response.success) {
setAvailableEngines(response.engines);
setAiAvailable(response.ai_correction_available);
setSystemStatus('ready');
// Update default options based on available engines
setProcessingOptions(prev => ({
...prev,
engines: response.engines.length > 0 ? [response.engines[0]] : [],
aiCorrection: response.ai_correction_available
}));
} else {
throw new Error('Failed to initialize system');
}
} catch (err) {
console.error('System initialization failed:', err);
setError(`System initialization failed: ${err.message}`);
setSystemStatus('error');
}
};
const handleFileSelect = (file) => {
setSelectedFile(file);
setResults(null);
setError('');
};
const handleOptionsChange = (newOptions) => {
setProcessingOptions(newOptions);
};
const handleProcess = async () => {
if (!selectedFile) {
setError('Please select a file first');
return;
}
if (processingOptions.engines.length === 0) {
setError('Please select at least one OCR engine');
return;
}
try {
setProcessing(true);
setError('');
setResults(null);
const response = await apiService.processFile(selectedFile, processingOptions);
if (response.success) {
setResults(response);
} else {
throw new Error(response.error || 'Processing failed');
}
} catch (err) {
console.error('Processing failed:', err);
setError(`Processing failed: ${err.message}`);
} finally {
setProcessing(false);
}
};
const handleTextEdit = (newText) => {
if (results) {
setResults(prev => ({
...prev,
final_text: newText
}));
}
};
const handleSaveResults = (text, resultsData) => {
// Create a comprehensive results file
const saveData = {
timestamp: new Date().toISOString(),
filename: selectedFile?.name,
final_text: text,
processing_settings: resultsData.settings,
ocr_results: resultsData.ocr_results,
ai_correction: resultsData.ai_correction,
combined_result: resultsData.combined_result
};
const blob = new Blob([JSON.stringify(saveData, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `ocr_results_${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
const renderSystemStatus = () => {
switch (systemStatus) {
case 'loading':
return (
AI-Powered Text Recognition and Correction
Running OCR engines and AI correction...
Upload a document to get started with OCR processing