import React, { useRef, useEffect, useState } from 'react'; import { SlidersHorizontal, ChevronDown, ChevronUp, Brain } from 'lucide-react'; const ResultCard = ({ result, imageData, processedImageData, onReprocess, isProcessing }) => { const canvasRef = useRef(null); const previewCanvasRef = useRef(null); const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); const [signatureCrop, setSignatureCrop] = useState(null); const [stampCrop, setStampCrop] = useState(null); const [resolution, setResolution] = useState(result.processedResolution || 100); const [adjustedDataUrl, setAdjustedDataUrl] = useState(null); const [previewDimensions, setPreviewDimensions] = useState({ width: 0, height: 0 }); const [currentImageData, setCurrentImageData] = useState(processedImageData || imageData); const [showReasoning, setShowReasoning] = useState(false); // Function to crop image regions const cropRegion = (img, coords, scaleX, scaleY) => { if (!coords || coords.length === 0) return null; const [x1, y1, x2, y2] = coords[0]; const width = (x2 - x1) * scaleX; const height = (y2 - y1) * scaleY; const cropCanvas = document.createElement('canvas'); cropCanvas.width = width; cropCanvas.height = height; const cropCtx = cropCanvas.getContext('2d'); // Draw the cropped region cropCtx.drawImage( img, x1, y1, x2 - x1, y2 - y1, 0, 0, width, height ); return cropCanvas.toDataURL(); }; // Initialize currentImageData with processedImageData when available useEffect(() => { if (processedImageData) { setCurrentImageData(processedImageData); } }, [processedImageData]); // Main effect to draw image with bounding boxes using currentImageData useEffect(() => { if (!currentImageData || !canvasRef.current) return; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const img = new Image(); img.onload = () => { // Set canvas size to match container while maintaining aspect ratio const maxWidth = 800; const maxHeight = 600; let width = img.width; let height = img.height; if (width > maxWidth) { height = (height * maxWidth) / width; width = maxWidth; } if (height > maxHeight) { width = (width * maxHeight) / height; height = maxHeight; } canvas.width = width; canvas.height = height; setDimensions({ width, height }); // Draw image ctx.drawImage(img, 0, 0, width, height); // Calculate scale factors const scaleX = width / img.width; const scaleY = height / img.height; // Create cropped images for signature and stamp from the CURRENT (processed) image // This ensures crops match the resolution that was sent to the API if (result.signature_coords && result.signature_coords.length > 0) { const sigCrop = cropRegion(img, result.signature_coords, 1, 1); setSignatureCrop(sigCrop); } if (result.stamp_coords && result.stamp_coords.length > 0) { const stCrop = cropRegion(img, result.stamp_coords, 1, 1); setStampCrop(stCrop); } // Draw bounding boxes for signature if (result.signature_coords && result.signature_coords.length > 0) { ctx.strokeStyle = '#ef4444'; ctx.lineWidth = 3; ctx.setLineDash([5, 5]); result.signature_coords.forEach(coords => { const [x1, y1, x2, y2] = coords; ctx.strokeRect( x1 * scaleX, y1 * scaleY, (x2 - x1) * scaleX, (y2 - y1) * scaleY ); }); // Add label ctx.fillStyle = '#ef4444'; ctx.font = 'bold 14px Arial'; ctx.fillText('Signature', result.signature_coords[0][0] * scaleX, result.signature_coords[0][1] * scaleY - 5); } // Draw bounding boxes for stamp if (result.stamp_coords && result.stamp_coords.length > 0) { ctx.strokeStyle = '#3b82f6'; ctx.lineWidth = 3; ctx.setLineDash([5, 5]); result.stamp_coords.forEach(coords => { const [x1, y1, x2, y2] = coords; ctx.strokeRect( x1 * scaleX, y1 * scaleY, (x2 - x1) * scaleX, (y2 - y1) * scaleY ); }); // Add label ctx.fillStyle = '#3b82f6'; ctx.font = 'bold 14px Arial'; ctx.fillText('Stamp', result.stamp_coords[0][0] * scaleX, result.stamp_coords[0][1] * scaleY - 5); } }; img.src = currentImageData; }, [currentImageData, imageData, result]); // Handle resolution adjustment for preview and update currentImageData useEffect(() => { if (!imageData || !previewCanvasRef.current) return; const canvas = previewCanvasRef.current; const ctx = canvas.getContext('2d'); const img = new Image(); img.onload = () => { const scale = resolution / 100; const newWidth = Math.floor(img.width * scale); const newHeight = Math.floor(img.height * scale); canvas.width = newWidth; canvas.height = newHeight; setPreviewDimensions({ width: newWidth, height: newHeight }); ctx.drawImage(img, 0, 0, newWidth, newHeight); // Generate adjusted data URL const adjustedUrl = canvas.toDataURL('image/jpeg', 0.95); setAdjustedDataUrl(adjustedUrl); // Update the current image data to reflect resolution change setCurrentImageData(adjustedUrl); }; img.src = imageData; }, [imageData, resolution]); if (!result.success) { return (
File: {result.filename}
Error: {result.error}
Page {result.pageNumber}
)}
{JSON.stringify(result.signature_coords)}
{JSON.stringify(result.stamp_coords)}