From 1ae274a658d0a705b698a8873c286ec73403b1a6 Mon Sep 17 00:00:00 2001 From: polwex Date: Thu, 15 May 2025 12:17:54 +0700 Subject: m --- src/components/Main.tsx | 227 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 src/components/Main.tsx (limited to 'src/components/Main.tsx') diff --git a/src/components/Main.tsx b/src/components/Main.tsx new file mode 100644 index 0000000..ee8dbab --- /dev/null +++ b/src/components/Main.tsx @@ -0,0 +1,227 @@ +// src/components/SorlangPage.tsx +"use client"; // For Next.js App Router, if applicable + +import React, { + useState, + useRef, + useTransition, + useEffect, + useCallback, + startTransition, +} from "react"; +import { Button } from "@/components/ui/button"; +import { Textarea } from "@/components/ui/textarea"; +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Loader2 } from "lucide-react"; // Loading spinner + +const SorlangPage: React.FC = () => { + const [textValue, setTextValue] = useState(""); + const [pastedImageUrl, setPastedImageUrl] = useState(null); + const [pastedImageFile, setPastedImageFile] = useState(null); // Store the file for extraction + const [isExtracting, setIsExtracting] = useState(false); + const [extractedTextResult, setExtractedTextResult] = useState( + null, + ); + + const textareaRef = useRef(null); + + // Cleanup object URL when component unmounts or image changes + useEffect(() => { + return () => { + if (pastedImageUrl) { + URL.revokeObjectURL(pastedImageUrl); + } + }; + }, [pastedImageUrl]); + + const handlePaste = useCallback( + (event: React.ClipboardEvent) => { + const items = event.clipboardData?.items; + console.log({ items }); + if (!items) return; + + let imageFound = false; + for (let i = 0; i < items.length; i++) { + const item = items[i]; + if (!item) return; + if (item.kind === "file" && item.type.startsWith("image/")) { + event.preventDefault(); // Prevent pasting image data as text + const file = item.getAsFile(); + if (file) { + if (pastedImageUrl) { + URL.revokeObjectURL(pastedImageUrl); // Revoke previous if any + } + const newImageUrl = URL.createObjectURL(file); + setPastedImageUrl(newImageUrl); + setPastedImageFile(file); + setTextValue(""); // Clear textarea when image is pasted, or decide on desired behavior + setExtractedTextResult(null); // Clear previous extraction results + imageFound = true; + } + break; // Handle first image found + } + } + + // If no image was found, let the default text paste happen + // Or, if you want to explicitly handle text paste: + if (!imageFound) { + // Let the default textarea paste handle it, or: + // event.preventDefault(); + // const text = event.clipboardData.getData('text/plain'); + // setTextValue(prev => prev + text); // Or replace, depending on desired behavior + // setPastedImageUrl(null); // Clear image if text is pasted + // setPastedImageFile(null); + } + }, + [pastedImageUrl], + ); + + const handleProcessText = () => { + if (!textValue.trim()) { + alert("Text area is empty!"); + return; + } + console.log("Processing text:", textValue); + // Add your text processing logic here + alert( + `Text submitted: "${textValue.substring(0, 50)}${textValue.length > 50 ? "..." : ""}"`, + ); + }; + + const [isPending, startTransition] = useTransition(); + const onClick = () => { + startTransition(async() => { + const + }) + } + const handleExtractTextFromImage = async () => { + if (!pastedImageFile) { + alert("No image to extract text from!"); + return; + } + setIsExtracting(true); + setExtractedTextResult(null); + console.log("Extracting text from image:", pastedImageFile.name); + + // --- SIMULATE OCR API CALL --- + // In a real app, you would send `pastedImageFile` to a backend + // or use a client-side OCR library like Tesseract.js + await new Promise((resolve) => setTimeout(resolve, 2000)); // Simulate network delay + + // Example: Simulate successful extraction + const mockExtractedText = `This is simulated extracted text from "${pastedImageFile.name}".\nIt could be multiple lines.`; + + // Example: Simulate an error + // const mockExtractedText = null; + // alert("Failed to extract text (simulated)."); + + if (mockExtractedText) { + setTextValue(mockExtractedText); // Put extracted text into the textarea + setExtractedTextResult( + `Successfully extracted text and placed it in the textarea.`, + ); + } else { + setExtractedTextResult("Failed to extract text (simulated)."); + } + // --- END SIMULATION --- + + setIsExtracting(false); + // Optionally clear the image after attempting extraction + // setPastedImageUrl(null); + // setPastedImageFile(null); + }; + + const handleClearImage = () => { + if (pastedImageUrl) { + URL.revokeObjectURL(pastedImageUrl); + } + setPastedImageUrl(null); + setPastedImageFile(null); + setExtractedTextResult(null); + }; + + return ( +
+ + + + Sorlang + + + +