'use client'; import { useState, useEffect, useRef } from 'react'; import { Item } from '@/lib/db'; interface DebugRotationPanelProps { item: Item; imageUrl: string; originalCropBounds?: { x: number; y: number; width: number; height: number }; originalRotation?: number; imageProcessing?: any; } export function DebugRotationPanel({ item, imageUrl, originalCropBounds, originalRotation = 0, imageProcessing, }: DebugRotationPanelProps) { const [rotation, setRotation] = useState(originalRotation); const [cropBounds, setCropBounds] = useState(originalCropBounds); const canvasRef = useRef(null); const [logs, setLogs] = useState([]); const [imageLoaded, setImageLoaded] = useState(false); const imageRef = useRef(null); 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 }, ]; useEffect(() => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { imageRef.current = img; setImageLoaded(true); addLog(`Image loaded: ${img.width}×${img.height}px`); }; img.onerror = () => addLog('❌ Failed to load image'); img.src = imageUrl; }, [imageUrl]); const addLog = (message: string) => { setLogs((prev) => [...prev, `[${new Date().toLocaleTimeString()}] ${message}`]); }; useEffect(() => { if (!imageLoaded || !imageRef.current || !canvasRef.current) return; const img = imageRef.current; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); if (!ctx) return; addLog(`\n--- Processing Step ---`); addLog(`Original image: ${img.width}×${img.height}px`); if (cropBounds) { addLog(`Crop bounds: x=${cropBounds.x}, y=${cropBounds.y}, w=${cropBounds.width}, h=${cropBounds.height}`); addLog(`Crop rect: (${cropBounds.x}, ${cropBounds.y}, ${cropBounds.x + cropBounds.width}, ${cropBounds.y + cropBounds.height})`); } // Set canvas size to match cropped result (or full image if no crop) const finalWidth = cropBounds ? cropBounds.width : img.width; const finalHeight = cropBounds ? cropBounds.height : img.height; // Account for rotation expanding the canvas let displayWidth = finalWidth; let displayHeight = finalHeight; const radians = (rotation * Math.PI) / 180; const cos = Math.abs(Math.cos(radians)); const sin = Math.abs(Math.sin(radians)); if (Math.abs(rotation % 90) !== 0) { displayWidth = Math.ceil(finalWidth * cos + finalHeight * sin); displayHeight = Math.ceil(finalWidth * sin + finalHeight * cos); } canvas.width = displayWidth; canvas.height = displayHeight; addLog(`After crop: ${finalWidth}×${finalHeight}px`); addLog(`Applying rotation: ${rotation}°`); addLog(`Canvas with expansion: ${displayWidth}×${displayHeight}px`); // Draw: Crop → Rotate ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Save context state ctx.save(); // Move to center, rotate, move back ctx.translate(displayWidth / 2, displayHeight / 2); ctx.rotate((rotation * Math.PI) / 180); ctx.translate(-finalWidth / 2, -finalHeight / 2); // Draw cropped portion of image if (cropBounds) { ctx.drawImage( img, cropBounds.x, cropBounds.y, cropBounds.width, cropBounds.height, 0, 0, cropBounds.width, cropBounds.height ); } else { ctx.drawImage(img, 0, 0); } ctx.restore(); addLog(`✅ Preview rendered`); addLog(`Final image: ${displayWidth}×${displayHeight}px`); }, [imageLoaded, rotation, cropBounds]); return (

🔧 Debug Rotation Panel

Item: {item.name}

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

Original Values

Rotation: {originalRotation}°
{originalCropBounds && (
Crop: ({originalCropBounds.x}, {originalCropBounds.y}) {originalCropBounds.width}×{originalCropBounds.height}
)} {imageProcessing?.confidence && (
Confidence: {(imageProcessing.confidence * 100).toFixed(0)}%
)}
)} {/* Save Button */}
{/* Right: Preview + Logs */}
{/* Canvas Preview */}

Processed Preview

{/* Logs */}

Debug Logs

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