'use client'; import { useState, useEffect, useRef } from 'react'; import { Item } from '@/lib/db'; import { X } from 'lucide-react'; interface DebugRotationPanelProps { item: Item; imageUrl: string; originalCropBounds?: { x: number; y: number; width: number; height: number }; originalRotation?: number; imageProcessing?: any; onClose: () => void; } export function DebugRotationPanel({ item, imageUrl, originalCropBounds, originalRotation = 0, imageProcessing, onClose, }: DebugRotationPanelProps) { const [rotation, setRotation] = useState(originalRotation); const canvasRef = useRef(null); const [logs, setLogs] = useState([]); const imageRef = useRef(null); const [imageLoaded, setImageLoaded] = useState(false); const [scaledDimensions, setScaledDimensions] = useState({ width: 0, height: 0, scale: 1 }); const commonAngles = [ { label: '0°', value: 0 }, { label: '+22°', value: 22 }, { label: '-22°', value: -22 }, { label: '+45°', value: 45 }, { label: '-45°', value: -45 }, { label: '+90°', value: 90 }, { label: '-90°', value: -90 }, { label: '±180°', value: 180 }, ]; const addLog = (message: string) => { setLogs((prev) => [...prev, `[${new Date().toLocaleTimeString()}] ${message}`]); }; useEffect(() => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { imageRef.current = img; setImageLoaded(true); addLog(`📸 Image loaded: ${img.width}×${img.height}px`); // Calculate scaled dimensions to fit canvas const maxWidth = 600; const maxHeight = 500; const scale = Math.min(maxWidth / img.width, maxHeight / img.height); const scaledW = img.width * scale; const scaledH = img.height * scale; setScaledDimensions({ width: scaledW, height: scaledH, scale }); addLog(`📐 Scaled to fit: ${scaledW.toFixed(0)}×${scaledH.toFixed(0)}px (scale ${scale.toFixed(2)}x)`); }; img.onerror = () => addLog('❌ Failed to load image'); img.src = imageUrl; }, [imageUrl]); useEffect(() => { if (!imageLoaded || !imageRef.current || !canvasRef.current || !originalCropBounds) return; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); if (!ctx) return; const img = imageRef.current; const { scale } = scaledDimensions; // Set canvas size to match scaled image canvas.width = scaledDimensions.width; canvas.height = scaledDimensions.height; addLog(`\n🎨 --- Drawing Preview ---`); addLog(`Rotation: ${rotation}°`); // Draw scaled image ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // Draw crop bounding box on the ORIGINAL image const cropX = originalCropBounds.x * scale; const cropY = originalCropBounds.y * scale; const cropW = originalCropBounds.width * scale; const cropH = originalCropBounds.height * scale; // Save state ctx.save(); // Draw semi-transparent overlay (darken everything outside crop) ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Clear the crop area (show full brightness) ctx.clearRect(cropX, cropY, cropW, cropH); // Draw crop bounds rectangle ctx.strokeStyle = '#00FF00'; ctx.lineWidth = 3; ctx.strokeRect(cropX, cropY, cropW, cropH); // Draw rotation indicator (rotated rectangle inside crop area) if (Math.abs(rotation) > 0.5) { ctx.strokeStyle = '#FFB800'; ctx.lineWidth = 2; ctx.setLineDash([5, 5]); // Draw a rotated rectangle showing where text will be after rotation ctx.save(); ctx.translate(cropX + cropW / 2, cropY + cropH / 2); ctx.rotate((rotation * Math.PI) / 180); ctx.strokeRect(-cropW / 2, -cropH / 2, cropW, cropH); ctx.restore(); } ctx.restore(); // Logs addLog(`Crop area: (${originalCropBounds.x}, ${originalCropBounds.y}) ${originalCropBounds.width}×${originalCropBounds.height}px`); addLog(`Scaled crop: (${cropX.toFixed(0)}, ${cropY.toFixed(0)}) ${cropW.toFixed(0)}×${cropH.toFixed(0)}px`); if (Math.abs(rotation) > 0.5) { addLog(`✅ Rotation overlay shown in ORANGE`); } }, [imageLoaded, rotation, originalCropBounds, scaledDimensions]); return (
{/* Header */}

🔧 Debug Rotation & Crop

{/* Left: Controls */}
{/* Rotation Slider */}
setRotation(Number(e.target.value))} className="w-full" />
{/* Quick Presets */}
{commonAngles.map((angle) => ( ))}
{/* Original Values */} {originalRotation !== undefined && (

Original Values

Rotation: {originalRotation}°
{originalCropBounds && ( <>
Crop X: {originalCropBounds.x}
Crop Y: {originalCropBounds.y}
Width: {originalCropBounds.width}
Height: {originalCropBounds.height}
)} {imageProcessing?.confidence && (
Confidence: {(imageProcessing.confidence * 100).toFixed(0)}%
)}
)}
{/* Center: Canvas Preview + Right: Logs */}
{/* Canvas */}

Image Preview

🟢 Crop 🟠 Rotate
{/* Logs */}

Logs

{logs.map((log, i) => (
{log}
))}
); }