Files
Stirling-PDF/frontend/src/tools/OCR.tsx
T
02189a67bd refactor(frontend): remove unused React default imports (#4529)
## Description of Changes

- Removed unused `React` default imports across multiple frontend
components.
- Updated imports to only include required React hooks and types (e.g.,
`useState`, `useEffect`, `Suspense`, `createContext`).
- Ensured consistency with React 17+ JSX transform, where default
`React` import is no longer required.
- This cleanup reduces bundle size slightly and aligns code with modern
React best practices.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.

Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
2025-09-29 13:01:09 +01:00

148 lines
4.7 KiB
TypeScript

import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
import { useFileSelection } from "../contexts/FileContext";
import { createToolFlow } from "../components/tools/shared/createToolFlow";
import OCRSettings from "../components/tools/ocr/OCRSettings";
import AdvancedOCRSettings from "../components/tools/ocr/AdvancedOCRSettings";
import { useOCRParameters } from "../hooks/tools/ocr/useOCRParameters";
import { useOCROperation } from "../hooks/tools/ocr/useOCROperation";
import { BaseToolProps, ToolComponent } from "../types/tool";
import { useOCRTips } from "../components/tooltips/useOCRTips";
import { useAdvancedOCRTips } from "../components/tooltips/useAdvancedOCRTips";
const OCR = ({ onPreviewFile, onComplete, onError }: BaseToolProps) => {
const { t } = useTranslation();
const { selectedFiles } = useFileSelection();
const ocrParams = useOCRParameters();
const ocrOperation = useOCROperation();
const ocrTips = useOCRTips();
const advancedOCRTips = useAdvancedOCRTips();
// Step expansion state management
const [expandedStep, setExpandedStep] = useState<"files" | "settings" | "advanced" | null>("files");
const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("ocr-pdf");
const hasFiles = selectedFiles.length > 0;
const hasResults = ocrOperation.files.length > 0 || ocrOperation.downloadUrl !== null;
const hasValidSettings = ocrParams.validateParameters();
useEffect(() => {
ocrOperation.resetResults();
onPreviewFile?.(null);
}, [ocrParams.parameters]);
useEffect(() => {
if (selectedFiles.length > 0 && expandedStep === "files") {
setExpandedStep("settings");
}
}, [selectedFiles.length, expandedStep]);
// Collapse all steps when results appear
useEffect(() => {
if (hasResults) {
setExpandedStep(null);
}
}, [hasResults]);
const handleOCR = async () => {
try {
await ocrOperation.executeOperation(ocrParams.parameters, selectedFiles);
if (ocrOperation.files && onComplete) {
onComplete(ocrOperation.files);
}
} catch (error) {
if (onError) {
onError(error instanceof Error ? error.message : "OCR operation failed");
}
}
};
const handleThumbnailClick = (file: File) => {
onPreviewFile?.(file);
sessionStorage.setItem("previousMode", "ocr");
};
const handleSettingsReset = () => {
ocrOperation.resetResults();
onPreviewFile?.(null);
};
const handleUndo = async () => {
await ocrOperation.undoOperation();
onPreviewFile?.(null);
};
const settingsCollapsed = expandedStep !== "settings";
return createToolFlow({
files: {
selectedFiles,
isCollapsed: hasResults,
},
steps: [
{
title: t("ocr.settings.title", "Settings"),
isCollapsed: !hasFiles || settingsCollapsed,
onCollapsedClick: hasResults
? handleSettingsReset
: () => {
if (!hasFiles) return; // Only allow if files are selected
setExpandedStep(expandedStep === "settings" ? null : "settings");
},
tooltip: ocrTips,
content: (
<OCRSettings
parameters={ocrParams.parameters}
onParameterChange={ocrParams.updateParameter}
disabled={endpointLoading}
/>
),
},
{
title: "Advanced",
isCollapsed: expandedStep !== "advanced",
onCollapsedClick: hasResults
? handleSettingsReset
: () => {
if (!hasFiles) return; // Only allow if files are selected
setExpandedStep(expandedStep === "advanced" ? null : "advanced");
},
tooltip: advancedOCRTips,
content: (
<AdvancedOCRSettings
advancedOptions={ocrParams.parameters.additionalOptions}
ocrRenderType={ocrParams.parameters.ocrRenderType}
onParameterChange={ocrParams.updateParameter}
disabled={endpointLoading}
/>
),
},
],
executeButton: {
text: t("ocr.operation.submit", "Process OCR and Review"),
loadingText: t("loading"),
onClick: handleOCR,
isVisible: hasValidSettings && !hasResults,
disabled: !ocrParams.validateParameters() || !hasFiles || !endpointEnabled,
},
review: {
isVisible: hasResults,
operation: ocrOperation,
title: t("ocr.results.title", "OCR Results"),
onFileClick: handleThumbnailClick,
onUndo: handleUndo,
},
});
};
// Static method to get the operation hook for automation
OCR.tool = () => useOCROperation;
export default OCR as ToolComponent;